ActivityManagerService.java revision 2c43c339de5aaf4fef58aa9b5ac3af48609263a8
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.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200; 274 275 // Amount of time after a call to stopAppSwitches() during which we will 276 // prevent further untrusted switches from happening. 277 static final long APP_SWITCH_DELAY_TIME = 5*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real. 281 static final int PROC_START_TIMEOUT = 10*1000; 282 283 // How long we wait for a launched process to attach to the activity manager 284 // before we decide it's never going to come up for real, when the process was 285 // started with a wrapper for instrumentation (such as Valgrind) because it 286 // could take much longer than usual. 287 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 288 289 // How long to wait after going idle before forcing apps to GC. 290 static final int GC_TIMEOUT = 5*1000; 291 292 // The minimum amount of time between successive GC requests for a process. 293 static final int GC_MIN_INTERVAL = 60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process. 296 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process 299 // when the request is due to the memory state being lowered. 300 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 301 302 // The rate at which we check for apps using excessive power -- 15 mins. 303 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on wake locks to start killing things. 307 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // The minimum sample duration we will allow before deciding we have 310 // enough data on CPU usage to start killing things. 311 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 312 313 // How long we allow a receiver to run before giving up on it. 314 static final int BROADCAST_FG_TIMEOUT = 10*1000; 315 static final int BROADCAST_BG_TIMEOUT = 60*1000; 316 317 // How long we wait until we timeout on key dispatching. 318 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 319 320 // How long we wait until we timeout on key dispatching during instrumentation. 321 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 322 323 // Amount of time we wait for observers to handle a user switch before 324 // giving up on them and unfreezing the screen. 325 static final int USER_SWITCH_TIMEOUT = 2*1000; 326 327 // Maximum number of users we allow to be running at a time. 328 static final int MAX_RUNNING_USERS = 3; 329 330 // How long to wait in getAssistContextExtras for the activity and foreground services 331 // to respond with the result. 332 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 333 334 // Maximum number of persisted Uri grants a package is allowed 335 static final int MAX_PERSISTED_URI_GRANTS = 128; 336 337 static final int MY_PID = Process.myPid(); 338 339 static final String[] EMPTY_STRING_ARRAY = new String[0]; 340 341 // How many bytes to write into the dropbox log before truncating 342 static final int DROPBOX_MAX_SIZE = 256 * 1024; 343 344 /** All system services */ 345 SystemServiceManager mSystemServiceManager; 346 347 /** Run all ActivityStacks through this */ 348 ActivityStackSupervisor mStackSupervisor; 349 350 public IntentFirewall mIntentFirewall; 351 352 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 353 // default actuion automatically. Important for devices without direct input 354 // devices. 355 private boolean mShowDialogs = true; 356 357 /** 358 * Description of a request to start a new activity, which has been held 359 * due to app switches being disabled. 360 */ 361 static class PendingActivityLaunch { 362 final ActivityRecord r; 363 final ActivityRecord sourceRecord; 364 final int startFlags; 365 final ActivityStack stack; 366 367 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 368 int _startFlags, ActivityStack _stack) { 369 r = _r; 370 sourceRecord = _sourceRecord; 371 startFlags = _startFlags; 372 stack = _stack; 373 } 374 } 375 376 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 377 = new ArrayList<PendingActivityLaunch>(); 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 415 public class PendingAssistExtras extends Binder implements Runnable { 416 public final ActivityRecord activity; 417 public boolean haveResult = false; 418 public Bundle result = null; 419 public PendingAssistExtras(ActivityRecord _activity) { 420 activity = _activity; 421 } 422 @Override 423 public void run() { 424 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 425 synchronized (this) { 426 haveResult = true; 427 notifyAll(); 428 } 429 } 430 } 431 432 final ArrayList<PendingAssistExtras> mPendingAssistExtras 433 = new ArrayList<PendingAssistExtras>(); 434 435 /** 436 * Process management. 437 */ 438 final ProcessList mProcessList = new ProcessList(); 439 440 /** 441 * All of the applications we currently have running organized by name. 442 * The keys are strings of the application package name (as 443 * returned by the package manager), and the keys are ApplicationRecord 444 * objects. 445 */ 446 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 447 448 /** 449 * Tracking long-term execution of processes to look for abuse and other 450 * bad app behavior. 451 */ 452 final ProcessStatsService mProcessStats; 453 454 /** 455 * The currently running isolated processes. 456 */ 457 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 458 459 /** 460 * Counter for assigning isolated process uids, to avoid frequently reusing the 461 * same ones. 462 */ 463 int mNextIsolatedProcessUid = 0; 464 465 /** 466 * The currently running heavy-weight process, if any. 467 */ 468 ProcessRecord mHeavyWeightProcess = null; 469 470 /** 471 * The last time that various processes have crashed. 472 */ 473 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 474 475 /** 476 * Information about a process that is currently marked as bad. 477 */ 478 static final class BadProcessInfo { 479 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 480 this.time = time; 481 this.shortMsg = shortMsg; 482 this.longMsg = longMsg; 483 this.stack = stack; 484 } 485 486 final long time; 487 final String shortMsg; 488 final String longMsg; 489 final String stack; 490 } 491 492 /** 493 * Set of applications that we consider to be bad, and will reject 494 * incoming broadcasts from (which the user has no control over). 495 * Processes are added to this set when they have crashed twice within 496 * a minimum amount of time; they are removed from it when they are 497 * later restarted (hopefully due to some user action). The value is the 498 * time it was added to the list. 499 */ 500 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 501 502 /** 503 * All of the processes we currently have running organized by pid. 504 * The keys are the pid running the application. 505 * 506 * <p>NOTE: This object is protected by its own lock, NOT the global 507 * activity manager lock! 508 */ 509 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 510 511 /** 512 * All of the processes that have been forced to be foreground. The key 513 * is the pid of the caller who requested it (we hold a death 514 * link on it). 515 */ 516 abstract class ForegroundToken implements IBinder.DeathRecipient { 517 int pid; 518 IBinder token; 519 } 520 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 521 522 /** 523 * List of records for processes that someone had tried to start before the 524 * system was ready. We don't start them at that point, but ensure they 525 * are started by the time booting is complete. 526 */ 527 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of persistent applications that are in the process 531 * of being started. 532 */ 533 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Processes that are being forcibly torn down. 537 */ 538 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 539 540 /** 541 * List of running applications, sorted by recent usage. 542 * The first entry in the list is the least recently used. 543 */ 544 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Where in mLruProcesses that the processes hosting activities start. 548 */ 549 int mLruProcessActivityStart = 0; 550 551 /** 552 * Where in mLruProcesses that the processes hosting services start. 553 * This is after (lower index) than mLruProcessesActivityStart. 554 */ 555 int mLruProcessServiceStart = 0; 556 557 /** 558 * List of processes that should gc as soon as things are idle. 559 */ 560 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Processes we want to collect PSS data from. 564 */ 565 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 566 567 /** 568 * Last time we requested PSS data of all processes. 569 */ 570 long mLastFullPssTime = SystemClock.uptimeMillis(); 571 572 /** 573 * This is the process holding what we currently consider to be 574 * the "home" activity. 575 */ 576 ProcessRecord mHomeProcess; 577 578 /** 579 * This is the process holding the activity the user last visited that 580 * is in a different process from the one they are currently in. 581 */ 582 ProcessRecord mPreviousProcess; 583 584 /** 585 * The time at which the previous process was last visible. 586 */ 587 long mPreviousProcessVisibleTime; 588 589 /** 590 * Which uses have been started, so are allowed to run code. 591 */ 592 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 593 594 /** 595 * LRU list of history of current users. Most recently current is at the end. 596 */ 597 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 598 599 /** 600 * Constant array of the users that are currently started. 601 */ 602 int[] mStartedUserArray = new int[] { 0 }; 603 604 /** 605 * Registered observers of the user switching mechanics. 606 */ 607 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 608 = new RemoteCallbackList<IUserSwitchObserver>(); 609 610 /** 611 * Currently active user switch. 612 */ 613 Object mCurUserSwitchCallback; 614 615 /** 616 * Packages that the user has asked to have run in screen size 617 * compatibility mode instead of filling the screen. 618 */ 619 final CompatModePackages mCompatModePackages; 620 621 /** 622 * Set of IntentSenderRecord objects that are currently active. 623 */ 624 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 625 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 626 627 /** 628 * Fingerprints (hashCode()) of stack traces that we've 629 * already logged DropBox entries for. Guarded by itself. If 630 * something (rogue user app) forces this over 631 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 632 */ 633 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 634 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 635 636 /** 637 * Strict Mode background batched logging state. 638 * 639 * The string buffer is guarded by itself, and its lock is also 640 * used to determine if another batched write is already 641 * in-flight. 642 */ 643 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 644 645 /** 646 * Keeps track of all IIntentReceivers that have been registered for 647 * broadcasts. Hash keys are the receiver IBinder, hash value is 648 * a ReceiverList. 649 */ 650 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 651 new HashMap<IBinder, ReceiverList>(); 652 653 /** 654 * Resolver for broadcast intents to registered receivers. 655 * Holds BroadcastFilter (subclass of IntentFilter). 656 */ 657 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 658 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 659 @Override 660 protected boolean allowFilterResult( 661 BroadcastFilter filter, List<BroadcastFilter> dest) { 662 IBinder target = filter.receiverList.receiver.asBinder(); 663 for (int i=dest.size()-1; i>=0; i--) { 664 if (dest.get(i).receiverList.receiver.asBinder() == target) { 665 return false; 666 } 667 } 668 return true; 669 } 670 671 @Override 672 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 673 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 674 || userId == filter.owningUserId) { 675 return super.newResult(filter, match, userId); 676 } 677 return null; 678 } 679 680 @Override 681 protected BroadcastFilter[] newArray(int size) { 682 return new BroadcastFilter[size]; 683 } 684 685 @Override 686 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 687 return packageName.equals(filter.packageName); 688 } 689 }; 690 691 /** 692 * State of all active sticky broadcasts per user. Keys are the action of the 693 * sticky Intent, values are an ArrayList of all broadcasted intents with 694 * that action (which should usually be one). The SparseArray is keyed 695 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 696 * for stickies that are sent to all users. 697 */ 698 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 699 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 700 701 final ActiveServices mServices; 702 703 /** 704 * Backup/restore process management 705 */ 706 String mBackupAppName = null; 707 BackupRecord mBackupTarget = null; 708 709 final ProviderMap mProviderMap; 710 711 /** 712 * List of content providers who have clients waiting for them. The 713 * application is currently being launched and the provider will be 714 * removed from this list once it is published. 715 */ 716 final ArrayList<ContentProviderRecord> mLaunchingProviders 717 = new ArrayList<ContentProviderRecord>(); 718 719 /** 720 * File storing persisted {@link #mGrantedUriPermissions}. 721 */ 722 private final AtomicFile mGrantFile; 723 724 /** XML constants used in {@link #mGrantFile} */ 725 private static final String TAG_URI_GRANTS = "uri-grants"; 726 private static final String TAG_URI_GRANT = "uri-grant"; 727 private static final String ATTR_USER_HANDLE = "userHandle"; 728 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 729 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 730 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 731 private static final String ATTR_TARGET_PKG = "targetPkg"; 732 private static final String ATTR_URI = "uri"; 733 private static final String ATTR_MODE_FLAGS = "modeFlags"; 734 private static final String ATTR_CREATED_TIME = "createdTime"; 735 private static final String ATTR_PREFIX = "prefix"; 736 737 /** 738 * Global set of specific {@link Uri} permissions that have been granted. 739 * This optimized lookup structure maps from {@link UriPermission#targetUid} 740 * to {@link UriPermission#uri} to {@link UriPermission}. 741 */ 742 @GuardedBy("this") 743 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 744 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 745 746 public static class GrantUri { 747 public final int sourceUserId; 748 public final Uri uri; 749 public boolean prefix; 750 751 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 752 this.sourceUserId = sourceUserId; 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) && (sourceUserId == other.sourceUserId) 767 && prefix == other.prefix; 768 } 769 return false; 770 } 771 772 @Override 773 public String toString() { 774 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 775 if (prefix) result += " [prefix]"; 776 return result; 777 } 778 779 public String toSafeString() { 780 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 781 if (prefix) result += " [prefix]"; 782 return result; 783 } 784 785 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 786 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 787 ContentProvider.getUriWithoutUserId(uri), false); 788 } 789 } 790 791 CoreSettingsObserver mCoreSettingsObserver; 792 793 /** 794 * Thread-local storage used to carry caller permissions over through 795 * indirect content-provider access. 796 */ 797 private class Identity { 798 public int pid; 799 public int uid; 800 801 Identity(int _pid, int _uid) { 802 pid = _pid; 803 uid = _uid; 804 } 805 } 806 807 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 808 809 /** 810 * All information we have collected about the runtime performance of 811 * any user id that can impact battery performance. 812 */ 813 final BatteryStatsService mBatteryStatsService; 814 815 /** 816 * Information about component usage 817 */ 818 final UsageStatsService mUsageStatsService; 819 820 /** 821 * Information about and control over application operations 822 */ 823 final AppOpsService mAppOpsService; 824 825 /** 826 * Save recent tasks information across reboots. 827 */ 828 final TaskPersister mTaskPersister; 829 830 /** 831 * Current configuration information. HistoryRecord objects are given 832 * a reference to this object to indicate which configuration they are 833 * currently running in, so this object must be kept immutable. 834 */ 835 Configuration mConfiguration = new Configuration(); 836 837 /** 838 * Current sequencing integer of the configuration, for skipping old 839 * configurations. 840 */ 841 int mConfigurationSeq = 0; 842 843 /** 844 * Hardware-reported OpenGLES version. 845 */ 846 final int GL_ES_VERSION; 847 848 /** 849 * List of initialization arguments to pass to all processes when binding applications to them. 850 * For example, references to the commonly used services. 851 */ 852 HashMap<String, IBinder> mAppBindArgs; 853 854 /** 855 * Temporary to avoid allocations. Protected by main lock. 856 */ 857 final StringBuilder mStringBuilder = new StringBuilder(256); 858 859 /** 860 * Used to control how we initialize the service. 861 */ 862 ComponentName mTopComponent; 863 String mTopAction = Intent.ACTION_MAIN; 864 String mTopData; 865 boolean mProcessesReady = false; 866 boolean mSystemReady = false; 867 boolean mBooting = false; 868 boolean mWaitingUpdate = false; 869 boolean mDidUpdate = false; 870 boolean mOnBattery = false; 871 boolean mLaunchWarningShown = false; 872 873 Context mContext; 874 875 int mFactoryTest; 876 877 boolean mCheckedForSetup; 878 879 /** 880 * The time at which we will allow normal application switches again, 881 * after a call to {@link #stopAppSwitches()}. 882 */ 883 long mAppSwitchesAllowedTime; 884 885 /** 886 * This is set to true after the first switch after mAppSwitchesAllowedTime 887 * is set; any switches after that will clear the time. 888 */ 889 boolean mDidAppSwitch; 890 891 /** 892 * Last time (in realtime) at which we checked for power usage. 893 */ 894 long mLastPowerCheckRealtime; 895 896 /** 897 * Last time (in uptime) at which we checked for power usage. 898 */ 899 long mLastPowerCheckUptime; 900 901 /** 902 * Set while we are wanting to sleep, to prevent any 903 * activities from being started/resumed. 904 */ 905 private boolean mSleeping = false; 906 907 /** 908 * Set while we are running a voice interaction. This overrides 909 * sleeping while it is active. 910 */ 911 private boolean mRunningVoice = false; 912 913 /** 914 * State of external calls telling us if the device is asleep. 915 */ 916 private boolean mWentToSleep = false; 917 918 /** 919 * State of external call telling us if the lock screen is shown. 920 */ 921 private boolean mLockScreenShown = false; 922 923 /** 924 * Set if we are shutting down the system, similar to sleeping. 925 */ 926 boolean mShuttingDown = false; 927 928 /** 929 * Current sequence id for oom_adj computation traversal. 930 */ 931 int mAdjSeq = 0; 932 933 /** 934 * Current sequence id for process LRU updating. 935 */ 936 int mLruSeq = 0; 937 938 /** 939 * Keep track of the non-cached/empty process we last found, to help 940 * determine how to distribute cached/empty processes next time. 941 */ 942 int mNumNonCachedProcs = 0; 943 944 /** 945 * Keep track of the number of cached hidden procs, to balance oom adj 946 * distribution between those and empty procs. 947 */ 948 int mNumCachedHiddenProcs = 0; 949 950 /** 951 * Keep track of the number of service processes we last found, to 952 * determine on the next iteration which should be B services. 953 */ 954 int mNumServiceProcs = 0; 955 int mNewNumAServiceProcs = 0; 956 int mNewNumServiceProcs = 0; 957 958 /** 959 * Allow the current computed overall memory level of the system to go down? 960 * This is set to false when we are killing processes for reasons other than 961 * memory management, so that the now smaller process list will not be taken as 962 * an indication that memory is tighter. 963 */ 964 boolean mAllowLowerMemLevel = false; 965 966 /** 967 * The last computed memory level, for holding when we are in a state that 968 * processes are going away for other reasons. 969 */ 970 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 971 972 /** 973 * The last total number of process we have, to determine if changes actually look 974 * like a shrinking number of process due to lower RAM. 975 */ 976 int mLastNumProcesses; 977 978 /** 979 * The uptime of the last time we performed idle maintenance. 980 */ 981 long mLastIdleTime = SystemClock.uptimeMillis(); 982 983 /** 984 * Total time spent with RAM that has been added in the past since the last idle time. 985 */ 986 long mLowRamTimeSinceLastIdle = 0; 987 988 /** 989 * If RAM is currently low, when that horrible situation started. 990 */ 991 long mLowRamStartTime = 0; 992 993 /** 994 * For reporting to battery stats the current top application. 995 */ 996 private String mCurResumedPackage = null; 997 private int mCurResumedUid = -1; 998 999 /** 1000 * For reporting to battery stats the apps currently running foreground 1001 * service. The ProcessMap is package/uid tuples; each of these contain 1002 * an array of the currently foreground processes. 1003 */ 1004 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1005 = new ProcessMap<ArrayList<ProcessRecord>>(); 1006 1007 /** 1008 * This is set if we had to do a delayed dexopt of an app before launching 1009 * it, to increase the ANR timeouts in that case. 1010 */ 1011 boolean mDidDexOpt; 1012 1013 /** 1014 * Set if the systemServer made a call to enterSafeMode. 1015 */ 1016 boolean mSafeMode; 1017 1018 String mDebugApp = null; 1019 boolean mWaitForDebugger = false; 1020 boolean mDebugTransient = false; 1021 String mOrigDebugApp = null; 1022 boolean mOrigWaitForDebugger = false; 1023 boolean mAlwaysFinishActivities = false; 1024 IActivityController mController = null; 1025 String mProfileApp = null; 1026 ProcessRecord mProfileProc = null; 1027 String mProfileFile; 1028 ParcelFileDescriptor mProfileFd; 1029 int mProfileType = 0; 1030 boolean mAutoStopProfiler = false; 1031 String mOpenGlTraceApp = null; 1032 1033 static class ProcessChangeItem { 1034 static final int CHANGE_ACTIVITIES = 1<<0; 1035 static final int CHANGE_PROCESS_STATE = 1<<1; 1036 int changes; 1037 int uid; 1038 int pid; 1039 int processState; 1040 boolean foregroundActivities; 1041 } 1042 1043 final RemoteCallbackList<IProcessObserver> mProcessObservers 1044 = new RemoteCallbackList<IProcessObserver>(); 1045 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1046 1047 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1048 = new ArrayList<ProcessChangeItem>(); 1049 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1050 = new ArrayList<ProcessChangeItem>(); 1051 1052 /** 1053 * Runtime CPU use collection thread. This object's lock is used to 1054 * protect all related state. 1055 */ 1056 final Thread mProcessCpuThread; 1057 1058 /** 1059 * Used to collect process stats when showing not responding dialog. 1060 * Protected by mProcessCpuThread. 1061 */ 1062 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1063 MONITOR_THREAD_CPU_USAGE); 1064 final AtomicLong mLastCpuTime = new AtomicLong(0); 1065 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1066 1067 long mLastWriteTime = 0; 1068 1069 /** 1070 * Used to retain an update lock when the foreground activity is in 1071 * immersive mode. 1072 */ 1073 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1074 1075 /** 1076 * Set to true after the system has finished booting. 1077 */ 1078 boolean mBooted = false; 1079 1080 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1081 int mProcessLimitOverride = -1; 1082 1083 WindowManagerService mWindowManager; 1084 1085 final ActivityThread mSystemThread; 1086 1087 int mCurrentUserId = 0; 1088 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1089 private UserManagerService mUserManager; 1090 1091 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1092 final ProcessRecord mApp; 1093 final int mPid; 1094 final IApplicationThread mAppThread; 1095 1096 AppDeathRecipient(ProcessRecord app, int pid, 1097 IApplicationThread thread) { 1098 if (localLOGV) Slog.v( 1099 TAG, "New death recipient " + this 1100 + " for thread " + thread.asBinder()); 1101 mApp = app; 1102 mPid = pid; 1103 mAppThread = thread; 1104 } 1105 1106 @Override 1107 public void binderDied() { 1108 if (localLOGV) Slog.v( 1109 TAG, "Death received in " + this 1110 + " for thread " + mAppThread.asBinder()); 1111 synchronized(ActivityManagerService.this) { 1112 appDiedLocked(mApp, mPid, mAppThread); 1113 } 1114 } 1115 } 1116 1117 static final int SHOW_ERROR_MSG = 1; 1118 static final int SHOW_NOT_RESPONDING_MSG = 2; 1119 static final int SHOW_FACTORY_ERROR_MSG = 3; 1120 static final int UPDATE_CONFIGURATION_MSG = 4; 1121 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1122 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1123 static final int SERVICE_TIMEOUT_MSG = 12; 1124 static final int UPDATE_TIME_ZONE = 13; 1125 static final int SHOW_UID_ERROR_MSG = 14; 1126 static final int IM_FEELING_LUCKY_MSG = 15; 1127 static final int PROC_START_TIMEOUT_MSG = 20; 1128 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1129 static final int KILL_APPLICATION_MSG = 22; 1130 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1131 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1132 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1133 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1134 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1135 static final int CLEAR_DNS_CACHE_MSG = 28; 1136 static final int UPDATE_HTTP_PROXY_MSG = 29; 1137 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1138 static final int DISPATCH_PROCESSES_CHANGED = 31; 1139 static final int DISPATCH_PROCESS_DIED = 32; 1140 static final int REPORT_MEM_USAGE_MSG = 33; 1141 static final int REPORT_USER_SWITCH_MSG = 34; 1142 static final int CONTINUE_USER_SWITCH_MSG = 35; 1143 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1144 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1145 static final int PERSIST_URI_GRANTS_MSG = 38; 1146 static final int REQUEST_ALL_PSS_MSG = 39; 1147 static final int START_PROFILES_MSG = 40; 1148 static final int UPDATE_TIME = 41; 1149 static final int SYSTEM_USER_START_MSG = 42; 1150 static final int SYSTEM_USER_CURRENT_MSG = 43; 1151 1152 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1153 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1154 static final int FIRST_COMPAT_MODE_MSG = 300; 1155 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1156 1157 AlertDialog mUidAlert; 1158 CompatModeDialog mCompatModeDialog; 1159 long mLastMemUsageReportTime = 0; 1160 1161 /** 1162 * Flag whether the current user is a "monkey", i.e. whether 1163 * the UI is driven by a UI automation tool. 1164 */ 1165 private boolean mUserIsMonkey; 1166 1167 final ServiceThread mHandlerThread; 1168 final MainHandler mHandler; 1169 1170 final class MainHandler extends Handler { 1171 public MainHandler(Looper looper) { 1172 super(looper, null, true); 1173 } 1174 1175 @Override 1176 public void handleMessage(Message msg) { 1177 switch (msg.what) { 1178 case SHOW_ERROR_MSG: { 1179 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1180 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1181 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1182 synchronized (ActivityManagerService.this) { 1183 ProcessRecord proc = (ProcessRecord)data.get("app"); 1184 AppErrorResult res = (AppErrorResult) data.get("result"); 1185 if (proc != null && proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has crash dialog: " + proc); 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 return; 1191 } 1192 if (!showBackground && UserHandle.getAppId(proc.uid) 1193 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1194 && proc.pid != MY_PID) { 1195 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1196 if (res != null) { 1197 res.set(0); 1198 } 1199 return; 1200 } 1201 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1202 Dialog d = new AppErrorDialog(mContext, 1203 ActivityManagerService.this, res, proc); 1204 d.show(); 1205 proc.crashDialog = d; 1206 } else { 1207 // The device is asleep, so just pretend that the user 1208 // saw a crash dialog and hit "force quit". 1209 if (res != null) { 1210 res.set(0); 1211 } 1212 } 1213 } 1214 1215 ensureBootCompleted(); 1216 } break; 1217 case SHOW_NOT_RESPONDING_MSG: { 1218 synchronized (ActivityManagerService.this) { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 ProcessRecord proc = (ProcessRecord)data.get("app"); 1221 if (proc != null && proc.anrDialog != null) { 1222 Slog.e(TAG, "App already has anr dialog: " + proc); 1223 return; 1224 } 1225 1226 Intent intent = new Intent("android.intent.action.ANR"); 1227 if (!mProcessesReady) { 1228 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1229 | Intent.FLAG_RECEIVER_FOREGROUND); 1230 } 1231 broadcastIntentLocked(null, null, intent, 1232 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1233 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1234 1235 if (mShowDialogs) { 1236 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1237 mContext, proc, (ActivityRecord)data.get("activity"), 1238 msg.arg1 != 0); 1239 d.show(); 1240 proc.anrDialog = d; 1241 } else { 1242 // Just kill the app if there is no dialog to be shown. 1243 killAppAtUsersRequest(proc, null); 1244 } 1245 } 1246 1247 ensureBootCompleted(); 1248 } break; 1249 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1250 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1251 synchronized (ActivityManagerService.this) { 1252 ProcessRecord proc = (ProcessRecord) data.get("app"); 1253 if (proc == null) { 1254 Slog.e(TAG, "App not found when showing strict mode dialog."); 1255 break; 1256 } 1257 if (proc.crashDialog != null) { 1258 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1259 return; 1260 } 1261 AppErrorResult res = (AppErrorResult) data.get("result"); 1262 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1263 Dialog d = new StrictModeViolationDialog(mContext, 1264 ActivityManagerService.this, res, proc); 1265 d.show(); 1266 proc.crashDialog = d; 1267 } else { 1268 // The device is asleep, so just pretend that the user 1269 // saw a crash dialog and hit "force quit". 1270 res.set(0); 1271 } 1272 } 1273 ensureBootCompleted(); 1274 } break; 1275 case SHOW_FACTORY_ERROR_MSG: { 1276 Dialog d = new FactoryErrorDialog( 1277 mContext, msg.getData().getCharSequence("msg")); 1278 d.show(); 1279 ensureBootCompleted(); 1280 } break; 1281 case UPDATE_CONFIGURATION_MSG: { 1282 final ContentResolver resolver = mContext.getContentResolver(); 1283 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1284 } break; 1285 case GC_BACKGROUND_PROCESSES_MSG: { 1286 synchronized (ActivityManagerService.this) { 1287 performAppGcsIfAppropriateLocked(); 1288 } 1289 } break; 1290 case WAIT_FOR_DEBUGGER_MSG: { 1291 synchronized (ActivityManagerService.this) { 1292 ProcessRecord app = (ProcessRecord)msg.obj; 1293 if (msg.arg1 != 0) { 1294 if (!app.waitedForDebugger) { 1295 Dialog d = new AppWaitingForDebuggerDialog( 1296 ActivityManagerService.this, 1297 mContext, app); 1298 app.waitDialog = d; 1299 app.waitedForDebugger = true; 1300 d.show(); 1301 } 1302 } else { 1303 if (app.waitDialog != null) { 1304 app.waitDialog.dismiss(); 1305 app.waitDialog = null; 1306 } 1307 } 1308 } 1309 } break; 1310 case SERVICE_TIMEOUT_MSG: { 1311 if (mDidDexOpt) { 1312 mDidDexOpt = false; 1313 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1314 nmsg.obj = msg.obj; 1315 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1316 return; 1317 } 1318 mServices.serviceTimeout((ProcessRecord)msg.obj); 1319 } break; 1320 case UPDATE_TIME_ZONE: { 1321 synchronized (ActivityManagerService.this) { 1322 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1323 ProcessRecord r = mLruProcesses.get(i); 1324 if (r.thread != null) { 1325 try { 1326 r.thread.updateTimeZone(); 1327 } catch (RemoteException ex) { 1328 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1329 } 1330 } 1331 } 1332 } 1333 } break; 1334 case CLEAR_DNS_CACHE_MSG: { 1335 synchronized (ActivityManagerService.this) { 1336 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1337 ProcessRecord r = mLruProcesses.get(i); 1338 if (r.thread != null) { 1339 try { 1340 r.thread.clearDnsCache(); 1341 } catch (RemoteException ex) { 1342 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1343 } 1344 } 1345 } 1346 } 1347 } break; 1348 case UPDATE_HTTP_PROXY_MSG: { 1349 ProxyInfo proxy = (ProxyInfo)msg.obj; 1350 String host = ""; 1351 String port = ""; 1352 String exclList = ""; 1353 Uri pacFileUrl = Uri.EMPTY; 1354 if (proxy != null) { 1355 host = proxy.getHost(); 1356 port = Integer.toString(proxy.getPort()); 1357 exclList = proxy.getExclusionListAsString(); 1358 pacFileUrl = proxy.getPacFileUrl(); 1359 } 1360 synchronized (ActivityManagerService.this) { 1361 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1362 ProcessRecord r = mLruProcesses.get(i); 1363 if (r.thread != null) { 1364 try { 1365 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1366 } catch (RemoteException ex) { 1367 Slog.w(TAG, "Failed to update http proxy for: " + 1368 r.info.processName); 1369 } 1370 } 1371 } 1372 } 1373 } break; 1374 case SHOW_UID_ERROR_MSG: { 1375 String title = "System UIDs Inconsistent"; 1376 String text = "UIDs on the system are inconsistent, you need to wipe your" 1377 + " data partition or your device will be unstable."; 1378 Log.e(TAG, title + ": " + text); 1379 if (mShowDialogs) { 1380 // XXX This is a temporary dialog, no need to localize. 1381 AlertDialog d = new BaseErrorDialog(mContext); 1382 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1383 d.setCancelable(false); 1384 d.setTitle(title); 1385 d.setMessage(text); 1386 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1387 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1388 mUidAlert = d; 1389 d.show(); 1390 } 1391 } break; 1392 case IM_FEELING_LUCKY_MSG: { 1393 if (mUidAlert != null) { 1394 mUidAlert.dismiss(); 1395 mUidAlert = null; 1396 } 1397 } break; 1398 case PROC_START_TIMEOUT_MSG: { 1399 if (mDidDexOpt) { 1400 mDidDexOpt = false; 1401 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1402 nmsg.obj = msg.obj; 1403 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1404 return; 1405 } 1406 ProcessRecord app = (ProcessRecord)msg.obj; 1407 synchronized (ActivityManagerService.this) { 1408 processStartTimedOutLocked(app); 1409 } 1410 } break; 1411 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1412 synchronized (ActivityManagerService.this) { 1413 doPendingActivityLaunchesLocked(true); 1414 } 1415 } break; 1416 case KILL_APPLICATION_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 int appid = msg.arg1; 1419 boolean restart = (msg.arg2 == 1); 1420 Bundle bundle = (Bundle)msg.obj; 1421 String pkg = bundle.getString("pkg"); 1422 String reason = bundle.getString("reason"); 1423 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1424 false, UserHandle.USER_ALL, reason); 1425 } 1426 } break; 1427 case FINALIZE_PENDING_INTENT_MSG: { 1428 ((PendingIntentRecord)msg.obj).completeFinalize(); 1429 } break; 1430 case POST_HEAVY_NOTIFICATION_MSG: { 1431 INotificationManager inm = NotificationManager.getService(); 1432 if (inm == null) { 1433 return; 1434 } 1435 1436 ActivityRecord root = (ActivityRecord)msg.obj; 1437 ProcessRecord process = root.app; 1438 if (process == null) { 1439 return; 1440 } 1441 1442 try { 1443 Context context = mContext.createPackageContext(process.info.packageName, 0); 1444 String text = mContext.getString(R.string.heavy_weight_notification, 1445 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1446 Notification notification = new Notification(); 1447 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1448 notification.when = 0; 1449 notification.flags = Notification.FLAG_ONGOING_EVENT; 1450 notification.tickerText = text; 1451 notification.defaults = 0; // please be quiet 1452 notification.sound = null; 1453 notification.vibrate = null; 1454 notification.setLatestEventInfo(context, text, 1455 mContext.getText(R.string.heavy_weight_notification_detail), 1456 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1457 PendingIntent.FLAG_CANCEL_CURRENT, null, 1458 new UserHandle(root.userId))); 1459 1460 try { 1461 int[] outId = new int[1]; 1462 inm.enqueueNotificationWithTag("android", "android", null, 1463 R.string.heavy_weight_notification, 1464 notification, outId, root.userId); 1465 } catch (RuntimeException e) { 1466 Slog.w(ActivityManagerService.TAG, 1467 "Error showing notification for heavy-weight app", e); 1468 } catch (RemoteException e) { 1469 } 1470 } catch (NameNotFoundException e) { 1471 Slog.w(TAG, "Unable to create context for heavy notification", e); 1472 } 1473 } break; 1474 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1475 INotificationManager inm = NotificationManager.getService(); 1476 if (inm == null) { 1477 return; 1478 } 1479 try { 1480 inm.cancelNotificationWithTag("android", null, 1481 R.string.heavy_weight_notification, msg.arg1); 1482 } catch (RuntimeException e) { 1483 Slog.w(ActivityManagerService.TAG, 1484 "Error canceling notification for service", e); 1485 } catch (RemoteException e) { 1486 } 1487 } break; 1488 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1489 synchronized (ActivityManagerService.this) { 1490 checkExcessivePowerUsageLocked(true); 1491 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1492 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1493 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1494 } 1495 } break; 1496 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1497 synchronized (ActivityManagerService.this) { 1498 ActivityRecord ar = (ActivityRecord)msg.obj; 1499 if (mCompatModeDialog != null) { 1500 if (mCompatModeDialog.mAppInfo.packageName.equals( 1501 ar.info.applicationInfo.packageName)) { 1502 return; 1503 } 1504 mCompatModeDialog.dismiss(); 1505 mCompatModeDialog = null; 1506 } 1507 if (ar != null && false) { 1508 if (mCompatModePackages.getPackageAskCompatModeLocked( 1509 ar.packageName)) { 1510 int mode = mCompatModePackages.computeCompatModeLocked( 1511 ar.info.applicationInfo); 1512 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1513 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1514 mCompatModeDialog = new CompatModeDialog( 1515 ActivityManagerService.this, mContext, 1516 ar.info.applicationInfo); 1517 mCompatModeDialog.show(); 1518 } 1519 } 1520 } 1521 } 1522 break; 1523 } 1524 case DISPATCH_PROCESSES_CHANGED: { 1525 dispatchProcessesChanged(); 1526 break; 1527 } 1528 case DISPATCH_PROCESS_DIED: { 1529 final int pid = msg.arg1; 1530 final int uid = msg.arg2; 1531 dispatchProcessDied(pid, uid); 1532 break; 1533 } 1534 case REPORT_MEM_USAGE_MSG: { 1535 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1536 Thread thread = new Thread() { 1537 @Override public void run() { 1538 final SparseArray<ProcessMemInfo> infoMap 1539 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1540 for (int i=0, N=memInfos.size(); i<N; i++) { 1541 ProcessMemInfo mi = memInfos.get(i); 1542 infoMap.put(mi.pid, mi); 1543 } 1544 updateCpuStatsNow(); 1545 synchronized (mProcessCpuThread) { 1546 final int N = mProcessCpuTracker.countStats(); 1547 for (int i=0; i<N; i++) { 1548 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1549 if (st.vsize > 0) { 1550 long pss = Debug.getPss(st.pid, null); 1551 if (pss > 0) { 1552 if (infoMap.indexOfKey(st.pid) < 0) { 1553 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1554 ProcessList.NATIVE_ADJ, -1, "native", null); 1555 mi.pss = pss; 1556 memInfos.add(mi); 1557 } 1558 } 1559 } 1560 } 1561 } 1562 1563 long totalPss = 0; 1564 for (int i=0, N=memInfos.size(); i<N; i++) { 1565 ProcessMemInfo mi = memInfos.get(i); 1566 if (mi.pss == 0) { 1567 mi.pss = Debug.getPss(mi.pid, null); 1568 } 1569 totalPss += mi.pss; 1570 } 1571 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1572 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1573 if (lhs.oomAdj != rhs.oomAdj) { 1574 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1575 } 1576 if (lhs.pss != rhs.pss) { 1577 return lhs.pss < rhs.pss ? 1 : -1; 1578 } 1579 return 0; 1580 } 1581 }); 1582 1583 StringBuilder tag = new StringBuilder(128); 1584 StringBuilder stack = new StringBuilder(128); 1585 tag.append("Low on memory -- "); 1586 appendMemBucket(tag, totalPss, "total", false); 1587 appendMemBucket(stack, totalPss, "total", true); 1588 1589 StringBuilder logBuilder = new StringBuilder(1024); 1590 logBuilder.append("Low on memory:\n"); 1591 1592 boolean firstLine = true; 1593 int lastOomAdj = Integer.MIN_VALUE; 1594 for (int i=0, N=memInfos.size(); i<N; i++) { 1595 ProcessMemInfo mi = memInfos.get(i); 1596 1597 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1598 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1599 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1600 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1601 if (lastOomAdj != mi.oomAdj) { 1602 lastOomAdj = mi.oomAdj; 1603 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1604 tag.append(" / "); 1605 } 1606 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1607 if (firstLine) { 1608 stack.append(":"); 1609 firstLine = false; 1610 } 1611 stack.append("\n\t at "); 1612 } else { 1613 stack.append("$"); 1614 } 1615 } else { 1616 tag.append(" "); 1617 stack.append("$"); 1618 } 1619 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1620 appendMemBucket(tag, mi.pss, mi.name, false); 1621 } 1622 appendMemBucket(stack, mi.pss, mi.name, true); 1623 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1624 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1625 stack.append("("); 1626 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1627 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1628 stack.append(DUMP_MEM_OOM_LABEL[k]); 1629 stack.append(":"); 1630 stack.append(DUMP_MEM_OOM_ADJ[k]); 1631 } 1632 } 1633 stack.append(")"); 1634 } 1635 } 1636 1637 logBuilder.append(" "); 1638 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1639 logBuilder.append(' '); 1640 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1641 logBuilder.append(' '); 1642 ProcessList.appendRamKb(logBuilder, mi.pss); 1643 logBuilder.append(" kB: "); 1644 logBuilder.append(mi.name); 1645 logBuilder.append(" ("); 1646 logBuilder.append(mi.pid); 1647 logBuilder.append(") "); 1648 logBuilder.append(mi.adjType); 1649 logBuilder.append('\n'); 1650 if (mi.adjReason != null) { 1651 logBuilder.append(" "); 1652 logBuilder.append(mi.adjReason); 1653 logBuilder.append('\n'); 1654 } 1655 } 1656 1657 logBuilder.append(" "); 1658 ProcessList.appendRamKb(logBuilder, totalPss); 1659 logBuilder.append(" kB: TOTAL\n"); 1660 1661 long[] infos = new long[Debug.MEMINFO_COUNT]; 1662 Debug.getMemInfo(infos); 1663 logBuilder.append(" MemInfo: "); 1664 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1665 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1666 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1667 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1668 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1669 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1670 logBuilder.append(" ZRAM: "); 1671 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1672 logBuilder.append(" kB RAM, "); 1673 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1674 logBuilder.append(" kB swap total, "); 1675 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1676 logBuilder.append(" kB swap free\n"); 1677 } 1678 Slog.i(TAG, logBuilder.toString()); 1679 1680 StringBuilder dropBuilder = new StringBuilder(1024); 1681 /* 1682 StringWriter oomSw = new StringWriter(); 1683 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1684 StringWriter catSw = new StringWriter(); 1685 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1686 String[] emptyArgs = new String[] { }; 1687 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1688 oomPw.flush(); 1689 String oomString = oomSw.toString(); 1690 */ 1691 dropBuilder.append(stack); 1692 dropBuilder.append('\n'); 1693 dropBuilder.append('\n'); 1694 dropBuilder.append(logBuilder); 1695 dropBuilder.append('\n'); 1696 /* 1697 dropBuilder.append(oomString); 1698 dropBuilder.append('\n'); 1699 */ 1700 StringWriter catSw = new StringWriter(); 1701 synchronized (ActivityManagerService.this) { 1702 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1703 String[] emptyArgs = new String[] { }; 1704 catPw.println(); 1705 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1706 catPw.println(); 1707 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1708 false, false, null); 1709 catPw.println(); 1710 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1711 catPw.flush(); 1712 } 1713 dropBuilder.append(catSw.toString()); 1714 addErrorToDropBox("lowmem", null, "system_server", null, 1715 null, tag.toString(), dropBuilder.toString(), null, null); 1716 //Slog.i(TAG, "Sent to dropbox:"); 1717 //Slog.i(TAG, dropBuilder.toString()); 1718 synchronized (ActivityManagerService.this) { 1719 long now = SystemClock.uptimeMillis(); 1720 if (mLastMemUsageReportTime < now) { 1721 mLastMemUsageReportTime = now; 1722 } 1723 } 1724 } 1725 }; 1726 thread.start(); 1727 break; 1728 } 1729 case REPORT_USER_SWITCH_MSG: { 1730 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1731 break; 1732 } 1733 case CONTINUE_USER_SWITCH_MSG: { 1734 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1735 break; 1736 } 1737 case USER_SWITCH_TIMEOUT_MSG: { 1738 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1739 break; 1740 } 1741 case IMMERSIVE_MODE_LOCK_MSG: { 1742 final boolean nextState = (msg.arg1 != 0); 1743 if (mUpdateLock.isHeld() != nextState) { 1744 if (DEBUG_IMMERSIVE) { 1745 final ActivityRecord r = (ActivityRecord) msg.obj; 1746 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1747 } 1748 if (nextState) { 1749 mUpdateLock.acquire(); 1750 } else { 1751 mUpdateLock.release(); 1752 } 1753 } 1754 break; 1755 } 1756 case PERSIST_URI_GRANTS_MSG: { 1757 writeGrantedUriPermissions(); 1758 break; 1759 } 1760 case REQUEST_ALL_PSS_MSG: { 1761 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1762 break; 1763 } 1764 case START_PROFILES_MSG: { 1765 synchronized (ActivityManagerService.this) { 1766 startProfilesLocked(); 1767 } 1768 break; 1769 } 1770 case UPDATE_TIME: { 1771 synchronized (ActivityManagerService.this) { 1772 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1773 ProcessRecord r = mLruProcesses.get(i); 1774 if (r.thread != null) { 1775 try { 1776 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1777 } catch (RemoteException ex) { 1778 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1779 } 1780 } 1781 } 1782 } 1783 break; 1784 } 1785 case SYSTEM_USER_START_MSG: { 1786 mSystemServiceManager.startUser(msg.arg1); 1787 break; 1788 } 1789 case SYSTEM_USER_CURRENT_MSG: { 1790 mSystemServiceManager.switchUser(msg.arg1); 1791 break; 1792 } 1793 } 1794 } 1795 }; 1796 1797 static final int COLLECT_PSS_BG_MSG = 1; 1798 1799 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1800 @Override 1801 public void handleMessage(Message msg) { 1802 switch (msg.what) { 1803 case COLLECT_PSS_BG_MSG: { 1804 int i=0, num=0; 1805 long start = SystemClock.uptimeMillis(); 1806 long[] tmp = new long[1]; 1807 do { 1808 ProcessRecord proc; 1809 int procState; 1810 int pid; 1811 synchronized (ActivityManagerService.this) { 1812 if (i >= mPendingPssProcesses.size()) { 1813 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1814 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1815 mPendingPssProcesses.clear(); 1816 return; 1817 } 1818 proc = mPendingPssProcesses.get(i); 1819 procState = proc.pssProcState; 1820 if (proc.thread != null && procState == proc.setProcState) { 1821 pid = proc.pid; 1822 } else { 1823 proc = null; 1824 pid = 0; 1825 } 1826 i++; 1827 } 1828 if (proc != null) { 1829 long pss = Debug.getPss(pid, tmp); 1830 synchronized (ActivityManagerService.this) { 1831 if (proc.thread != null && proc.setProcState == procState 1832 && proc.pid == pid) { 1833 num++; 1834 proc.lastPssTime = SystemClock.uptimeMillis(); 1835 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1836 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1837 + ": " + pss + " lastPss=" + proc.lastPss 1838 + " state=" + ProcessList.makeProcStateString(procState)); 1839 if (proc.initialIdlePss == 0) { 1840 proc.initialIdlePss = pss; 1841 } 1842 proc.lastPss = pss; 1843 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1844 proc.lastCachedPss = pss; 1845 } 1846 } 1847 } 1848 } 1849 } while (true); 1850 } 1851 } 1852 } 1853 }; 1854 1855 /** 1856 * Monitor for package changes and update our internal state. 1857 */ 1858 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1859 @Override 1860 public void onPackageRemoved(String packageName, int uid) { 1861 // Remove all tasks with activities in the specified package from the list of recent tasks 1862 synchronized (ActivityManagerService.this) { 1863 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1864 TaskRecord tr = mRecentTasks.get(i); 1865 ComponentName cn = tr.intent.getComponent(); 1866 if (cn != null && cn.getPackageName().equals(packageName)) { 1867 // If the package name matches, remove the task and kill the process 1868 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1869 } 1870 } 1871 } 1872 } 1873 1874 @Override 1875 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1876 onPackageModified(packageName); 1877 return true; 1878 } 1879 1880 @Override 1881 public void onPackageModified(String packageName) { 1882 final PackageManager pm = mContext.getPackageManager(); 1883 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1884 new ArrayList<Pair<Intent, Integer>>(); 1885 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1886 // Copy the list of recent tasks so that we don't hold onto the lock on 1887 // ActivityManagerService for long periods while checking if components exist. 1888 synchronized (ActivityManagerService.this) { 1889 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1890 TaskRecord tr = mRecentTasks.get(i); 1891 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1892 } 1893 } 1894 // Check the recent tasks and filter out all tasks with components that no longer exist. 1895 Intent tmpI = new Intent(); 1896 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1897 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1898 ComponentName cn = p.first.getComponent(); 1899 if (cn != null && cn.getPackageName().equals(packageName)) { 1900 try { 1901 // Add the task to the list to remove if the component no longer exists 1902 tmpI.setComponent(cn); 1903 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1904 tasksToRemove.add(p.second); 1905 } 1906 } catch (Exception e) {} 1907 } 1908 } 1909 // Prune all the tasks with removed components from the list of recent tasks 1910 synchronized (ActivityManagerService.this) { 1911 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1912 // Remove the task but don't kill the process (since other components in that 1913 // package may still be running and in the background) 1914 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1915 } 1916 } 1917 } 1918 1919 @Override 1920 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1921 // Force stop the specified packages 1922 if (packages != null) { 1923 for (String pkg : packages) { 1924 synchronized (ActivityManagerService.this) { 1925 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1926 "finished booting")) { 1927 return true; 1928 } 1929 } 1930 } 1931 } 1932 return false; 1933 } 1934 }; 1935 1936 public void setSystemProcess() { 1937 try { 1938 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1939 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1940 ServiceManager.addService("meminfo", new MemBinder(this)); 1941 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1942 ServiceManager.addService("dbinfo", new DbBinder(this)); 1943 if (MONITOR_CPU_USAGE) { 1944 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1945 } 1946 ServiceManager.addService("permission", new PermissionController(this)); 1947 1948 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1949 "android", STOCK_PM_FLAGS); 1950 mSystemThread.installSystemApplicationInfo(info); 1951 1952 synchronized (this) { 1953 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1954 app.persistent = true; 1955 app.pid = MY_PID; 1956 app.maxAdj = ProcessList.SYSTEM_ADJ; 1957 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1958 mProcessNames.put(app.processName, app.uid, app); 1959 synchronized (mPidsSelfLocked) { 1960 mPidsSelfLocked.put(app.pid, app); 1961 } 1962 updateLruProcessLocked(app, false, null); 1963 updateOomAdjLocked(); 1964 } 1965 } catch (PackageManager.NameNotFoundException e) { 1966 throw new RuntimeException( 1967 "Unable to find android system package", e); 1968 } 1969 } 1970 1971 public void setWindowManager(WindowManagerService wm) { 1972 mWindowManager = wm; 1973 mStackSupervisor.setWindowManager(wm); 1974 } 1975 1976 public void startObservingNativeCrashes() { 1977 final NativeCrashListener ncl = new NativeCrashListener(this); 1978 ncl.start(); 1979 } 1980 1981 public IAppOpsService getAppOpsService() { 1982 return mAppOpsService; 1983 } 1984 1985 static class MemBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 MemBinder(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 meminfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2002 } 2003 } 2004 2005 static class GraphicsBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 GraphicsBinder(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 gfxinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2022 } 2023 } 2024 2025 static class DbBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 DbBinder(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 dbinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 mActivityManagerService.dumpDbInfo(fd, pw, args); 2042 } 2043 } 2044 2045 static class CpuBinder extends Binder { 2046 ActivityManagerService mActivityManagerService; 2047 CpuBinder(ActivityManagerService activityManagerService) { 2048 mActivityManagerService = activityManagerService; 2049 } 2050 2051 @Override 2052 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2053 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2054 != PackageManager.PERMISSION_GRANTED) { 2055 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2056 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2057 + " without permission " + android.Manifest.permission.DUMP); 2058 return; 2059 } 2060 2061 synchronized (mActivityManagerService.mProcessCpuThread) { 2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2063 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2064 SystemClock.uptimeMillis())); 2065 } 2066 } 2067 } 2068 2069 public static final class Lifecycle extends SystemService { 2070 private final ActivityManagerService mService; 2071 2072 public Lifecycle(Context context) { 2073 super(context); 2074 mService = new ActivityManagerService(context); 2075 } 2076 2077 @Override 2078 public void onStart() { 2079 mService.start(); 2080 } 2081 2082 public ActivityManagerService getService() { 2083 return mService; 2084 } 2085 } 2086 2087 // Note: This method is invoked on the main thread but may need to attach various 2088 // handlers to other threads. So take care to be explicit about the looper. 2089 public ActivityManagerService(Context systemContext) { 2090 mContext = systemContext; 2091 mFactoryTest = FactoryTest.getMode(); 2092 mSystemThread = ActivityThread.currentActivityThread(); 2093 2094 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2095 2096 mHandlerThread = new ServiceThread(TAG, 2097 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2098 mHandlerThread.start(); 2099 mHandler = new MainHandler(mHandlerThread.getLooper()); 2100 2101 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2102 "foreground", BROADCAST_FG_TIMEOUT, false); 2103 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2104 "background", BROADCAST_BG_TIMEOUT, true); 2105 mBroadcastQueues[0] = mFgBroadcastQueue; 2106 mBroadcastQueues[1] = mBgBroadcastQueue; 2107 2108 mServices = new ActiveServices(this); 2109 mProviderMap = new ProviderMap(this); 2110 2111 // TODO: Move creation of battery stats service outside of activity manager service. 2112 File dataDir = Environment.getDataDirectory(); 2113 File systemDir = new File(dataDir, "system"); 2114 systemDir.mkdirs(); 2115 mBatteryStatsService = new BatteryStatsService(new File( 2116 systemDir, "batterystats.bin").toString(), mHandler); 2117 mBatteryStatsService.getActiveStatistics().readLocked(); 2118 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2119 mOnBattery = DEBUG_POWER ? true 2120 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2121 mBatteryStatsService.getActiveStatistics().setCallback(this); 2122 2123 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2124 2125 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2126 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2127 2128 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2129 2130 // User 0 is the first and only user that runs at boot. 2131 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2132 mUserLru.add(Integer.valueOf(0)); 2133 updateStartedUserArrayLocked(); 2134 2135 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2136 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2137 2138 mConfiguration.setToDefaults(); 2139 mConfiguration.setLocale(Locale.getDefault()); 2140 2141 mConfigurationSeq = mConfiguration.seq = 1; 2142 mProcessCpuTracker.init(); 2143 2144 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2145 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2146 mStackSupervisor = new ActivityStackSupervisor(this); 2147 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2148 2149 mProcessCpuThread = new Thread("CpuTracker") { 2150 @Override 2151 public void run() { 2152 while (true) { 2153 try { 2154 try { 2155 synchronized(this) { 2156 final long now = SystemClock.uptimeMillis(); 2157 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2158 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2159 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2160 // + ", write delay=" + nextWriteDelay); 2161 if (nextWriteDelay < nextCpuDelay) { 2162 nextCpuDelay = nextWriteDelay; 2163 } 2164 if (nextCpuDelay > 0) { 2165 mProcessCpuMutexFree.set(true); 2166 this.wait(nextCpuDelay); 2167 } 2168 } 2169 } catch (InterruptedException e) { 2170 } 2171 updateCpuStatsNow(); 2172 } catch (Exception e) { 2173 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2174 } 2175 } 2176 } 2177 }; 2178 2179 Watchdog.getInstance().addMonitor(this); 2180 Watchdog.getInstance().addThread(mHandler); 2181 } 2182 2183 public void setSystemServiceManager(SystemServiceManager mgr) { 2184 mSystemServiceManager = mgr; 2185 } 2186 2187 private void start() { 2188 mProcessCpuThread.start(); 2189 2190 mBatteryStatsService.publish(mContext); 2191 mUsageStatsService.publish(mContext); 2192 mAppOpsService.publish(mContext); 2193 Slog.d("AppOps", "AppOpsService published"); 2194 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2195 } 2196 2197 public void initPowerManagement() { 2198 mStackSupervisor.initPowerManagement(); 2199 mBatteryStatsService.initPowerManagement(); 2200 } 2201 2202 @Override 2203 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2204 throws RemoteException { 2205 if (code == SYSPROPS_TRANSACTION) { 2206 // We need to tell all apps about the system property change. 2207 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2208 synchronized(this) { 2209 final int NP = mProcessNames.getMap().size(); 2210 for (int ip=0; ip<NP; ip++) { 2211 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2212 final int NA = apps.size(); 2213 for (int ia=0; ia<NA; ia++) { 2214 ProcessRecord app = apps.valueAt(ia); 2215 if (app.thread != null) { 2216 procs.add(app.thread.asBinder()); 2217 } 2218 } 2219 } 2220 } 2221 2222 int N = procs.size(); 2223 for (int i=0; i<N; i++) { 2224 Parcel data2 = Parcel.obtain(); 2225 try { 2226 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2227 } catch (RemoteException e) { 2228 } 2229 data2.recycle(); 2230 } 2231 } 2232 try { 2233 return super.onTransact(code, data, reply, flags); 2234 } catch (RuntimeException e) { 2235 // The activity manager only throws security exceptions, so let's 2236 // log all others. 2237 if (!(e instanceof SecurityException)) { 2238 Slog.wtf(TAG, "Activity Manager Crash", e); 2239 } 2240 throw e; 2241 } 2242 } 2243 2244 void updateCpuStats() { 2245 final long now = SystemClock.uptimeMillis(); 2246 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2247 return; 2248 } 2249 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2250 synchronized (mProcessCpuThread) { 2251 mProcessCpuThread.notify(); 2252 } 2253 } 2254 } 2255 2256 void updateCpuStatsNow() { 2257 synchronized (mProcessCpuThread) { 2258 mProcessCpuMutexFree.set(false); 2259 final long now = SystemClock.uptimeMillis(); 2260 boolean haveNewCpuStats = false; 2261 2262 if (MONITOR_CPU_USAGE && 2263 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2264 mLastCpuTime.set(now); 2265 haveNewCpuStats = true; 2266 mProcessCpuTracker.update(); 2267 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2268 //Slog.i(TAG, "Total CPU usage: " 2269 // + mProcessCpu.getTotalCpuPercent() + "%"); 2270 2271 // Slog the cpu usage if the property is set. 2272 if ("true".equals(SystemProperties.get("events.cpu"))) { 2273 int user = mProcessCpuTracker.getLastUserTime(); 2274 int system = mProcessCpuTracker.getLastSystemTime(); 2275 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2276 int irq = mProcessCpuTracker.getLastIrqTime(); 2277 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2278 int idle = mProcessCpuTracker.getLastIdleTime(); 2279 2280 int total = user + system + iowait + irq + softIrq + idle; 2281 if (total == 0) total = 1; 2282 2283 EventLog.writeEvent(EventLogTags.CPU, 2284 ((user+system+iowait+irq+softIrq) * 100) / total, 2285 (user * 100) / total, 2286 (system * 100) / total, 2287 (iowait * 100) / total, 2288 (irq * 100) / total, 2289 (softIrq * 100) / total); 2290 } 2291 } 2292 2293 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2294 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2295 synchronized(bstats) { 2296 synchronized(mPidsSelfLocked) { 2297 if (haveNewCpuStats) { 2298 if (mOnBattery) { 2299 int perc = bstats.startAddingCpuLocked(); 2300 int totalUTime = 0; 2301 int totalSTime = 0; 2302 final int N = mProcessCpuTracker.countStats(); 2303 for (int i=0; i<N; i++) { 2304 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2305 if (!st.working) { 2306 continue; 2307 } 2308 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2309 int otherUTime = (st.rel_utime*perc)/100; 2310 int otherSTime = (st.rel_stime*perc)/100; 2311 totalUTime += otherUTime; 2312 totalSTime += otherSTime; 2313 if (pr != null) { 2314 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2315 if (ps == null || !ps.isActive()) { 2316 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2317 pr.info.uid, pr.processName); 2318 } 2319 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2320 st.rel_stime-otherSTime); 2321 ps.addSpeedStepTimes(cpuSpeedTimes); 2322 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2323 } else { 2324 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2325 if (ps == null || !ps.isActive()) { 2326 st.batteryStats = ps = bstats.getProcessStatsLocked( 2327 bstats.mapUid(st.uid), st.name); 2328 } 2329 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2330 st.rel_stime-otherSTime); 2331 ps.addSpeedStepTimes(cpuSpeedTimes); 2332 } 2333 } 2334 bstats.finishAddingCpuLocked(perc, totalUTime, 2335 totalSTime, cpuSpeedTimes); 2336 } 2337 } 2338 } 2339 2340 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2341 mLastWriteTime = now; 2342 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2343 } 2344 } 2345 } 2346 } 2347 2348 @Override 2349 public void batteryNeedsCpuUpdate() { 2350 updateCpuStatsNow(); 2351 } 2352 2353 @Override 2354 public void batteryPowerChanged(boolean onBattery) { 2355 // When plugging in, update the CPU stats first before changing 2356 // the plug state. 2357 updateCpuStatsNow(); 2358 synchronized (this) { 2359 synchronized(mPidsSelfLocked) { 2360 mOnBattery = DEBUG_POWER ? true : onBattery; 2361 } 2362 } 2363 } 2364 2365 /** 2366 * Initialize the application bind args. These are passed to each 2367 * process when the bindApplication() IPC is sent to the process. They're 2368 * lazily setup to make sure the services are running when they're asked for. 2369 */ 2370 private HashMap<String, IBinder> getCommonServicesLocked() { 2371 if (mAppBindArgs == null) { 2372 mAppBindArgs = new HashMap<String, IBinder>(); 2373 2374 // Setup the application init args 2375 mAppBindArgs.put("package", ServiceManager.getService("package")); 2376 mAppBindArgs.put("window", ServiceManager.getService("window")); 2377 mAppBindArgs.put(Context.ALARM_SERVICE, 2378 ServiceManager.getService(Context.ALARM_SERVICE)); 2379 } 2380 return mAppBindArgs; 2381 } 2382 2383 final void setFocusedActivityLocked(ActivityRecord r) { 2384 if (mFocusedActivity != r) { 2385 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2386 mFocusedActivity = r; 2387 if (r.task != null && r.task.voiceInteractor != null) { 2388 startRunningVoiceLocked(); 2389 } else { 2390 finishRunningVoiceLocked(); 2391 } 2392 mStackSupervisor.setFocusedStack(r); 2393 if (r != null) { 2394 mWindowManager.setFocusedApp(r.appToken, true); 2395 } 2396 applyUpdateLockStateLocked(r); 2397 } 2398 } 2399 2400 final void clearFocusedActivity(ActivityRecord r) { 2401 if (mFocusedActivity == r) { 2402 mFocusedActivity = null; 2403 } 2404 } 2405 2406 @Override 2407 public void setFocusedStack(int stackId) { 2408 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2409 synchronized (ActivityManagerService.this) { 2410 ActivityStack stack = mStackSupervisor.getStack(stackId); 2411 if (stack != null) { 2412 ActivityRecord r = stack.topRunningActivityLocked(null); 2413 if (r != null) { 2414 setFocusedActivityLocked(r); 2415 } 2416 } 2417 } 2418 } 2419 2420 @Override 2421 public void notifyActivityDrawn(IBinder token) { 2422 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2423 synchronized (this) { 2424 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2425 if (r != null) { 2426 r.task.stack.notifyActivityDrawnLocked(r); 2427 } 2428 } 2429 } 2430 2431 final void applyUpdateLockStateLocked(ActivityRecord r) { 2432 // Modifications to the UpdateLock state are done on our handler, outside 2433 // the activity manager's locks. The new state is determined based on the 2434 // state *now* of the relevant activity record. The object is passed to 2435 // the handler solely for logging detail, not to be consulted/modified. 2436 final boolean nextState = r != null && r.immersive; 2437 mHandler.sendMessage( 2438 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2439 } 2440 2441 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2442 Message msg = Message.obtain(); 2443 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2444 msg.obj = r.task.askedCompatMode ? null : r; 2445 mHandler.sendMessage(msg); 2446 } 2447 2448 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2449 String what, Object obj, ProcessRecord srcApp) { 2450 app.lastActivityTime = now; 2451 2452 if (app.activities.size() > 0) { 2453 // Don't want to touch dependent processes that are hosting activities. 2454 return index; 2455 } 2456 2457 int lrui = mLruProcesses.lastIndexOf(app); 2458 if (lrui < 0) { 2459 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2460 + what + " " + obj + " from " + srcApp); 2461 return index; 2462 } 2463 2464 if (lrui >= index) { 2465 // Don't want to cause this to move dependent processes *back* in the 2466 // list as if they were less frequently used. 2467 return index; 2468 } 2469 2470 if (lrui >= mLruProcessActivityStart) { 2471 // Don't want to touch dependent processes that are hosting activities. 2472 return index; 2473 } 2474 2475 mLruProcesses.remove(lrui); 2476 if (index > 0) { 2477 index--; 2478 } 2479 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2480 + " in LRU list: " + app); 2481 mLruProcesses.add(index, app); 2482 return index; 2483 } 2484 2485 final void removeLruProcessLocked(ProcessRecord app) { 2486 int lrui = mLruProcesses.lastIndexOf(app); 2487 if (lrui >= 0) { 2488 if (lrui <= mLruProcessActivityStart) { 2489 mLruProcessActivityStart--; 2490 } 2491 if (lrui <= mLruProcessServiceStart) { 2492 mLruProcessServiceStart--; 2493 } 2494 mLruProcesses.remove(lrui); 2495 } 2496 } 2497 2498 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2499 ProcessRecord client) { 2500 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2501 || app.treatLikeActivity; 2502 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2503 if (!activityChange && hasActivity) { 2504 // The process has activities, so we are only allowing activity-based adjustments 2505 // to move it. It should be kept in the front of the list with other 2506 // processes that have activities, and we don't want those to change their 2507 // order except due to activity operations. 2508 return; 2509 } 2510 2511 mLruSeq++; 2512 final long now = SystemClock.uptimeMillis(); 2513 app.lastActivityTime = now; 2514 2515 // First a quick reject: if the app is already at the position we will 2516 // put it, then there is nothing to do. 2517 if (hasActivity) { 2518 final int N = mLruProcesses.size(); 2519 if (N > 0 && mLruProcesses.get(N-1) == app) { 2520 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2521 return; 2522 } 2523 } else { 2524 if (mLruProcessServiceStart > 0 2525 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2526 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2527 return; 2528 } 2529 } 2530 2531 int lrui = mLruProcesses.lastIndexOf(app); 2532 2533 if (app.persistent && lrui >= 0) { 2534 // We don't care about the position of persistent processes, as long as 2535 // they are in the list. 2536 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2537 return; 2538 } 2539 2540 /* In progress: compute new position first, so we can avoid doing work 2541 if the process is not actually going to move. Not yet working. 2542 int addIndex; 2543 int nextIndex; 2544 boolean inActivity = false, inService = false; 2545 if (hasActivity) { 2546 // Process has activities, put it at the very tipsy-top. 2547 addIndex = mLruProcesses.size(); 2548 nextIndex = mLruProcessServiceStart; 2549 inActivity = true; 2550 } else if (hasService) { 2551 // Process has services, put it at the top of the service list. 2552 addIndex = mLruProcessActivityStart; 2553 nextIndex = mLruProcessServiceStart; 2554 inActivity = true; 2555 inService = true; 2556 } else { 2557 // Process not otherwise of interest, it goes to the top of the non-service area. 2558 addIndex = mLruProcessServiceStart; 2559 if (client != null) { 2560 int clientIndex = mLruProcesses.lastIndexOf(client); 2561 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2562 + app); 2563 if (clientIndex >= 0 && addIndex > clientIndex) { 2564 addIndex = clientIndex; 2565 } 2566 } 2567 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2568 } 2569 2570 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2571 + mLruProcessActivityStart + "): " + app); 2572 */ 2573 2574 if (lrui >= 0) { 2575 if (lrui < mLruProcessActivityStart) { 2576 mLruProcessActivityStart--; 2577 } 2578 if (lrui < mLruProcessServiceStart) { 2579 mLruProcessServiceStart--; 2580 } 2581 /* 2582 if (addIndex > lrui) { 2583 addIndex--; 2584 } 2585 if (nextIndex > lrui) { 2586 nextIndex--; 2587 } 2588 */ 2589 mLruProcesses.remove(lrui); 2590 } 2591 2592 /* 2593 mLruProcesses.add(addIndex, app); 2594 if (inActivity) { 2595 mLruProcessActivityStart++; 2596 } 2597 if (inService) { 2598 mLruProcessActivityStart++; 2599 } 2600 */ 2601 2602 int nextIndex; 2603 if (hasActivity) { 2604 final int N = mLruProcesses.size(); 2605 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2606 // Process doesn't have activities, but has clients with 2607 // activities... move it up, but one below the top (the top 2608 // should always have a real activity). 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2610 mLruProcesses.add(N-1, app); 2611 // To keep it from spamming the LRU list (by making a bunch of clients), 2612 // we will push down any other entries owned by the app. 2613 final int uid = app.info.uid; 2614 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2615 ProcessRecord subProc = mLruProcesses.get(i); 2616 if (subProc.info.uid == uid) { 2617 // We want to push this one down the list. If the process after 2618 // it is for the same uid, however, don't do so, because we don't 2619 // want them internally to be re-ordered. 2620 if (mLruProcesses.get(i-1).info.uid != uid) { 2621 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2622 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2623 ProcessRecord tmp = mLruProcesses.get(i); 2624 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2625 mLruProcesses.set(i-1, tmp); 2626 i--; 2627 } 2628 } else { 2629 // A gap, we can stop here. 2630 break; 2631 } 2632 } 2633 } else { 2634 // Process has activities, put it at the very tipsy-top. 2635 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2636 mLruProcesses.add(app); 2637 } 2638 nextIndex = mLruProcessServiceStart; 2639 } else if (hasService) { 2640 // Process has services, put it at the top of the service list. 2641 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2642 mLruProcesses.add(mLruProcessActivityStart, app); 2643 nextIndex = mLruProcessServiceStart; 2644 mLruProcessActivityStart++; 2645 } else { 2646 // Process not otherwise of interest, it goes to the top of the non-service area. 2647 int index = mLruProcessServiceStart; 2648 if (client != null) { 2649 // If there is a client, don't allow the process to be moved up higher 2650 // in the list than that client. 2651 int clientIndex = mLruProcesses.lastIndexOf(client); 2652 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2653 + " when updating " + app); 2654 if (clientIndex <= lrui) { 2655 // Don't allow the client index restriction to push it down farther in the 2656 // list than it already is. 2657 clientIndex = lrui; 2658 } 2659 if (clientIndex >= 0 && index > clientIndex) { 2660 index = clientIndex; 2661 } 2662 } 2663 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2664 mLruProcesses.add(index, app); 2665 nextIndex = index-1; 2666 mLruProcessActivityStart++; 2667 mLruProcessServiceStart++; 2668 } 2669 2670 // If the app is currently using a content provider or service, 2671 // bump those processes as well. 2672 for (int j=app.connections.size()-1; j>=0; j--) { 2673 ConnectionRecord cr = app.connections.valueAt(j); 2674 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2675 && cr.binding.service.app != null 2676 && cr.binding.service.app.lruSeq != mLruSeq 2677 && !cr.binding.service.app.persistent) { 2678 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2679 "service connection", cr, app); 2680 } 2681 } 2682 for (int j=app.conProviders.size()-1; j>=0; j--) { 2683 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2684 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2685 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2686 "provider reference", cpr, app); 2687 } 2688 } 2689 } 2690 2691 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2692 if (uid == Process.SYSTEM_UID) { 2693 // The system gets to run in any process. If there are multiple 2694 // processes with the same uid, just pick the first (this 2695 // should never happen). 2696 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2697 if (procs == null) return null; 2698 final int N = procs.size(); 2699 for (int i = 0; i < N; i++) { 2700 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2701 } 2702 } 2703 ProcessRecord proc = mProcessNames.get(processName, uid); 2704 if (false && proc != null && !keepIfLarge 2705 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2706 && proc.lastCachedPss >= 4000) { 2707 // Turn this condition on to cause killing to happen regularly, for testing. 2708 if (proc.baseProcessTracker != null) { 2709 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2710 } 2711 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2712 + "k from cached"); 2713 } else if (proc != null && !keepIfLarge 2714 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2715 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2716 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2717 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2718 if (proc.baseProcessTracker != null) { 2719 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2720 } 2721 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2722 + "k from cached"); 2723 } 2724 } 2725 return proc; 2726 } 2727 2728 void ensurePackageDexOpt(String packageName) { 2729 IPackageManager pm = AppGlobals.getPackageManager(); 2730 try { 2731 if (pm.performDexOpt(packageName)) { 2732 mDidDexOpt = true; 2733 } 2734 } catch (RemoteException e) { 2735 } 2736 } 2737 2738 boolean isNextTransitionForward() { 2739 int transit = mWindowManager.getPendingAppTransition(); 2740 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2741 || transit == AppTransition.TRANSIT_TASK_OPEN 2742 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2743 } 2744 2745 final ProcessRecord startProcessLocked(String processName, 2746 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2747 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2748 boolean isolated, boolean keepIfLarge) { 2749 ProcessRecord app; 2750 if (!isolated) { 2751 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2752 } else { 2753 // If this is an isolated process, it can't re-use an existing process. 2754 app = null; 2755 } 2756 // We don't have to do anything more if: 2757 // (1) There is an existing application record; and 2758 // (2) The caller doesn't think it is dead, OR there is no thread 2759 // object attached to it so we know it couldn't have crashed; and 2760 // (3) There is a pid assigned to it, so it is either starting or 2761 // already running. 2762 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2763 + " app=" + app + " knownToBeDead=" + knownToBeDead 2764 + " thread=" + (app != null ? app.thread : null) 2765 + " pid=" + (app != null ? app.pid : -1)); 2766 if (app != null && app.pid > 0) { 2767 if (!knownToBeDead || app.thread == null) { 2768 // We already have the app running, or are waiting for it to 2769 // come up (we have a pid but not yet its thread), so keep it. 2770 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2771 // If this is a new package in the process, add the package to the list 2772 app.addPackage(info.packageName, mProcessStats); 2773 return app; 2774 } 2775 2776 // An application record is attached to a previous process, 2777 // clean it up now. 2778 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2779 handleAppDiedLocked(app, true, true); 2780 } 2781 2782 String hostingNameStr = hostingName != null 2783 ? hostingName.flattenToShortString() : null; 2784 2785 if (!isolated) { 2786 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2787 // If we are in the background, then check to see if this process 2788 // is bad. If so, we will just silently fail. 2789 if (mBadProcesses.get(info.processName, info.uid) != null) { 2790 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2791 + "/" + info.processName); 2792 return null; 2793 } 2794 } else { 2795 // When the user is explicitly starting a process, then clear its 2796 // crash count so that we won't make it bad until they see at 2797 // least one crash dialog again, and make the process good again 2798 // if it had been bad. 2799 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2800 + "/" + info.processName); 2801 mProcessCrashTimes.remove(info.processName, info.uid); 2802 if (mBadProcesses.get(info.processName, info.uid) != null) { 2803 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2804 UserHandle.getUserId(info.uid), info.uid, 2805 info.processName); 2806 mBadProcesses.remove(info.processName, info.uid); 2807 if (app != null) { 2808 app.bad = false; 2809 } 2810 } 2811 } 2812 } 2813 2814 if (app == null) { 2815 app = newProcessRecordLocked(info, processName, isolated); 2816 if (app == null) { 2817 Slog.w(TAG, "Failed making new process record for " 2818 + processName + "/" + info.uid + " isolated=" + isolated); 2819 return null; 2820 } 2821 mProcessNames.put(processName, app.uid, app); 2822 if (isolated) { 2823 mIsolatedProcesses.put(app.uid, app); 2824 } 2825 } else { 2826 // If this is a new package in the process, add the package to the list 2827 app.addPackage(info.packageName, mProcessStats); 2828 } 2829 2830 // If the system is not ready yet, then hold off on starting this 2831 // process until it is. 2832 if (!mProcessesReady 2833 && !isAllowedWhileBooting(info) 2834 && !allowWhileBooting) { 2835 if (!mProcessesOnHold.contains(app)) { 2836 mProcessesOnHold.add(app); 2837 } 2838 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2839 return app; 2840 } 2841 2842 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2843 return (app.pid != 0) ? app : null; 2844 } 2845 2846 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2847 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2848 } 2849 2850 private final void startProcessLocked(ProcessRecord app, 2851 String hostingType, String hostingNameStr, String abiOverride) { 2852 if (app.pid > 0 && app.pid != MY_PID) { 2853 synchronized (mPidsSelfLocked) { 2854 mPidsSelfLocked.remove(app.pid); 2855 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2856 } 2857 app.setPid(0); 2858 } 2859 2860 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2861 "startProcessLocked removing on hold: " + app); 2862 mProcessesOnHold.remove(app); 2863 2864 updateCpuStats(); 2865 2866 try { 2867 int uid = app.uid; 2868 2869 int[] gids = null; 2870 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2871 if (!app.isolated) { 2872 int[] permGids = null; 2873 try { 2874 final PackageManager pm = mContext.getPackageManager(); 2875 permGids = pm.getPackageGids(app.info.packageName); 2876 2877 if (Environment.isExternalStorageEmulated()) { 2878 if (pm.checkPermission( 2879 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2880 app.info.packageName) == PERMISSION_GRANTED) { 2881 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2882 } else { 2883 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2884 } 2885 } 2886 } catch (PackageManager.NameNotFoundException e) { 2887 Slog.w(TAG, "Unable to retrieve gids", e); 2888 } 2889 2890 /* 2891 * Add shared application and profile GIDs so applications can share some 2892 * resources like shared libraries and access user-wide resources 2893 */ 2894 if (permGids == null) { 2895 gids = new int[2]; 2896 } else { 2897 gids = new int[permGids.length + 2]; 2898 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2899 } 2900 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2901 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2902 } 2903 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2904 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2905 && mTopComponent != null 2906 && app.processName.equals(mTopComponent.getPackageName())) { 2907 uid = 0; 2908 } 2909 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2910 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2911 uid = 0; 2912 } 2913 } 2914 int debugFlags = 0; 2915 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2916 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2917 // Also turn on CheckJNI for debuggable apps. It's quite 2918 // awkward to turn on otherwise. 2919 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2920 } 2921 // Run the app in safe mode if its manifest requests so or the 2922 // system is booted in safe mode. 2923 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2924 mSafeMode == true) { 2925 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2926 } 2927 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2928 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2929 } 2930 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2931 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2932 } 2933 if ("1".equals(SystemProperties.get("debug.assert"))) { 2934 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2935 } 2936 2937 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2938 if (requiredAbi == null) { 2939 requiredAbi = Build.SUPPORTED_ABIS[0]; 2940 } 2941 2942 // Start the process. It will either succeed and return a result containing 2943 // the PID of the new process, or else throw a RuntimeException. 2944 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2945 app.processName, uid, uid, gids, debugFlags, mountExternal, 2946 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2947 2948 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2949 synchronized (bs) { 2950 if (bs.isOnBattery()) { 2951 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2952 } 2953 } 2954 2955 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2956 UserHandle.getUserId(uid), startResult.pid, uid, 2957 app.processName, hostingType, 2958 hostingNameStr != null ? hostingNameStr : ""); 2959 2960 if (app.persistent) { 2961 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2962 } 2963 2964 StringBuilder buf = mStringBuilder; 2965 buf.setLength(0); 2966 buf.append("Start proc "); 2967 buf.append(app.processName); 2968 buf.append(" for "); 2969 buf.append(hostingType); 2970 if (hostingNameStr != null) { 2971 buf.append(" "); 2972 buf.append(hostingNameStr); 2973 } 2974 buf.append(": pid="); 2975 buf.append(startResult.pid); 2976 buf.append(" uid="); 2977 buf.append(uid); 2978 buf.append(" gids={"); 2979 if (gids != null) { 2980 for (int gi=0; gi<gids.length; gi++) { 2981 if (gi != 0) buf.append(", "); 2982 buf.append(gids[gi]); 2983 2984 } 2985 } 2986 buf.append("}"); 2987 if (requiredAbi != null) { 2988 buf.append(" abi="); 2989 buf.append(requiredAbi); 2990 } 2991 Slog.i(TAG, buf.toString()); 2992 app.setPid(startResult.pid); 2993 app.usingWrapper = startResult.usingWrapper; 2994 app.removed = false; 2995 synchronized (mPidsSelfLocked) { 2996 this.mPidsSelfLocked.put(startResult.pid, app); 2997 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2998 msg.obj = app; 2999 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3000 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3001 } 3002 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3003 app.processName, app.info.uid); 3004 if (app.isolated) { 3005 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3006 } 3007 } catch (RuntimeException e) { 3008 // XXX do better error recovery. 3009 app.setPid(0); 3010 Slog.e(TAG, "Failure starting process " + app.processName, e); 3011 } 3012 } 3013 3014 void updateUsageStats(ActivityRecord component, boolean resumed) { 3015 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3016 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3017 if (resumed) { 3018 mUsageStatsService.noteResumeComponent(component.realActivity); 3019 synchronized (stats) { 3020 stats.noteActivityResumedLocked(component.app.uid); 3021 } 3022 } else { 3023 mUsageStatsService.notePauseComponent(component.realActivity); 3024 synchronized (stats) { 3025 stats.noteActivityPausedLocked(component.app.uid); 3026 } 3027 } 3028 } 3029 3030 Intent getHomeIntent() { 3031 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3032 intent.setComponent(mTopComponent); 3033 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3034 intent.addCategory(Intent.CATEGORY_HOME); 3035 } 3036 return intent; 3037 } 3038 3039 boolean startHomeActivityLocked(int userId) { 3040 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3041 && mTopAction == null) { 3042 // We are running in factory test mode, but unable to find 3043 // the factory test app, so just sit around displaying the 3044 // error message and don't try to start anything. 3045 return false; 3046 } 3047 Intent intent = getHomeIntent(); 3048 ActivityInfo aInfo = 3049 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3050 if (aInfo != null) { 3051 intent.setComponent(new ComponentName( 3052 aInfo.applicationInfo.packageName, aInfo.name)); 3053 // Don't do this if the home app is currently being 3054 // instrumented. 3055 aInfo = new ActivityInfo(aInfo); 3056 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3057 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3058 aInfo.applicationInfo.uid, true); 3059 if (app == null || app.instrumentationClass == null) { 3060 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3061 mStackSupervisor.startHomeActivity(intent, aInfo); 3062 } 3063 } 3064 3065 return true; 3066 } 3067 3068 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3069 ActivityInfo ai = null; 3070 ComponentName comp = intent.getComponent(); 3071 try { 3072 if (comp != null) { 3073 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3074 } else { 3075 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3076 intent, 3077 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3078 flags, userId); 3079 3080 if (info != null) { 3081 ai = info.activityInfo; 3082 } 3083 } 3084 } catch (RemoteException e) { 3085 // ignore 3086 } 3087 3088 return ai; 3089 } 3090 3091 /** 3092 * Starts the "new version setup screen" if appropriate. 3093 */ 3094 void startSetupActivityLocked() { 3095 // Only do this once per boot. 3096 if (mCheckedForSetup) { 3097 return; 3098 } 3099 3100 // We will show this screen if the current one is a different 3101 // version than the last one shown, and we are not running in 3102 // low-level factory test mode. 3103 final ContentResolver resolver = mContext.getContentResolver(); 3104 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3105 Settings.Global.getInt(resolver, 3106 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3107 mCheckedForSetup = true; 3108 3109 // See if we should be showing the platform update setup UI. 3110 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3111 List<ResolveInfo> ris = mContext.getPackageManager() 3112 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3113 3114 // We don't allow third party apps to replace this. 3115 ResolveInfo ri = null; 3116 for (int i=0; ris != null && i<ris.size(); i++) { 3117 if ((ris.get(i).activityInfo.applicationInfo.flags 3118 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3119 ri = ris.get(i); 3120 break; 3121 } 3122 } 3123 3124 if (ri != null) { 3125 String vers = ri.activityInfo.metaData != null 3126 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3127 : null; 3128 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3129 vers = ri.activityInfo.applicationInfo.metaData.getString( 3130 Intent.METADATA_SETUP_VERSION); 3131 } 3132 String lastVers = Settings.Secure.getString( 3133 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3134 if (vers != null && !vers.equals(lastVers)) { 3135 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3136 intent.setComponent(new ComponentName( 3137 ri.activityInfo.packageName, ri.activityInfo.name)); 3138 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3139 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3140 } 3141 } 3142 } 3143 } 3144 3145 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3146 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3147 } 3148 3149 void enforceNotIsolatedCaller(String caller) { 3150 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3151 throw new SecurityException("Isolated process not allowed to call " + caller); 3152 } 3153 } 3154 3155 @Override 3156 public int getFrontActivityScreenCompatMode() { 3157 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3158 synchronized (this) { 3159 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3160 } 3161 } 3162 3163 @Override 3164 public void setFrontActivityScreenCompatMode(int mode) { 3165 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3166 "setFrontActivityScreenCompatMode"); 3167 synchronized (this) { 3168 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3169 } 3170 } 3171 3172 @Override 3173 public int getPackageScreenCompatMode(String packageName) { 3174 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3175 synchronized (this) { 3176 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3177 } 3178 } 3179 3180 @Override 3181 public void setPackageScreenCompatMode(String packageName, int mode) { 3182 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3183 "setPackageScreenCompatMode"); 3184 synchronized (this) { 3185 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3186 } 3187 } 3188 3189 @Override 3190 public boolean getPackageAskScreenCompat(String packageName) { 3191 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3192 synchronized (this) { 3193 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3194 } 3195 } 3196 3197 @Override 3198 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3199 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3200 "setPackageAskScreenCompat"); 3201 synchronized (this) { 3202 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3203 } 3204 } 3205 3206 private void dispatchProcessesChanged() { 3207 int N; 3208 synchronized (this) { 3209 N = mPendingProcessChanges.size(); 3210 if (mActiveProcessChanges.length < N) { 3211 mActiveProcessChanges = new ProcessChangeItem[N]; 3212 } 3213 mPendingProcessChanges.toArray(mActiveProcessChanges); 3214 mAvailProcessChanges.addAll(mPendingProcessChanges); 3215 mPendingProcessChanges.clear(); 3216 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3217 } 3218 3219 int i = mProcessObservers.beginBroadcast(); 3220 while (i > 0) { 3221 i--; 3222 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3223 if (observer != null) { 3224 try { 3225 for (int j=0; j<N; j++) { 3226 ProcessChangeItem item = mActiveProcessChanges[j]; 3227 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3228 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3229 + item.pid + " uid=" + item.uid + ": " 3230 + item.foregroundActivities); 3231 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3232 item.foregroundActivities); 3233 } 3234 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3235 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3236 + item.pid + " uid=" + item.uid + ": " + item.processState); 3237 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3238 } 3239 } 3240 } catch (RemoteException e) { 3241 } 3242 } 3243 } 3244 mProcessObservers.finishBroadcast(); 3245 } 3246 3247 private void dispatchProcessDied(int pid, int uid) { 3248 int i = mProcessObservers.beginBroadcast(); 3249 while (i > 0) { 3250 i--; 3251 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3252 if (observer != null) { 3253 try { 3254 observer.onProcessDied(pid, uid); 3255 } catch (RemoteException e) { 3256 } 3257 } 3258 } 3259 mProcessObservers.finishBroadcast(); 3260 } 3261 3262 final void doPendingActivityLaunchesLocked(boolean doResume) { 3263 final int N = mPendingActivityLaunches.size(); 3264 if (N <= 0) { 3265 return; 3266 } 3267 for (int i=0; i<N; i++) { 3268 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3269 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3270 doResume && i == (N-1), null); 3271 } 3272 mPendingActivityLaunches.clear(); 3273 } 3274 3275 @Override 3276 public final int startActivity(IApplicationThread caller, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, 3279 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3280 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3281 resultWho, requestCode, 3282 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3283 } 3284 3285 @Override 3286 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3287 Intent intent, String resolvedType, IBinder resultTo, 3288 String resultWho, int requestCode, int startFlags, 3289 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3290 enforceNotIsolatedCaller("startActivity"); 3291 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3292 false, true, "startActivity", null); 3293 // TODO: Switch to user app stacks here. 3294 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3295 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3296 null, null, options, userId, null); 3297 } 3298 3299 @Override 3300 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3301 Intent intent, String resolvedType, IBinder resultTo, 3302 String resultWho, int requestCode, int startFlags, String profileFile, 3303 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3304 enforceNotIsolatedCaller("startActivityAndWait"); 3305 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3306 false, true, "startActivityAndWait", null); 3307 WaitResult res = new WaitResult(); 3308 // TODO: Switch to user app stacks here. 3309 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3310 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3311 res, null, options, UserHandle.getCallingUserId(), null); 3312 return res; 3313 } 3314 3315 @Override 3316 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3317 Intent intent, String resolvedType, IBinder resultTo, 3318 String resultWho, int requestCode, int startFlags, Configuration config, 3319 Bundle options, int userId) { 3320 enforceNotIsolatedCaller("startActivityWithConfig"); 3321 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3322 false, true, "startActivityWithConfig", null); 3323 // TODO: Switch to user app stacks here. 3324 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3325 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3326 null, null, null, config, options, userId, null); 3327 return ret; 3328 } 3329 3330 @Override 3331 public int startActivityIntentSender(IApplicationThread caller, 3332 IntentSender intent, Intent fillInIntent, String resolvedType, 3333 IBinder resultTo, String resultWho, int requestCode, 3334 int flagsMask, int flagsValues, Bundle options) { 3335 enforceNotIsolatedCaller("startActivityIntentSender"); 3336 // Refuse possible leaked file descriptors 3337 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3338 throw new IllegalArgumentException("File descriptors passed in Intent"); 3339 } 3340 3341 IIntentSender sender = intent.getTarget(); 3342 if (!(sender instanceof PendingIntentRecord)) { 3343 throw new IllegalArgumentException("Bad PendingIntent object"); 3344 } 3345 3346 PendingIntentRecord pir = (PendingIntentRecord)sender; 3347 3348 synchronized (this) { 3349 // If this is coming from the currently resumed activity, it is 3350 // effectively saying that app switches are allowed at this point. 3351 final ActivityStack stack = getFocusedStack(); 3352 if (stack.mResumedActivity != null && 3353 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3354 mAppSwitchesAllowedTime = 0; 3355 } 3356 } 3357 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3358 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3359 return ret; 3360 } 3361 3362 @Override 3363 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3364 Intent intent, String resolvedType, IVoiceInteractionSession session, 3365 IVoiceInteractor interactor, int startFlags, String profileFile, 3366 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3367 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3368 != PackageManager.PERMISSION_GRANTED) { 3369 String msg = "Permission Denial: startVoiceActivity() from pid=" 3370 + Binder.getCallingPid() 3371 + ", uid=" + Binder.getCallingUid() 3372 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3373 Slog.w(TAG, msg); 3374 throw new SecurityException(msg); 3375 } 3376 if (session == null || interactor == null) { 3377 throw new NullPointerException("null session or interactor"); 3378 } 3379 userId = handleIncomingUser(callingPid, callingUid, userId, 3380 false, true, "startVoiceActivity", null); 3381 // TODO: Switch to user app stacks here. 3382 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3383 resolvedType, session, interactor, null, null, 0, startFlags, 3384 profileFile, profileFd, null, null, options, userId, null); 3385 } 3386 3387 @Override 3388 public boolean startNextMatchingActivity(IBinder callingActivity, 3389 Intent intent, Bundle options) { 3390 // Refuse possible leaked file descriptors 3391 if (intent != null && intent.hasFileDescriptors() == true) { 3392 throw new IllegalArgumentException("File descriptors passed in Intent"); 3393 } 3394 3395 synchronized (this) { 3396 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3397 if (r == null) { 3398 ActivityOptions.abort(options); 3399 return false; 3400 } 3401 if (r.app == null || r.app.thread == null) { 3402 // The caller is not running... d'oh! 3403 ActivityOptions.abort(options); 3404 return false; 3405 } 3406 intent = new Intent(intent); 3407 // The caller is not allowed to change the data. 3408 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3409 // And we are resetting to find the next component... 3410 intent.setComponent(null); 3411 3412 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3413 3414 ActivityInfo aInfo = null; 3415 try { 3416 List<ResolveInfo> resolves = 3417 AppGlobals.getPackageManager().queryIntentActivities( 3418 intent, r.resolvedType, 3419 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3420 UserHandle.getCallingUserId()); 3421 3422 // Look for the original activity in the list... 3423 final int N = resolves != null ? resolves.size() : 0; 3424 for (int i=0; i<N; i++) { 3425 ResolveInfo rInfo = resolves.get(i); 3426 if (rInfo.activityInfo.packageName.equals(r.packageName) 3427 && rInfo.activityInfo.name.equals(r.info.name)) { 3428 // We found the current one... the next matching is 3429 // after it. 3430 i++; 3431 if (i<N) { 3432 aInfo = resolves.get(i).activityInfo; 3433 } 3434 if (debug) { 3435 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3436 + "/" + r.info.name); 3437 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3438 + "/" + aInfo.name); 3439 } 3440 break; 3441 } 3442 } 3443 } catch (RemoteException e) { 3444 } 3445 3446 if (aInfo == null) { 3447 // Nobody who is next! 3448 ActivityOptions.abort(options); 3449 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3450 return false; 3451 } 3452 3453 intent.setComponent(new ComponentName( 3454 aInfo.applicationInfo.packageName, aInfo.name)); 3455 intent.setFlags(intent.getFlags()&~( 3456 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3457 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3458 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3459 Intent.FLAG_ACTIVITY_NEW_TASK)); 3460 3461 // Okay now we need to start the new activity, replacing the 3462 // currently running activity. This is a little tricky because 3463 // we want to start the new one as if the current one is finished, 3464 // but not finish the current one first so that there is no flicker. 3465 // And thus... 3466 final boolean wasFinishing = r.finishing; 3467 r.finishing = true; 3468 3469 // Propagate reply information over to the new activity. 3470 final ActivityRecord resultTo = r.resultTo; 3471 final String resultWho = r.resultWho; 3472 final int requestCode = r.requestCode; 3473 r.resultTo = null; 3474 if (resultTo != null) { 3475 resultTo.removeResultsLocked(r, resultWho, requestCode); 3476 } 3477 3478 final long origId = Binder.clearCallingIdentity(); 3479 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3480 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3481 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3482 options, false, null, null); 3483 Binder.restoreCallingIdentity(origId); 3484 3485 r.finishing = wasFinishing; 3486 if (res != ActivityManager.START_SUCCESS) { 3487 return false; 3488 } 3489 return true; 3490 } 3491 } 3492 3493 final int startActivityInPackage(int uid, String callingPackage, 3494 Intent intent, String resolvedType, IBinder resultTo, 3495 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3496 IActivityContainer container) { 3497 3498 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3499 false, true, "startActivityInPackage", null); 3500 3501 // TODO: Switch to user app stacks here. 3502 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3503 null, null, resultTo, resultWho, requestCode, startFlags, 3504 null, null, null, null, options, userId, container); 3505 return ret; 3506 } 3507 3508 @Override 3509 public final int startActivities(IApplicationThread caller, String callingPackage, 3510 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3511 int userId) { 3512 enforceNotIsolatedCaller("startActivities"); 3513 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3514 false, true, "startActivity", null); 3515 // TODO: Switch to user app stacks here. 3516 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3517 resolvedTypes, resultTo, options, userId); 3518 return ret; 3519 } 3520 3521 final int startActivitiesInPackage(int uid, String callingPackage, 3522 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3523 Bundle options, int userId) { 3524 3525 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3526 false, true, "startActivityInPackage", null); 3527 // TODO: Switch to user app stacks here. 3528 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3529 resultTo, options, userId); 3530 return ret; 3531 } 3532 3533 final void addRecentTaskLocked(TaskRecord task) { 3534 int N = mRecentTasks.size(); 3535 // Quick case: check if the top-most recent task is the same. 3536 if (N > 0 && mRecentTasks.get(0) == task) { 3537 return; 3538 } 3539 // Another quick case: never add voice sessions. 3540 if (task.voiceSession != null) { 3541 return; 3542 } 3543 // Remove any existing entries that are the same kind of task. 3544 final Intent intent = task.intent; 3545 final boolean document = intent != null && intent.isDocument(); 3546 final ComponentName comp = intent.getComponent(); 3547 3548 int maxRecents = task.maxRecents - 1; 3549 for (int i=0; i<N; i++) { 3550 TaskRecord tr = mRecentTasks.get(i); 3551 if (task != tr) { 3552 if (task.userId != tr.userId) { 3553 continue; 3554 } 3555 final Intent trIntent = tr.intent; 3556 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3557 (intent == null || !intent.filterEquals(trIntent))) { 3558 continue; 3559 } 3560 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3561 if (document && trIsDocument) { 3562 // These are the same document activity (not necessarily the same doc). 3563 if (maxRecents > 0) { 3564 --maxRecents; 3565 continue; 3566 } 3567 // Hit the maximum number of documents for this task. Fall through 3568 // and remove this document from recents. 3569 } else if (document || trIsDocument) { 3570 // Only one of these is a document. Not the droid we're looking for. 3571 continue; 3572 } 3573 } 3574 3575 // Either task and tr are the same or, their affinities match or their intents match 3576 // and neither of them is a document, or they are documents using the same activity 3577 // and their maxRecents has been reached. 3578 tr.disposeThumbnail(); 3579 mRecentTasks.remove(i); 3580 i--; 3581 N--; 3582 if (task.intent == null) { 3583 // If the new recent task we are adding is not fully 3584 // specified, then replace it with the existing recent task. 3585 task = tr; 3586 } 3587 mTaskPersister.notify(tr, false); 3588 } 3589 if (N >= MAX_RECENT_TASKS) { 3590 mRecentTasks.remove(N-1).disposeThumbnail(); 3591 } 3592 mRecentTasks.add(0, task); 3593 } 3594 3595 @Override 3596 public void reportActivityFullyDrawn(IBinder token) { 3597 synchronized (this) { 3598 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3599 if (r == null) { 3600 return; 3601 } 3602 r.reportFullyDrawnLocked(); 3603 } 3604 } 3605 3606 @Override 3607 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3608 synchronized (this) { 3609 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3610 if (r == null) { 3611 return; 3612 } 3613 final long origId = Binder.clearCallingIdentity(); 3614 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3615 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3616 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3617 if (config != null) { 3618 r.frozenBeforeDestroy = true; 3619 if (!updateConfigurationLocked(config, r, false, false)) { 3620 mStackSupervisor.resumeTopActivitiesLocked(); 3621 } 3622 } 3623 Binder.restoreCallingIdentity(origId); 3624 } 3625 } 3626 3627 @Override 3628 public int getRequestedOrientation(IBinder token) { 3629 synchronized (this) { 3630 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3631 if (r == null) { 3632 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3633 } 3634 return mWindowManager.getAppOrientation(r.appToken); 3635 } 3636 } 3637 3638 /** 3639 * This is the internal entry point for handling Activity.finish(). 3640 * 3641 * @param token The Binder token referencing the Activity we want to finish. 3642 * @param resultCode Result code, if any, from this Activity. 3643 * @param resultData Result data (Intent), if any, from this Activity. 3644 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3645 * the root Activity in the task. 3646 * 3647 * @return Returns true if the activity successfully finished, or false if it is still running. 3648 */ 3649 @Override 3650 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3651 boolean finishTask) { 3652 // Refuse possible leaked file descriptors 3653 if (resultData != null && resultData.hasFileDescriptors() == true) { 3654 throw new IllegalArgumentException("File descriptors passed in Intent"); 3655 } 3656 3657 synchronized(this) { 3658 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3659 if (r == null) { 3660 return true; 3661 } 3662 // Keep track of the root activity of the task before we finish it 3663 TaskRecord tr = r.task; 3664 ActivityRecord rootR = tr.getRootActivity(); 3665 if (mController != null) { 3666 // Find the first activity that is not finishing. 3667 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3668 if (next != null) { 3669 // ask watcher if this is allowed 3670 boolean resumeOK = true; 3671 try { 3672 resumeOK = mController.activityResuming(next.packageName); 3673 } catch (RemoteException e) { 3674 mController = null; 3675 Watchdog.getInstance().setActivityController(null); 3676 } 3677 3678 if (!resumeOK) { 3679 return false; 3680 } 3681 } 3682 } 3683 final long origId = Binder.clearCallingIdentity(); 3684 try { 3685 boolean res; 3686 if (finishTask && r == rootR) { 3687 // If requested, remove the task that is associated to this activity only if it 3688 // was the root activity in the task. The result code and data is ignored because 3689 // we don't support returning them across task boundaries. 3690 res = removeTaskByIdLocked(tr.taskId, 0); 3691 } else { 3692 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3693 resultData, "app-request", true); 3694 } 3695 return res; 3696 } finally { 3697 Binder.restoreCallingIdentity(origId); 3698 } 3699 } 3700 } 3701 3702 @Override 3703 public final void finishHeavyWeightApp() { 3704 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3705 != PackageManager.PERMISSION_GRANTED) { 3706 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3707 + Binder.getCallingPid() 3708 + ", uid=" + Binder.getCallingUid() 3709 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3710 Slog.w(TAG, msg); 3711 throw new SecurityException(msg); 3712 } 3713 3714 synchronized(this) { 3715 if (mHeavyWeightProcess == null) { 3716 return; 3717 } 3718 3719 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3720 mHeavyWeightProcess.activities); 3721 for (int i=0; i<activities.size(); i++) { 3722 ActivityRecord r = activities.get(i); 3723 if (!r.finishing) { 3724 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3725 null, "finish-heavy", true); 3726 } 3727 } 3728 3729 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3730 mHeavyWeightProcess.userId, 0)); 3731 mHeavyWeightProcess = null; 3732 } 3733 } 3734 3735 @Override 3736 public void crashApplication(int uid, int initialPid, String packageName, 3737 String message) { 3738 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3739 != PackageManager.PERMISSION_GRANTED) { 3740 String msg = "Permission Denial: crashApplication() from pid=" 3741 + Binder.getCallingPid() 3742 + ", uid=" + Binder.getCallingUid() 3743 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3744 Slog.w(TAG, msg); 3745 throw new SecurityException(msg); 3746 } 3747 3748 synchronized(this) { 3749 ProcessRecord proc = null; 3750 3751 // Figure out which process to kill. We don't trust that initialPid 3752 // still has any relation to current pids, so must scan through the 3753 // list. 3754 synchronized (mPidsSelfLocked) { 3755 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3756 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3757 if (p.uid != uid) { 3758 continue; 3759 } 3760 if (p.pid == initialPid) { 3761 proc = p; 3762 break; 3763 } 3764 if (p.pkgList.containsKey(packageName)) { 3765 proc = p; 3766 } 3767 } 3768 } 3769 3770 if (proc == null) { 3771 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3772 + " initialPid=" + initialPid 3773 + " packageName=" + packageName); 3774 return; 3775 } 3776 3777 if (proc.thread != null) { 3778 if (proc.pid == Process.myPid()) { 3779 Log.w(TAG, "crashApplication: trying to crash self!"); 3780 return; 3781 } 3782 long ident = Binder.clearCallingIdentity(); 3783 try { 3784 proc.thread.scheduleCrash(message); 3785 } catch (RemoteException e) { 3786 } 3787 Binder.restoreCallingIdentity(ident); 3788 } 3789 } 3790 } 3791 3792 @Override 3793 public final void finishSubActivity(IBinder token, String resultWho, 3794 int requestCode) { 3795 synchronized(this) { 3796 final long origId = Binder.clearCallingIdentity(); 3797 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3798 if (r != null) { 3799 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3800 } 3801 Binder.restoreCallingIdentity(origId); 3802 } 3803 } 3804 3805 @Override 3806 public boolean finishActivityAffinity(IBinder token) { 3807 synchronized(this) { 3808 final long origId = Binder.clearCallingIdentity(); 3809 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3810 boolean res = false; 3811 if (r != null) { 3812 res = r.task.stack.finishActivityAffinityLocked(r); 3813 } 3814 Binder.restoreCallingIdentity(origId); 3815 return res; 3816 } 3817 } 3818 3819 @Override 3820 public boolean willActivityBeVisible(IBinder token) { 3821 synchronized(this) { 3822 ActivityStack stack = ActivityRecord.getStackLocked(token); 3823 if (stack != null) { 3824 return stack.willActivityBeVisibleLocked(token); 3825 } 3826 return false; 3827 } 3828 } 3829 3830 @Override 3831 public void overridePendingTransition(IBinder token, String packageName, 3832 int enterAnim, int exitAnim) { 3833 synchronized(this) { 3834 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3835 if (self == null) { 3836 return; 3837 } 3838 3839 final long origId = Binder.clearCallingIdentity(); 3840 3841 if (self.state == ActivityState.RESUMED 3842 || self.state == ActivityState.PAUSING) { 3843 mWindowManager.overridePendingAppTransition(packageName, 3844 enterAnim, exitAnim, null); 3845 } 3846 3847 Binder.restoreCallingIdentity(origId); 3848 } 3849 } 3850 3851 /** 3852 * Main function for removing an existing process from the activity manager 3853 * as a result of that process going away. Clears out all connections 3854 * to the process. 3855 */ 3856 private final void handleAppDiedLocked(ProcessRecord app, 3857 boolean restarting, boolean allowRestart) { 3858 int pid = app.pid; 3859 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3860 if (!restarting) { 3861 removeLruProcessLocked(app); 3862 if (pid > 0) { 3863 ProcessList.remove(pid); 3864 } 3865 } 3866 3867 if (mProfileProc == app) { 3868 clearProfilerLocked(); 3869 } 3870 3871 // Remove this application's activities from active lists. 3872 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3873 3874 app.activities.clear(); 3875 3876 if (app.instrumentationClass != null) { 3877 Slog.w(TAG, "Crash of app " + app.processName 3878 + " running instrumentation " + app.instrumentationClass); 3879 Bundle info = new Bundle(); 3880 info.putString("shortMsg", "Process crashed."); 3881 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3882 } 3883 3884 if (!restarting) { 3885 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3886 // If there was nothing to resume, and we are not already 3887 // restarting this process, but there is a visible activity that 3888 // is hosted by the process... then make sure all visible 3889 // activities are running, taking care of restarting this 3890 // process. 3891 if (hasVisibleActivities) { 3892 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3893 } 3894 } 3895 } 3896 } 3897 3898 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3899 IBinder threadBinder = thread.asBinder(); 3900 // Find the application record. 3901 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3902 ProcessRecord rec = mLruProcesses.get(i); 3903 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3904 return i; 3905 } 3906 } 3907 return -1; 3908 } 3909 3910 final ProcessRecord getRecordForAppLocked( 3911 IApplicationThread thread) { 3912 if (thread == null) { 3913 return null; 3914 } 3915 3916 int appIndex = getLRURecordIndexForAppLocked(thread); 3917 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3918 } 3919 3920 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3921 // If there are no longer any background processes running, 3922 // and the app that died was not running instrumentation, 3923 // then tell everyone we are now low on memory. 3924 boolean haveBg = false; 3925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3926 ProcessRecord rec = mLruProcesses.get(i); 3927 if (rec.thread != null 3928 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3929 haveBg = true; 3930 break; 3931 } 3932 } 3933 3934 if (!haveBg) { 3935 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3936 if (doReport) { 3937 long now = SystemClock.uptimeMillis(); 3938 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3939 doReport = false; 3940 } else { 3941 mLastMemUsageReportTime = now; 3942 } 3943 } 3944 final ArrayList<ProcessMemInfo> memInfos 3945 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3946 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3947 long now = SystemClock.uptimeMillis(); 3948 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3949 ProcessRecord rec = mLruProcesses.get(i); 3950 if (rec == dyingProc || rec.thread == null) { 3951 continue; 3952 } 3953 if (doReport) { 3954 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3955 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3956 } 3957 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3958 // The low memory report is overriding any current 3959 // state for a GC request. Make sure to do 3960 // heavy/important/visible/foreground processes first. 3961 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3962 rec.lastRequestedGc = 0; 3963 } else { 3964 rec.lastRequestedGc = rec.lastLowMemory; 3965 } 3966 rec.reportLowMemory = true; 3967 rec.lastLowMemory = now; 3968 mProcessesToGc.remove(rec); 3969 addProcessToGcListLocked(rec); 3970 } 3971 } 3972 if (doReport) { 3973 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3974 mHandler.sendMessage(msg); 3975 } 3976 scheduleAppGcsLocked(); 3977 } 3978 } 3979 3980 final void appDiedLocked(ProcessRecord app, int pid, 3981 IApplicationThread thread) { 3982 3983 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3984 synchronized (stats) { 3985 stats.noteProcessDiedLocked(app.info.uid, pid); 3986 } 3987 3988 // Clean up already done if the process has been re-started. 3989 if (app.pid == pid && app.thread != null && 3990 app.thread.asBinder() == thread.asBinder()) { 3991 boolean doLowMem = app.instrumentationClass == null; 3992 boolean doOomAdj = doLowMem; 3993 if (!app.killedByAm) { 3994 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3995 + ") has died."); 3996 mAllowLowerMemLevel = true; 3997 } else { 3998 // Note that we always want to do oom adj to update our state with the 3999 // new number of procs. 4000 mAllowLowerMemLevel = false; 4001 doLowMem = false; 4002 } 4003 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4004 if (DEBUG_CLEANUP) Slog.v( 4005 TAG, "Dying app: " + app + ", pid: " + pid 4006 + ", thread: " + thread.asBinder()); 4007 handleAppDiedLocked(app, false, true); 4008 4009 if (doOomAdj) { 4010 updateOomAdjLocked(); 4011 } 4012 if (doLowMem) { 4013 doLowMemReportIfNeededLocked(app); 4014 } 4015 } else if (app.pid != pid) { 4016 // A new process has already been started. 4017 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4018 + ") has died and restarted (pid " + app.pid + ")."); 4019 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4020 } else if (DEBUG_PROCESSES) { 4021 Slog.d(TAG, "Received spurious death notification for thread " 4022 + thread.asBinder()); 4023 } 4024 } 4025 4026 /** 4027 * If a stack trace dump file is configured, dump process stack traces. 4028 * @param clearTraces causes the dump file to be erased prior to the new 4029 * traces being written, if true; when false, the new traces will be 4030 * appended to any existing file content. 4031 * @param firstPids of dalvik VM processes to dump stack traces for first 4032 * @param lastPids of dalvik VM processes to dump stack traces for last 4033 * @param nativeProcs optional list of native process names to dump stack crawls 4034 * @return file containing stack traces, or null if no dump file is configured 4035 */ 4036 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4037 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4038 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4039 if (tracesPath == null || tracesPath.length() == 0) { 4040 return null; 4041 } 4042 4043 File tracesFile = new File(tracesPath); 4044 try { 4045 File tracesDir = tracesFile.getParentFile(); 4046 if (!tracesDir.exists()) { 4047 tracesFile.mkdirs(); 4048 if (!SELinux.restorecon(tracesDir)) { 4049 return null; 4050 } 4051 } 4052 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4053 4054 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4055 tracesFile.createNewFile(); 4056 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4057 } catch (IOException e) { 4058 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4059 return null; 4060 } 4061 4062 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4063 return tracesFile; 4064 } 4065 4066 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4067 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4068 // Use a FileObserver to detect when traces finish writing. 4069 // The order of traces is considered important to maintain for legibility. 4070 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4071 @Override 4072 public synchronized void onEvent(int event, String path) { notify(); } 4073 }; 4074 4075 try { 4076 observer.startWatching(); 4077 4078 // First collect all of the stacks of the most important pids. 4079 if (firstPids != null) { 4080 try { 4081 int num = firstPids.size(); 4082 for (int i = 0; i < num; i++) { 4083 synchronized (observer) { 4084 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4085 observer.wait(200); // Wait for write-close, give up after 200msec 4086 } 4087 } 4088 } catch (InterruptedException e) { 4089 Log.wtf(TAG, e); 4090 } 4091 } 4092 4093 // Next collect the stacks of the native pids 4094 if (nativeProcs != null) { 4095 int[] pids = Process.getPidsForCommands(nativeProcs); 4096 if (pids != null) { 4097 for (int pid : pids) { 4098 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4099 } 4100 } 4101 } 4102 4103 // Lastly, measure CPU usage. 4104 if (processCpuTracker != null) { 4105 processCpuTracker.init(); 4106 System.gc(); 4107 processCpuTracker.update(); 4108 try { 4109 synchronized (processCpuTracker) { 4110 processCpuTracker.wait(500); // measure over 1/2 second. 4111 } 4112 } catch (InterruptedException e) { 4113 } 4114 processCpuTracker.update(); 4115 4116 // We'll take the stack crawls of just the top apps using CPU. 4117 final int N = processCpuTracker.countWorkingStats(); 4118 int numProcs = 0; 4119 for (int i=0; i<N && numProcs<5; i++) { 4120 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4121 if (lastPids.indexOfKey(stats.pid) >= 0) { 4122 numProcs++; 4123 try { 4124 synchronized (observer) { 4125 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4126 observer.wait(200); // Wait for write-close, give up after 200msec 4127 } 4128 } catch (InterruptedException e) { 4129 Log.wtf(TAG, e); 4130 } 4131 4132 } 4133 } 4134 } 4135 } finally { 4136 observer.stopWatching(); 4137 } 4138 } 4139 4140 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4141 if (true || IS_USER_BUILD) { 4142 return; 4143 } 4144 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4145 if (tracesPath == null || tracesPath.length() == 0) { 4146 return; 4147 } 4148 4149 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4150 StrictMode.allowThreadDiskWrites(); 4151 try { 4152 final File tracesFile = new File(tracesPath); 4153 final File tracesDir = tracesFile.getParentFile(); 4154 final File tracesTmp = new File(tracesDir, "__tmp__"); 4155 try { 4156 if (!tracesDir.exists()) { 4157 tracesFile.mkdirs(); 4158 if (!SELinux.restorecon(tracesDir.getPath())) { 4159 return; 4160 } 4161 } 4162 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4163 4164 if (tracesFile.exists()) { 4165 tracesTmp.delete(); 4166 tracesFile.renameTo(tracesTmp); 4167 } 4168 StringBuilder sb = new StringBuilder(); 4169 Time tobj = new Time(); 4170 tobj.set(System.currentTimeMillis()); 4171 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4172 sb.append(": "); 4173 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4174 sb.append(" since "); 4175 sb.append(msg); 4176 FileOutputStream fos = new FileOutputStream(tracesFile); 4177 fos.write(sb.toString().getBytes()); 4178 if (app == null) { 4179 fos.write("\n*** No application process!".getBytes()); 4180 } 4181 fos.close(); 4182 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4183 } catch (IOException e) { 4184 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4185 return; 4186 } 4187 4188 if (app != null) { 4189 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4190 firstPids.add(app.pid); 4191 dumpStackTraces(tracesPath, firstPids, null, null, null); 4192 } 4193 4194 File lastTracesFile = null; 4195 File curTracesFile = null; 4196 for (int i=9; i>=0; i--) { 4197 String name = String.format(Locale.US, "slow%02d.txt", i); 4198 curTracesFile = new File(tracesDir, name); 4199 if (curTracesFile.exists()) { 4200 if (lastTracesFile != null) { 4201 curTracesFile.renameTo(lastTracesFile); 4202 } else { 4203 curTracesFile.delete(); 4204 } 4205 } 4206 lastTracesFile = curTracesFile; 4207 } 4208 tracesFile.renameTo(curTracesFile); 4209 if (tracesTmp.exists()) { 4210 tracesTmp.renameTo(tracesFile); 4211 } 4212 } finally { 4213 StrictMode.setThreadPolicy(oldPolicy); 4214 } 4215 } 4216 4217 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4218 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4219 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4220 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4221 4222 if (mController != null) { 4223 try { 4224 // 0 == continue, -1 = kill process immediately 4225 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4226 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4227 } catch (RemoteException e) { 4228 mController = null; 4229 Watchdog.getInstance().setActivityController(null); 4230 } 4231 } 4232 4233 long anrTime = SystemClock.uptimeMillis(); 4234 if (MONITOR_CPU_USAGE) { 4235 updateCpuStatsNow(); 4236 } 4237 4238 synchronized (this) { 4239 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4240 if (mShuttingDown) { 4241 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4242 return; 4243 } else if (app.notResponding) { 4244 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4245 return; 4246 } else if (app.crashing) { 4247 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4248 return; 4249 } 4250 4251 // In case we come through here for the same app before completing 4252 // this one, mark as anring now so we will bail out. 4253 app.notResponding = true; 4254 4255 // Log the ANR to the event log. 4256 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4257 app.processName, app.info.flags, annotation); 4258 4259 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4260 firstPids.add(app.pid); 4261 4262 int parentPid = app.pid; 4263 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4264 if (parentPid != app.pid) firstPids.add(parentPid); 4265 4266 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4267 4268 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4269 ProcessRecord r = mLruProcesses.get(i); 4270 if (r != null && r.thread != null) { 4271 int pid = r.pid; 4272 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4273 if (r.persistent) { 4274 firstPids.add(pid); 4275 } else { 4276 lastPids.put(pid, Boolean.TRUE); 4277 } 4278 } 4279 } 4280 } 4281 } 4282 4283 // Log the ANR to the main log. 4284 StringBuilder info = new StringBuilder(); 4285 info.setLength(0); 4286 info.append("ANR in ").append(app.processName); 4287 if (activity != null && activity.shortComponentName != null) { 4288 info.append(" (").append(activity.shortComponentName).append(")"); 4289 } 4290 info.append("\n"); 4291 info.append("PID: ").append(app.pid).append("\n"); 4292 if (annotation != null) { 4293 info.append("Reason: ").append(annotation).append("\n"); 4294 } 4295 if (parent != null && parent != activity) { 4296 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4297 } 4298 4299 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4300 4301 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4302 NATIVE_STACKS_OF_INTEREST); 4303 4304 String cpuInfo = null; 4305 if (MONITOR_CPU_USAGE) { 4306 updateCpuStatsNow(); 4307 synchronized (mProcessCpuThread) { 4308 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4309 } 4310 info.append(processCpuTracker.printCurrentLoad()); 4311 info.append(cpuInfo); 4312 } 4313 4314 info.append(processCpuTracker.printCurrentState(anrTime)); 4315 4316 Slog.e(TAG, info.toString()); 4317 if (tracesFile == null) { 4318 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4319 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4320 } 4321 4322 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4323 cpuInfo, tracesFile, null); 4324 4325 if (mController != null) { 4326 try { 4327 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4328 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4329 if (res != 0) { 4330 if (res < 0 && app.pid != MY_PID) { 4331 Process.killProcess(app.pid); 4332 } else { 4333 synchronized (this) { 4334 mServices.scheduleServiceTimeoutLocked(app); 4335 } 4336 } 4337 return; 4338 } 4339 } catch (RemoteException e) { 4340 mController = null; 4341 Watchdog.getInstance().setActivityController(null); 4342 } 4343 } 4344 4345 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4346 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4347 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4348 4349 synchronized (this) { 4350 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4351 killUnneededProcessLocked(app, "background ANR"); 4352 return; 4353 } 4354 4355 // Set the app's notResponding state, and look up the errorReportReceiver 4356 makeAppNotRespondingLocked(app, 4357 activity != null ? activity.shortComponentName : null, 4358 annotation != null ? "ANR " + annotation : "ANR", 4359 info.toString()); 4360 4361 // Bring up the infamous App Not Responding dialog 4362 Message msg = Message.obtain(); 4363 HashMap<String, Object> map = new HashMap<String, Object>(); 4364 msg.what = SHOW_NOT_RESPONDING_MSG; 4365 msg.obj = map; 4366 msg.arg1 = aboveSystem ? 1 : 0; 4367 map.put("app", app); 4368 if (activity != null) { 4369 map.put("activity", activity); 4370 } 4371 4372 mHandler.sendMessage(msg); 4373 } 4374 } 4375 4376 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4377 if (!mLaunchWarningShown) { 4378 mLaunchWarningShown = true; 4379 mHandler.post(new Runnable() { 4380 @Override 4381 public void run() { 4382 synchronized (ActivityManagerService.this) { 4383 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4384 d.show(); 4385 mHandler.postDelayed(new Runnable() { 4386 @Override 4387 public void run() { 4388 synchronized (ActivityManagerService.this) { 4389 d.dismiss(); 4390 mLaunchWarningShown = false; 4391 } 4392 } 4393 }, 4000); 4394 } 4395 } 4396 }); 4397 } 4398 } 4399 4400 @Override 4401 public boolean clearApplicationUserData(final String packageName, 4402 final IPackageDataObserver observer, int userId) { 4403 enforceNotIsolatedCaller("clearApplicationUserData"); 4404 int uid = Binder.getCallingUid(); 4405 int pid = Binder.getCallingPid(); 4406 userId = handleIncomingUser(pid, uid, 4407 userId, false, true, "clearApplicationUserData", null); 4408 long callingId = Binder.clearCallingIdentity(); 4409 try { 4410 IPackageManager pm = AppGlobals.getPackageManager(); 4411 int pkgUid = -1; 4412 synchronized(this) { 4413 try { 4414 pkgUid = pm.getPackageUid(packageName, userId); 4415 } catch (RemoteException e) { 4416 } 4417 if (pkgUid == -1) { 4418 Slog.w(TAG, "Invalid packageName: " + packageName); 4419 if (observer != null) { 4420 try { 4421 observer.onRemoveCompleted(packageName, false); 4422 } catch (RemoteException e) { 4423 Slog.i(TAG, "Observer no longer exists."); 4424 } 4425 } 4426 return false; 4427 } 4428 if (uid == pkgUid || checkComponentPermission( 4429 android.Manifest.permission.CLEAR_APP_USER_DATA, 4430 pid, uid, -1, true) 4431 == PackageManager.PERMISSION_GRANTED) { 4432 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4433 } else { 4434 throw new SecurityException("PID " + pid + " does not have permission " 4435 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4436 + " of package " + packageName); 4437 } 4438 } 4439 4440 try { 4441 // Clear application user data 4442 pm.clearApplicationUserData(packageName, observer, userId); 4443 4444 // Remove all permissions granted from/to this package 4445 removeUriPermissionsForPackageLocked(packageName, userId, true); 4446 4447 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4448 Uri.fromParts("package", packageName, null)); 4449 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4450 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4451 null, null, 0, null, null, null, false, false, userId); 4452 } catch (RemoteException e) { 4453 } 4454 } finally { 4455 Binder.restoreCallingIdentity(callingId); 4456 } 4457 return true; 4458 } 4459 4460 @Override 4461 public void killBackgroundProcesses(final String packageName, int userId) { 4462 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4463 != PackageManager.PERMISSION_GRANTED && 4464 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4465 != PackageManager.PERMISSION_GRANTED) { 4466 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4467 + Binder.getCallingPid() 4468 + ", uid=" + Binder.getCallingUid() 4469 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4470 Slog.w(TAG, msg); 4471 throw new SecurityException(msg); 4472 } 4473 4474 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4475 userId, true, true, "killBackgroundProcesses", null); 4476 long callingId = Binder.clearCallingIdentity(); 4477 try { 4478 IPackageManager pm = AppGlobals.getPackageManager(); 4479 synchronized(this) { 4480 int appId = -1; 4481 try { 4482 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4483 } catch (RemoteException e) { 4484 } 4485 if (appId == -1) { 4486 Slog.w(TAG, "Invalid packageName: " + packageName); 4487 return; 4488 } 4489 killPackageProcessesLocked(packageName, appId, userId, 4490 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4491 } 4492 } finally { 4493 Binder.restoreCallingIdentity(callingId); 4494 } 4495 } 4496 4497 @Override 4498 public void killAllBackgroundProcesses() { 4499 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4500 != PackageManager.PERMISSION_GRANTED) { 4501 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4502 + Binder.getCallingPid() 4503 + ", uid=" + Binder.getCallingUid() 4504 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4505 Slog.w(TAG, msg); 4506 throw new SecurityException(msg); 4507 } 4508 4509 long callingId = Binder.clearCallingIdentity(); 4510 try { 4511 synchronized(this) { 4512 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4513 final int NP = mProcessNames.getMap().size(); 4514 for (int ip=0; ip<NP; ip++) { 4515 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4516 final int NA = apps.size(); 4517 for (int ia=0; ia<NA; ia++) { 4518 ProcessRecord app = apps.valueAt(ia); 4519 if (app.persistent) { 4520 // we don't kill persistent processes 4521 continue; 4522 } 4523 if (app.removed) { 4524 procs.add(app); 4525 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4526 app.removed = true; 4527 procs.add(app); 4528 } 4529 } 4530 } 4531 4532 int N = procs.size(); 4533 for (int i=0; i<N; i++) { 4534 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4535 } 4536 mAllowLowerMemLevel = true; 4537 updateOomAdjLocked(); 4538 doLowMemReportIfNeededLocked(null); 4539 } 4540 } finally { 4541 Binder.restoreCallingIdentity(callingId); 4542 } 4543 } 4544 4545 @Override 4546 public void forceStopPackage(final String packageName, int userId) { 4547 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4548 != PackageManager.PERMISSION_GRANTED) { 4549 String msg = "Permission Denial: forceStopPackage() from pid=" 4550 + Binder.getCallingPid() 4551 + ", uid=" + Binder.getCallingUid() 4552 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4553 Slog.w(TAG, msg); 4554 throw new SecurityException(msg); 4555 } 4556 final int callingPid = Binder.getCallingPid(); 4557 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4558 userId, true, true, "forceStopPackage", null); 4559 long callingId = Binder.clearCallingIdentity(); 4560 try { 4561 IPackageManager pm = AppGlobals.getPackageManager(); 4562 synchronized(this) { 4563 int[] users = userId == UserHandle.USER_ALL 4564 ? getUsersLocked() : new int[] { userId }; 4565 for (int user : users) { 4566 int pkgUid = -1; 4567 try { 4568 pkgUid = pm.getPackageUid(packageName, user); 4569 } catch (RemoteException e) { 4570 } 4571 if (pkgUid == -1) { 4572 Slog.w(TAG, "Invalid packageName: " + packageName); 4573 continue; 4574 } 4575 try { 4576 pm.setPackageStoppedState(packageName, true, user); 4577 } catch (RemoteException e) { 4578 } catch (IllegalArgumentException e) { 4579 Slog.w(TAG, "Failed trying to unstop package " 4580 + packageName + ": " + e); 4581 } 4582 if (isUserRunningLocked(user, false)) { 4583 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4584 } 4585 } 4586 } 4587 } finally { 4588 Binder.restoreCallingIdentity(callingId); 4589 } 4590 } 4591 4592 /* 4593 * The pkg name and app id have to be specified. 4594 */ 4595 @Override 4596 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4597 if (pkg == null) { 4598 return; 4599 } 4600 // Make sure the uid is valid. 4601 if (appid < 0) { 4602 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4603 return; 4604 } 4605 int callerUid = Binder.getCallingUid(); 4606 // Only the system server can kill an application 4607 if (callerUid == Process.SYSTEM_UID) { 4608 // Post an aysnc message to kill the application 4609 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4610 msg.arg1 = appid; 4611 msg.arg2 = 0; 4612 Bundle bundle = new Bundle(); 4613 bundle.putString("pkg", pkg); 4614 bundle.putString("reason", reason); 4615 msg.obj = bundle; 4616 mHandler.sendMessage(msg); 4617 } else { 4618 throw new SecurityException(callerUid + " cannot kill pkg: " + 4619 pkg); 4620 } 4621 } 4622 4623 @Override 4624 public void closeSystemDialogs(String reason) { 4625 enforceNotIsolatedCaller("closeSystemDialogs"); 4626 4627 final int pid = Binder.getCallingPid(); 4628 final int uid = Binder.getCallingUid(); 4629 final long origId = Binder.clearCallingIdentity(); 4630 try { 4631 synchronized (this) { 4632 // Only allow this from foreground processes, so that background 4633 // applications can't abuse it to prevent system UI from being shown. 4634 if (uid >= Process.FIRST_APPLICATION_UID) { 4635 ProcessRecord proc; 4636 synchronized (mPidsSelfLocked) { 4637 proc = mPidsSelfLocked.get(pid); 4638 } 4639 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4640 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4641 + " from background process " + proc); 4642 return; 4643 } 4644 } 4645 closeSystemDialogsLocked(reason); 4646 } 4647 } finally { 4648 Binder.restoreCallingIdentity(origId); 4649 } 4650 } 4651 4652 void closeSystemDialogsLocked(String reason) { 4653 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4655 | Intent.FLAG_RECEIVER_FOREGROUND); 4656 if (reason != null) { 4657 intent.putExtra("reason", reason); 4658 } 4659 mWindowManager.closeSystemDialogs(reason); 4660 4661 mStackSupervisor.closeSystemDialogsLocked(); 4662 4663 broadcastIntentLocked(null, null, intent, null, 4664 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4665 Process.SYSTEM_UID, UserHandle.USER_ALL); 4666 } 4667 4668 @Override 4669 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4670 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4671 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4672 for (int i=pids.length-1; i>=0; i--) { 4673 ProcessRecord proc; 4674 int oomAdj; 4675 synchronized (this) { 4676 synchronized (mPidsSelfLocked) { 4677 proc = mPidsSelfLocked.get(pids[i]); 4678 oomAdj = proc != null ? proc.setAdj : 0; 4679 } 4680 } 4681 infos[i] = new Debug.MemoryInfo(); 4682 Debug.getMemoryInfo(pids[i], infos[i]); 4683 if (proc != null) { 4684 synchronized (this) { 4685 if (proc.thread != null && proc.setAdj == oomAdj) { 4686 // Record this for posterity if the process has been stable. 4687 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4688 infos[i].getTotalUss(), false, proc.pkgList); 4689 } 4690 } 4691 } 4692 } 4693 return infos; 4694 } 4695 4696 @Override 4697 public long[] getProcessPss(int[] pids) { 4698 enforceNotIsolatedCaller("getProcessPss"); 4699 long[] pss = new long[pids.length]; 4700 for (int i=pids.length-1; i>=0; i--) { 4701 ProcessRecord proc; 4702 int oomAdj; 4703 synchronized (this) { 4704 synchronized (mPidsSelfLocked) { 4705 proc = mPidsSelfLocked.get(pids[i]); 4706 oomAdj = proc != null ? proc.setAdj : 0; 4707 } 4708 } 4709 long[] tmpUss = new long[1]; 4710 pss[i] = Debug.getPss(pids[i], tmpUss); 4711 if (proc != null) { 4712 synchronized (this) { 4713 if (proc.thread != null && proc.setAdj == oomAdj) { 4714 // Record this for posterity if the process has been stable. 4715 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4716 } 4717 } 4718 } 4719 } 4720 return pss; 4721 } 4722 4723 @Override 4724 public void killApplicationProcess(String processName, int uid) { 4725 if (processName == null) { 4726 return; 4727 } 4728 4729 int callerUid = Binder.getCallingUid(); 4730 // Only the system server can kill an application 4731 if (callerUid == Process.SYSTEM_UID) { 4732 synchronized (this) { 4733 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4734 if (app != null && app.thread != null) { 4735 try { 4736 app.thread.scheduleSuicide(); 4737 } catch (RemoteException e) { 4738 // If the other end already died, then our work here is done. 4739 } 4740 } else { 4741 Slog.w(TAG, "Process/uid not found attempting kill of " 4742 + processName + " / " + uid); 4743 } 4744 } 4745 } else { 4746 throw new SecurityException(callerUid + " cannot kill app process: " + 4747 processName); 4748 } 4749 } 4750 4751 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4752 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4753 false, true, false, false, UserHandle.getUserId(uid), reason); 4754 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4755 Uri.fromParts("package", packageName, null)); 4756 if (!mProcessesReady) { 4757 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4758 | Intent.FLAG_RECEIVER_FOREGROUND); 4759 } 4760 intent.putExtra(Intent.EXTRA_UID, uid); 4761 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4762 broadcastIntentLocked(null, null, intent, 4763 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4764 false, false, 4765 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4766 } 4767 4768 private void forceStopUserLocked(int userId, String reason) { 4769 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4770 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4771 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4772 | Intent.FLAG_RECEIVER_FOREGROUND); 4773 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4774 broadcastIntentLocked(null, null, intent, 4775 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4776 false, false, 4777 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4778 } 4779 4780 private final boolean killPackageProcessesLocked(String packageName, int appId, 4781 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4782 boolean doit, boolean evenPersistent, String reason) { 4783 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4784 4785 // Remove all processes this package may have touched: all with the 4786 // same UID (except for the system or root user), and all whose name 4787 // matches the package name. 4788 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4789 final int NP = mProcessNames.getMap().size(); 4790 for (int ip=0; ip<NP; ip++) { 4791 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4792 final int NA = apps.size(); 4793 for (int ia=0; ia<NA; ia++) { 4794 ProcessRecord app = apps.valueAt(ia); 4795 if (app.persistent && !evenPersistent) { 4796 // we don't kill persistent processes 4797 continue; 4798 } 4799 if (app.removed) { 4800 if (doit) { 4801 procs.add(app); 4802 } 4803 continue; 4804 } 4805 4806 // Skip process if it doesn't meet our oom adj requirement. 4807 if (app.setAdj < minOomAdj) { 4808 continue; 4809 } 4810 4811 // If no package is specified, we call all processes under the 4812 // give user id. 4813 if (packageName == null) { 4814 if (app.userId != userId) { 4815 continue; 4816 } 4817 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4818 continue; 4819 } 4820 // Package has been specified, we want to hit all processes 4821 // that match it. We need to qualify this by the processes 4822 // that are running under the specified app and user ID. 4823 } else { 4824 if (UserHandle.getAppId(app.uid) != appId) { 4825 continue; 4826 } 4827 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4828 continue; 4829 } 4830 if (!app.pkgList.containsKey(packageName)) { 4831 continue; 4832 } 4833 } 4834 4835 // Process has passed all conditions, kill it! 4836 if (!doit) { 4837 return true; 4838 } 4839 app.removed = true; 4840 procs.add(app); 4841 } 4842 } 4843 4844 int N = procs.size(); 4845 for (int i=0; i<N; i++) { 4846 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4847 } 4848 updateOomAdjLocked(); 4849 return N > 0; 4850 } 4851 4852 private final boolean forceStopPackageLocked(String name, int appId, 4853 boolean callerWillRestart, boolean purgeCache, boolean doit, 4854 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4855 int i; 4856 int N; 4857 4858 if (userId == UserHandle.USER_ALL && name == null) { 4859 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4860 } 4861 4862 if (appId < 0 && name != null) { 4863 try { 4864 appId = UserHandle.getAppId( 4865 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4866 } catch (RemoteException e) { 4867 } 4868 } 4869 4870 if (doit) { 4871 if (name != null) { 4872 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4873 + " user=" + userId + ": " + reason); 4874 } else { 4875 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4876 } 4877 4878 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4879 for (int ip=pmap.size()-1; ip>=0; ip--) { 4880 SparseArray<Long> ba = pmap.valueAt(ip); 4881 for (i=ba.size()-1; i>=0; i--) { 4882 boolean remove = false; 4883 final int entUid = ba.keyAt(i); 4884 if (name != null) { 4885 if (userId == UserHandle.USER_ALL) { 4886 if (UserHandle.getAppId(entUid) == appId) { 4887 remove = true; 4888 } 4889 } else { 4890 if (entUid == UserHandle.getUid(userId, appId)) { 4891 remove = true; 4892 } 4893 } 4894 } else if (UserHandle.getUserId(entUid) == userId) { 4895 remove = true; 4896 } 4897 if (remove) { 4898 ba.removeAt(i); 4899 } 4900 } 4901 if (ba.size() == 0) { 4902 pmap.removeAt(ip); 4903 } 4904 } 4905 } 4906 4907 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4908 -100, callerWillRestart, true, doit, evenPersistent, 4909 name == null ? ("stop user " + userId) : ("stop " + name)); 4910 4911 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4912 if (!doit) { 4913 return true; 4914 } 4915 didSomething = true; 4916 } 4917 4918 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4919 if (!doit) { 4920 return true; 4921 } 4922 didSomething = true; 4923 } 4924 4925 if (name == null) { 4926 // Remove all sticky broadcasts from this user. 4927 mStickyBroadcasts.remove(userId); 4928 } 4929 4930 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4931 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4932 userId, providers)) { 4933 if (!doit) { 4934 return true; 4935 } 4936 didSomething = true; 4937 } 4938 N = providers.size(); 4939 for (i=0; i<N; i++) { 4940 removeDyingProviderLocked(null, providers.get(i), true); 4941 } 4942 4943 // Remove transient permissions granted from/to this package/user 4944 removeUriPermissionsForPackageLocked(name, userId, false); 4945 4946 if (name == null || uninstalling) { 4947 // Remove pending intents. For now we only do this when force 4948 // stopping users, because we have some problems when doing this 4949 // for packages -- app widgets are not currently cleaned up for 4950 // such packages, so they can be left with bad pending intents. 4951 if (mIntentSenderRecords.size() > 0) { 4952 Iterator<WeakReference<PendingIntentRecord>> it 4953 = mIntentSenderRecords.values().iterator(); 4954 while (it.hasNext()) { 4955 WeakReference<PendingIntentRecord> wpir = it.next(); 4956 if (wpir == null) { 4957 it.remove(); 4958 continue; 4959 } 4960 PendingIntentRecord pir = wpir.get(); 4961 if (pir == null) { 4962 it.remove(); 4963 continue; 4964 } 4965 if (name == null) { 4966 // Stopping user, remove all objects for the user. 4967 if (pir.key.userId != userId) { 4968 // Not the same user, skip it. 4969 continue; 4970 } 4971 } else { 4972 if (UserHandle.getAppId(pir.uid) != appId) { 4973 // Different app id, skip it. 4974 continue; 4975 } 4976 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4977 // Different user, skip it. 4978 continue; 4979 } 4980 if (!pir.key.packageName.equals(name)) { 4981 // Different package, skip it. 4982 continue; 4983 } 4984 } 4985 if (!doit) { 4986 return true; 4987 } 4988 didSomething = true; 4989 it.remove(); 4990 pir.canceled = true; 4991 if (pir.key.activity != null) { 4992 pir.key.activity.pendingResults.remove(pir.ref); 4993 } 4994 } 4995 } 4996 } 4997 4998 if (doit) { 4999 if (purgeCache && name != null) { 5000 AttributeCache ac = AttributeCache.instance(); 5001 if (ac != null) { 5002 ac.removePackage(name); 5003 } 5004 } 5005 if (mBooted) { 5006 mStackSupervisor.resumeTopActivitiesLocked(); 5007 mStackSupervisor.scheduleIdleLocked(); 5008 } 5009 } 5010 5011 return didSomething; 5012 } 5013 5014 private final boolean removeProcessLocked(ProcessRecord app, 5015 boolean callerWillRestart, boolean allowRestart, String reason) { 5016 final String name = app.processName; 5017 final int uid = app.uid; 5018 if (DEBUG_PROCESSES) Slog.d( 5019 TAG, "Force removing proc " + app.toShortString() + " (" + name 5020 + "/" + uid + ")"); 5021 5022 mProcessNames.remove(name, uid); 5023 mIsolatedProcesses.remove(app.uid); 5024 if (mHeavyWeightProcess == app) { 5025 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5026 mHeavyWeightProcess.userId, 0)); 5027 mHeavyWeightProcess = null; 5028 } 5029 boolean needRestart = false; 5030 if (app.pid > 0 && app.pid != MY_PID) { 5031 int pid = app.pid; 5032 synchronized (mPidsSelfLocked) { 5033 mPidsSelfLocked.remove(pid); 5034 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5035 } 5036 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5037 app.processName, app.info.uid); 5038 if (app.isolated) { 5039 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5040 } 5041 killUnneededProcessLocked(app, reason); 5042 handleAppDiedLocked(app, true, allowRestart); 5043 removeLruProcessLocked(app); 5044 5045 if (app.persistent && !app.isolated) { 5046 if (!callerWillRestart) { 5047 addAppLocked(app.info, false, null /* ABI override */); 5048 } else { 5049 needRestart = true; 5050 } 5051 } 5052 } else { 5053 mRemovedProcesses.add(app); 5054 } 5055 5056 return needRestart; 5057 } 5058 5059 private final void processStartTimedOutLocked(ProcessRecord app) { 5060 final int pid = app.pid; 5061 boolean gone = false; 5062 synchronized (mPidsSelfLocked) { 5063 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5064 if (knownApp != null && knownApp.thread == null) { 5065 mPidsSelfLocked.remove(pid); 5066 gone = true; 5067 } 5068 } 5069 5070 if (gone) { 5071 Slog.w(TAG, "Process " + app + " failed to attach"); 5072 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5073 pid, app.uid, app.processName); 5074 mProcessNames.remove(app.processName, app.uid); 5075 mIsolatedProcesses.remove(app.uid); 5076 if (mHeavyWeightProcess == app) { 5077 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5078 mHeavyWeightProcess.userId, 0)); 5079 mHeavyWeightProcess = null; 5080 } 5081 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5082 app.processName, app.info.uid); 5083 if (app.isolated) { 5084 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5085 } 5086 // Take care of any launching providers waiting for this process. 5087 checkAppInLaunchingProvidersLocked(app, true); 5088 // Take care of any services that are waiting for the process. 5089 mServices.processStartTimedOutLocked(app); 5090 killUnneededProcessLocked(app, "start timeout"); 5091 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5092 Slog.w(TAG, "Unattached app died before backup, skipping"); 5093 try { 5094 IBackupManager bm = IBackupManager.Stub.asInterface( 5095 ServiceManager.getService(Context.BACKUP_SERVICE)); 5096 bm.agentDisconnected(app.info.packageName); 5097 } catch (RemoteException e) { 5098 // Can't happen; the backup manager is local 5099 } 5100 } 5101 if (isPendingBroadcastProcessLocked(pid)) { 5102 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5103 skipPendingBroadcastLocked(pid); 5104 } 5105 } else { 5106 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5107 } 5108 } 5109 5110 private final boolean attachApplicationLocked(IApplicationThread thread, 5111 int pid) { 5112 5113 // Find the application record that is being attached... either via 5114 // the pid if we are running in multiple processes, or just pull the 5115 // next app record if we are emulating process with anonymous threads. 5116 ProcessRecord app; 5117 if (pid != MY_PID && pid >= 0) { 5118 synchronized (mPidsSelfLocked) { 5119 app = mPidsSelfLocked.get(pid); 5120 } 5121 } else { 5122 app = null; 5123 } 5124 5125 if (app == null) { 5126 Slog.w(TAG, "No pending application record for pid " + pid 5127 + " (IApplicationThread " + thread + "); dropping process"); 5128 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5129 if (pid > 0 && pid != MY_PID) { 5130 Process.killProcessQuiet(pid); 5131 } else { 5132 try { 5133 thread.scheduleExit(); 5134 } catch (Exception e) { 5135 // Ignore exceptions. 5136 } 5137 } 5138 return false; 5139 } 5140 5141 // If this application record is still attached to a previous 5142 // process, clean it up now. 5143 if (app.thread != null) { 5144 handleAppDiedLocked(app, true, true); 5145 } 5146 5147 // Tell the process all about itself. 5148 5149 if (localLOGV) Slog.v( 5150 TAG, "Binding process pid " + pid + " to record " + app); 5151 5152 final String processName = app.processName; 5153 try { 5154 AppDeathRecipient adr = new AppDeathRecipient( 5155 app, pid, thread); 5156 thread.asBinder().linkToDeath(adr, 0); 5157 app.deathRecipient = adr; 5158 } catch (RemoteException e) { 5159 app.resetPackageList(mProcessStats); 5160 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5161 return false; 5162 } 5163 5164 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5165 5166 app.makeActive(thread, mProcessStats); 5167 app.curAdj = app.setAdj = -100; 5168 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5169 app.forcingToForeground = null; 5170 updateProcessForegroundLocked(app, false, false); 5171 app.hasShownUi = false; 5172 app.debugging = false; 5173 app.cached = false; 5174 5175 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5176 5177 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5178 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5179 5180 if (!normalMode) { 5181 Slog.i(TAG, "Launching preboot mode app: " + app); 5182 } 5183 5184 if (localLOGV) Slog.v( 5185 TAG, "New app record " + app 5186 + " thread=" + thread.asBinder() + " pid=" + pid); 5187 try { 5188 int testMode = IApplicationThread.DEBUG_OFF; 5189 if (mDebugApp != null && mDebugApp.equals(processName)) { 5190 testMode = mWaitForDebugger 5191 ? IApplicationThread.DEBUG_WAIT 5192 : IApplicationThread.DEBUG_ON; 5193 app.debugging = true; 5194 if (mDebugTransient) { 5195 mDebugApp = mOrigDebugApp; 5196 mWaitForDebugger = mOrigWaitForDebugger; 5197 } 5198 } 5199 String profileFile = app.instrumentationProfileFile; 5200 ParcelFileDescriptor profileFd = null; 5201 boolean profileAutoStop = false; 5202 if (mProfileApp != null && mProfileApp.equals(processName)) { 5203 mProfileProc = app; 5204 profileFile = mProfileFile; 5205 profileFd = mProfileFd; 5206 profileAutoStop = mAutoStopProfiler; 5207 } 5208 boolean enableOpenGlTrace = false; 5209 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5210 enableOpenGlTrace = true; 5211 mOpenGlTraceApp = null; 5212 } 5213 5214 // If the app is being launched for restore or full backup, set it up specially 5215 boolean isRestrictedBackupMode = false; 5216 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5217 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5218 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5219 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5220 } 5221 5222 ensurePackageDexOpt(app.instrumentationInfo != null 5223 ? app.instrumentationInfo.packageName 5224 : app.info.packageName); 5225 if (app.instrumentationClass != null) { 5226 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5227 } 5228 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5229 + processName + " with config " + mConfiguration); 5230 ApplicationInfo appInfo = app.instrumentationInfo != null 5231 ? app.instrumentationInfo : app.info; 5232 app.compat = compatibilityInfoForPackageLocked(appInfo); 5233 if (profileFd != null) { 5234 profileFd = profileFd.dup(); 5235 } 5236 thread.bindApplication(processName, appInfo, providers, 5237 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5238 app.instrumentationArguments, app.instrumentationWatcher, 5239 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5240 isRestrictedBackupMode || !normalMode, app.persistent, 5241 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5242 mCoreSettingsObserver.getCoreSettingsLocked()); 5243 updateLruProcessLocked(app, false, null); 5244 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5245 } catch (Exception e) { 5246 // todo: Yikes! What should we do? For now we will try to 5247 // start another process, but that could easily get us in 5248 // an infinite loop of restarting processes... 5249 Slog.w(TAG, "Exception thrown during bind!", e); 5250 5251 app.resetPackageList(mProcessStats); 5252 app.unlinkDeathRecipient(); 5253 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5254 return false; 5255 } 5256 5257 // Remove this record from the list of starting applications. 5258 mPersistentStartingProcesses.remove(app); 5259 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5260 "Attach application locked removing on hold: " + app); 5261 mProcessesOnHold.remove(app); 5262 5263 boolean badApp = false; 5264 boolean didSomething = false; 5265 5266 // See if the top visible activity is waiting to run in this process... 5267 if (normalMode) { 5268 try { 5269 if (mStackSupervisor.attachApplicationLocked(app)) { 5270 didSomething = true; 5271 } 5272 } catch (Exception e) { 5273 badApp = true; 5274 } 5275 } 5276 5277 // Find any services that should be running in this process... 5278 if (!badApp) { 5279 try { 5280 didSomething |= mServices.attachApplicationLocked(app, processName); 5281 } catch (Exception e) { 5282 badApp = true; 5283 } 5284 } 5285 5286 // Check if a next-broadcast receiver is in this process... 5287 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5288 try { 5289 didSomething |= sendPendingBroadcastsLocked(app); 5290 } catch (Exception e) { 5291 // If the app died trying to launch the receiver we declare it 'bad' 5292 badApp = true; 5293 } 5294 } 5295 5296 // Check whether the next backup agent is in this process... 5297 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5298 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5299 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5300 try { 5301 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5302 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5303 mBackupTarget.backupMode); 5304 } catch (Exception e) { 5305 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5306 e.printStackTrace(); 5307 } 5308 } 5309 5310 if (badApp) { 5311 // todo: Also need to kill application to deal with all 5312 // kinds of exceptions. 5313 handleAppDiedLocked(app, false, true); 5314 return false; 5315 } 5316 5317 if (!didSomething) { 5318 updateOomAdjLocked(); 5319 } 5320 5321 return true; 5322 } 5323 5324 @Override 5325 public final void attachApplication(IApplicationThread thread) { 5326 synchronized (this) { 5327 int callingPid = Binder.getCallingPid(); 5328 final long origId = Binder.clearCallingIdentity(); 5329 attachApplicationLocked(thread, callingPid); 5330 Binder.restoreCallingIdentity(origId); 5331 } 5332 } 5333 5334 @Override 5335 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5336 final long origId = Binder.clearCallingIdentity(); 5337 synchronized (this) { 5338 ActivityStack stack = ActivityRecord.getStackLocked(token); 5339 if (stack != null) { 5340 ActivityRecord r = 5341 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5342 if (stopProfiling) { 5343 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5344 try { 5345 mProfileFd.close(); 5346 } catch (IOException e) { 5347 } 5348 clearProfilerLocked(); 5349 } 5350 } 5351 } 5352 } 5353 Binder.restoreCallingIdentity(origId); 5354 } 5355 5356 void enableScreenAfterBoot() { 5357 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5358 SystemClock.uptimeMillis()); 5359 mWindowManager.enableScreenAfterBoot(); 5360 5361 synchronized (this) { 5362 updateEventDispatchingLocked(); 5363 } 5364 } 5365 5366 @Override 5367 public void showBootMessage(final CharSequence msg, final boolean always) { 5368 enforceNotIsolatedCaller("showBootMessage"); 5369 mWindowManager.showBootMessage(msg, always); 5370 } 5371 5372 @Override 5373 public void dismissKeyguardOnNextActivity() { 5374 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5375 final long token = Binder.clearCallingIdentity(); 5376 try { 5377 synchronized (this) { 5378 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5379 if (mLockScreenShown) { 5380 mLockScreenShown = false; 5381 comeOutOfSleepIfNeededLocked(); 5382 } 5383 mStackSupervisor.setDismissKeyguard(true); 5384 } 5385 } finally { 5386 Binder.restoreCallingIdentity(token); 5387 } 5388 } 5389 5390 final void finishBooting() { 5391 // Register receivers to handle package update events 5392 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5393 5394 synchronized (this) { 5395 // Ensure that any processes we had put on hold are now started 5396 // up. 5397 final int NP = mProcessesOnHold.size(); 5398 if (NP > 0) { 5399 ArrayList<ProcessRecord> procs = 5400 new ArrayList<ProcessRecord>(mProcessesOnHold); 5401 for (int ip=0; ip<NP; ip++) { 5402 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5403 + procs.get(ip)); 5404 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5405 } 5406 } 5407 5408 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5409 // Start looking for apps that are abusing wake locks. 5410 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5411 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5412 // Tell anyone interested that we are done booting! 5413 SystemProperties.set("sys.boot_completed", "1"); 5414 SystemProperties.set("dev.bootcomplete", "1"); 5415 for (int i=0; i<mStartedUsers.size(); i++) { 5416 UserStartedState uss = mStartedUsers.valueAt(i); 5417 if (uss.mState == UserStartedState.STATE_BOOTING) { 5418 uss.mState = UserStartedState.STATE_RUNNING; 5419 final int userId = mStartedUsers.keyAt(i); 5420 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5421 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5422 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5423 broadcastIntentLocked(null, null, intent, null, 5424 new IIntentReceiver.Stub() { 5425 @Override 5426 public void performReceive(Intent intent, int resultCode, 5427 String data, Bundle extras, boolean ordered, 5428 boolean sticky, int sendingUser) { 5429 synchronized (ActivityManagerService.this) { 5430 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5431 true, false); 5432 } 5433 } 5434 }, 5435 0, null, null, 5436 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5437 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5438 userId); 5439 } 5440 } 5441 scheduleStartProfilesLocked(); 5442 } 5443 } 5444 } 5445 5446 final void ensureBootCompleted() { 5447 boolean booting; 5448 boolean enableScreen; 5449 synchronized (this) { 5450 booting = mBooting; 5451 mBooting = false; 5452 enableScreen = !mBooted; 5453 mBooted = true; 5454 } 5455 5456 if (booting) { 5457 finishBooting(); 5458 } 5459 5460 if (enableScreen) { 5461 enableScreenAfterBoot(); 5462 } 5463 } 5464 5465 @Override 5466 public final void activityResumed(IBinder token) { 5467 final long origId = Binder.clearCallingIdentity(); 5468 synchronized(this) { 5469 ActivityStack stack = ActivityRecord.getStackLocked(token); 5470 if (stack != null) { 5471 ActivityRecord.activityResumedLocked(token); 5472 } 5473 } 5474 Binder.restoreCallingIdentity(origId); 5475 } 5476 5477 @Override 5478 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5479 final long origId = Binder.clearCallingIdentity(); 5480 synchronized(this) { 5481 ActivityStack stack = ActivityRecord.getStackLocked(token); 5482 if (stack != null) { 5483 stack.activityPausedLocked(token, false, persistentState); 5484 } 5485 } 5486 Binder.restoreCallingIdentity(origId); 5487 } 5488 5489 @Override 5490 public final void activityStopped(IBinder token, Bundle icicle, 5491 PersistableBundle persistentState, CharSequence description) { 5492 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5493 5494 // Refuse possible leaked file descriptors 5495 if (icicle != null && icicle.hasFileDescriptors()) { 5496 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5497 } 5498 5499 final long origId = Binder.clearCallingIdentity(); 5500 5501 synchronized (this) { 5502 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5503 if (r != null) { 5504 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5505 } 5506 } 5507 5508 trimApplications(); 5509 5510 Binder.restoreCallingIdentity(origId); 5511 } 5512 5513 @Override 5514 public final void activityDestroyed(IBinder token) { 5515 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5516 synchronized (this) { 5517 ActivityStack stack = ActivityRecord.getStackLocked(token); 5518 if (stack != null) { 5519 stack.activityDestroyedLocked(token); 5520 } 5521 } 5522 } 5523 5524 @Override 5525 public String getCallingPackage(IBinder token) { 5526 synchronized (this) { 5527 ActivityRecord r = getCallingRecordLocked(token); 5528 return r != null ? r.info.packageName : null; 5529 } 5530 } 5531 5532 @Override 5533 public ComponentName getCallingActivity(IBinder token) { 5534 synchronized (this) { 5535 ActivityRecord r = getCallingRecordLocked(token); 5536 return r != null ? r.intent.getComponent() : null; 5537 } 5538 } 5539 5540 private ActivityRecord getCallingRecordLocked(IBinder token) { 5541 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5542 if (r == null) { 5543 return null; 5544 } 5545 return r.resultTo; 5546 } 5547 5548 @Override 5549 public ComponentName getActivityClassForToken(IBinder token) { 5550 synchronized(this) { 5551 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5552 if (r == null) { 5553 return null; 5554 } 5555 return r.intent.getComponent(); 5556 } 5557 } 5558 5559 @Override 5560 public String getPackageForToken(IBinder token) { 5561 synchronized(this) { 5562 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5563 if (r == null) { 5564 return null; 5565 } 5566 return r.packageName; 5567 } 5568 } 5569 5570 @Override 5571 public IIntentSender getIntentSender(int type, 5572 String packageName, IBinder token, String resultWho, 5573 int requestCode, Intent[] intents, String[] resolvedTypes, 5574 int flags, Bundle options, int userId) { 5575 enforceNotIsolatedCaller("getIntentSender"); 5576 // Refuse possible leaked file descriptors 5577 if (intents != null) { 5578 if (intents.length < 1) { 5579 throw new IllegalArgumentException("Intents array length must be >= 1"); 5580 } 5581 for (int i=0; i<intents.length; i++) { 5582 Intent intent = intents[i]; 5583 if (intent != null) { 5584 if (intent.hasFileDescriptors()) { 5585 throw new IllegalArgumentException("File descriptors passed in Intent"); 5586 } 5587 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5588 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5589 throw new IllegalArgumentException( 5590 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5591 } 5592 intents[i] = new Intent(intent); 5593 } 5594 } 5595 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5596 throw new IllegalArgumentException( 5597 "Intent array length does not match resolvedTypes length"); 5598 } 5599 } 5600 if (options != null) { 5601 if (options.hasFileDescriptors()) { 5602 throw new IllegalArgumentException("File descriptors passed in options"); 5603 } 5604 } 5605 5606 synchronized(this) { 5607 int callingUid = Binder.getCallingUid(); 5608 int origUserId = userId; 5609 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5610 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5611 "getIntentSender", null); 5612 if (origUserId == UserHandle.USER_CURRENT) { 5613 // We don't want to evaluate this until the pending intent is 5614 // actually executed. However, we do want to always do the 5615 // security checking for it above. 5616 userId = UserHandle.USER_CURRENT; 5617 } 5618 try { 5619 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5620 int uid = AppGlobals.getPackageManager() 5621 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5622 if (!UserHandle.isSameApp(callingUid, uid)) { 5623 String msg = "Permission Denial: getIntentSender() from pid=" 5624 + Binder.getCallingPid() 5625 + ", uid=" + Binder.getCallingUid() 5626 + ", (need uid=" + uid + ")" 5627 + " is not allowed to send as package " + packageName; 5628 Slog.w(TAG, msg); 5629 throw new SecurityException(msg); 5630 } 5631 } 5632 5633 return getIntentSenderLocked(type, packageName, callingUid, userId, 5634 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5635 5636 } catch (RemoteException e) { 5637 throw new SecurityException(e); 5638 } 5639 } 5640 } 5641 5642 IIntentSender getIntentSenderLocked(int type, String packageName, 5643 int callingUid, int userId, IBinder token, String resultWho, 5644 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5645 Bundle options) { 5646 if (DEBUG_MU) 5647 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5648 ActivityRecord activity = null; 5649 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5650 activity = ActivityRecord.isInStackLocked(token); 5651 if (activity == null) { 5652 return null; 5653 } 5654 if (activity.finishing) { 5655 return null; 5656 } 5657 } 5658 5659 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5660 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5661 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5662 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5663 |PendingIntent.FLAG_UPDATE_CURRENT); 5664 5665 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5666 type, packageName, activity, resultWho, 5667 requestCode, intents, resolvedTypes, flags, options, userId); 5668 WeakReference<PendingIntentRecord> ref; 5669 ref = mIntentSenderRecords.get(key); 5670 PendingIntentRecord rec = ref != null ? ref.get() : null; 5671 if (rec != null) { 5672 if (!cancelCurrent) { 5673 if (updateCurrent) { 5674 if (rec.key.requestIntent != null) { 5675 rec.key.requestIntent.replaceExtras(intents != null ? 5676 intents[intents.length - 1] : null); 5677 } 5678 if (intents != null) { 5679 intents[intents.length-1] = rec.key.requestIntent; 5680 rec.key.allIntents = intents; 5681 rec.key.allResolvedTypes = resolvedTypes; 5682 } else { 5683 rec.key.allIntents = null; 5684 rec.key.allResolvedTypes = null; 5685 } 5686 } 5687 return rec; 5688 } 5689 rec.canceled = true; 5690 mIntentSenderRecords.remove(key); 5691 } 5692 if (noCreate) { 5693 return rec; 5694 } 5695 rec = new PendingIntentRecord(this, key, callingUid); 5696 mIntentSenderRecords.put(key, rec.ref); 5697 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5698 if (activity.pendingResults == null) { 5699 activity.pendingResults 5700 = new HashSet<WeakReference<PendingIntentRecord>>(); 5701 } 5702 activity.pendingResults.add(rec.ref); 5703 } 5704 return rec; 5705 } 5706 5707 @Override 5708 public void cancelIntentSender(IIntentSender sender) { 5709 if (!(sender instanceof PendingIntentRecord)) { 5710 return; 5711 } 5712 synchronized(this) { 5713 PendingIntentRecord rec = (PendingIntentRecord)sender; 5714 try { 5715 int uid = AppGlobals.getPackageManager() 5716 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5717 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5718 String msg = "Permission Denial: cancelIntentSender() from pid=" 5719 + Binder.getCallingPid() 5720 + ", uid=" + Binder.getCallingUid() 5721 + " is not allowed to cancel packges " 5722 + rec.key.packageName; 5723 Slog.w(TAG, msg); 5724 throw new SecurityException(msg); 5725 } 5726 } catch (RemoteException e) { 5727 throw new SecurityException(e); 5728 } 5729 cancelIntentSenderLocked(rec, true); 5730 } 5731 } 5732 5733 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5734 rec.canceled = true; 5735 mIntentSenderRecords.remove(rec.key); 5736 if (cleanActivity && rec.key.activity != null) { 5737 rec.key.activity.pendingResults.remove(rec.ref); 5738 } 5739 } 5740 5741 @Override 5742 public String getPackageForIntentSender(IIntentSender pendingResult) { 5743 if (!(pendingResult instanceof PendingIntentRecord)) { 5744 return null; 5745 } 5746 try { 5747 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5748 return res.key.packageName; 5749 } catch (ClassCastException e) { 5750 } 5751 return null; 5752 } 5753 5754 @Override 5755 public int getUidForIntentSender(IIntentSender sender) { 5756 if (sender instanceof PendingIntentRecord) { 5757 try { 5758 PendingIntentRecord res = (PendingIntentRecord)sender; 5759 return res.uid; 5760 } catch (ClassCastException e) { 5761 } 5762 } 5763 return -1; 5764 } 5765 5766 @Override 5767 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5768 if (!(pendingResult instanceof PendingIntentRecord)) { 5769 return false; 5770 } 5771 try { 5772 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5773 if (res.key.allIntents == null) { 5774 return false; 5775 } 5776 for (int i=0; i<res.key.allIntents.length; i++) { 5777 Intent intent = res.key.allIntents[i]; 5778 if (intent.getPackage() != null && intent.getComponent() != null) { 5779 return false; 5780 } 5781 } 5782 return true; 5783 } catch (ClassCastException e) { 5784 } 5785 return false; 5786 } 5787 5788 @Override 5789 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5790 if (!(pendingResult instanceof PendingIntentRecord)) { 5791 return false; 5792 } 5793 try { 5794 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5795 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5796 return true; 5797 } 5798 return false; 5799 } catch (ClassCastException e) { 5800 } 5801 return false; 5802 } 5803 5804 @Override 5805 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5806 if (!(pendingResult instanceof PendingIntentRecord)) { 5807 return null; 5808 } 5809 try { 5810 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5811 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5812 } catch (ClassCastException e) { 5813 } 5814 return null; 5815 } 5816 5817 @Override 5818 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5819 if (!(pendingResult instanceof PendingIntentRecord)) { 5820 return null; 5821 } 5822 try { 5823 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5824 Intent intent = res.key.requestIntent; 5825 if (intent != null) { 5826 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5827 || res.lastTagPrefix.equals(prefix))) { 5828 return res.lastTag; 5829 } 5830 res.lastTagPrefix = prefix; 5831 StringBuilder sb = new StringBuilder(128); 5832 if (prefix != null) { 5833 sb.append(prefix); 5834 } 5835 if (intent.getAction() != null) { 5836 sb.append(intent.getAction()); 5837 } else if (intent.getComponent() != null) { 5838 intent.getComponent().appendShortString(sb); 5839 } else { 5840 sb.append("?"); 5841 } 5842 return res.lastTag = sb.toString(); 5843 } 5844 } catch (ClassCastException e) { 5845 } 5846 return null; 5847 } 5848 5849 @Override 5850 public void setProcessLimit(int max) { 5851 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5852 "setProcessLimit()"); 5853 synchronized (this) { 5854 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5855 mProcessLimitOverride = max; 5856 } 5857 trimApplications(); 5858 } 5859 5860 @Override 5861 public int getProcessLimit() { 5862 synchronized (this) { 5863 return mProcessLimitOverride; 5864 } 5865 } 5866 5867 void foregroundTokenDied(ForegroundToken token) { 5868 synchronized (ActivityManagerService.this) { 5869 synchronized (mPidsSelfLocked) { 5870 ForegroundToken cur 5871 = mForegroundProcesses.get(token.pid); 5872 if (cur != token) { 5873 return; 5874 } 5875 mForegroundProcesses.remove(token.pid); 5876 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5877 if (pr == null) { 5878 return; 5879 } 5880 pr.forcingToForeground = null; 5881 updateProcessForegroundLocked(pr, false, false); 5882 } 5883 updateOomAdjLocked(); 5884 } 5885 } 5886 5887 @Override 5888 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5889 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5890 "setProcessForeground()"); 5891 synchronized(this) { 5892 boolean changed = false; 5893 5894 synchronized (mPidsSelfLocked) { 5895 ProcessRecord pr = mPidsSelfLocked.get(pid); 5896 if (pr == null && isForeground) { 5897 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5898 return; 5899 } 5900 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5901 if (oldToken != null) { 5902 oldToken.token.unlinkToDeath(oldToken, 0); 5903 mForegroundProcesses.remove(pid); 5904 if (pr != null) { 5905 pr.forcingToForeground = null; 5906 } 5907 changed = true; 5908 } 5909 if (isForeground && token != null) { 5910 ForegroundToken newToken = new ForegroundToken() { 5911 @Override 5912 public void binderDied() { 5913 foregroundTokenDied(this); 5914 } 5915 }; 5916 newToken.pid = pid; 5917 newToken.token = token; 5918 try { 5919 token.linkToDeath(newToken, 0); 5920 mForegroundProcesses.put(pid, newToken); 5921 pr.forcingToForeground = token; 5922 changed = true; 5923 } catch (RemoteException e) { 5924 // If the process died while doing this, we will later 5925 // do the cleanup with the process death link. 5926 } 5927 } 5928 } 5929 5930 if (changed) { 5931 updateOomAdjLocked(); 5932 } 5933 } 5934 } 5935 5936 // ========================================================= 5937 // PERMISSIONS 5938 // ========================================================= 5939 5940 static class PermissionController extends IPermissionController.Stub { 5941 ActivityManagerService mActivityManagerService; 5942 PermissionController(ActivityManagerService activityManagerService) { 5943 mActivityManagerService = activityManagerService; 5944 } 5945 5946 @Override 5947 public boolean checkPermission(String permission, int pid, int uid) { 5948 return mActivityManagerService.checkPermission(permission, pid, 5949 uid) == PackageManager.PERMISSION_GRANTED; 5950 } 5951 } 5952 5953 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5954 @Override 5955 public int checkComponentPermission(String permission, int pid, int uid, 5956 int owningUid, boolean exported) { 5957 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5958 owningUid, exported); 5959 } 5960 5961 @Override 5962 public Object getAMSLock() { 5963 return ActivityManagerService.this; 5964 } 5965 } 5966 5967 /** 5968 * This can be called with or without the global lock held. 5969 */ 5970 int checkComponentPermission(String permission, int pid, int uid, 5971 int owningUid, boolean exported) { 5972 // We might be performing an operation on behalf of an indirect binder 5973 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5974 // client identity accordingly before proceeding. 5975 Identity tlsIdentity = sCallerIdentity.get(); 5976 if (tlsIdentity != null) { 5977 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5978 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5979 uid = tlsIdentity.uid; 5980 pid = tlsIdentity.pid; 5981 } 5982 5983 if (pid == MY_PID) { 5984 return PackageManager.PERMISSION_GRANTED; 5985 } 5986 5987 return ActivityManager.checkComponentPermission(permission, uid, 5988 owningUid, exported); 5989 } 5990 5991 /** 5992 * As the only public entry point for permissions checking, this method 5993 * can enforce the semantic that requesting a check on a null global 5994 * permission is automatically denied. (Internally a null permission 5995 * string is used when calling {@link #checkComponentPermission} in cases 5996 * when only uid-based security is needed.) 5997 * 5998 * This can be called with or without the global lock held. 5999 */ 6000 @Override 6001 public int checkPermission(String permission, int pid, int uid) { 6002 if (permission == null) { 6003 return PackageManager.PERMISSION_DENIED; 6004 } 6005 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6006 } 6007 6008 /** 6009 * Binder IPC calls go through the public entry point. 6010 * This can be called with or without the global lock held. 6011 */ 6012 int checkCallingPermission(String permission) { 6013 return checkPermission(permission, 6014 Binder.getCallingPid(), 6015 UserHandle.getAppId(Binder.getCallingUid())); 6016 } 6017 6018 /** 6019 * This can be called with or without the global lock held. 6020 */ 6021 void enforceCallingPermission(String permission, String func) { 6022 if (checkCallingPermission(permission) 6023 == PackageManager.PERMISSION_GRANTED) { 6024 return; 6025 } 6026 6027 String msg = "Permission Denial: " + func + " from pid=" 6028 + Binder.getCallingPid() 6029 + ", uid=" + Binder.getCallingUid() 6030 + " requires " + permission; 6031 Slog.w(TAG, msg); 6032 throw new SecurityException(msg); 6033 } 6034 6035 /** 6036 * Determine if UID is holding permissions required to access {@link Uri} in 6037 * the given {@link ProviderInfo}. Final permission checking is always done 6038 * in {@link ContentProvider}. 6039 */ 6040 private final boolean checkHoldingPermissionsLocked( 6041 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6043 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6044 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6045 return false; 6046 } 6047 6048 if (pi.applicationInfo.uid == uid) { 6049 return true; 6050 } else if (!pi.exported) { 6051 return false; 6052 } 6053 6054 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6055 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6056 try { 6057 // check if target holds top-level <provider> permissions 6058 if (!readMet && pi.readPermission != null 6059 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6060 readMet = true; 6061 } 6062 if (!writeMet && pi.writePermission != null 6063 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6064 writeMet = true; 6065 } 6066 6067 // track if unprotected read/write is allowed; any denied 6068 // <path-permission> below removes this ability 6069 boolean allowDefaultRead = pi.readPermission == null; 6070 boolean allowDefaultWrite = pi.writePermission == null; 6071 6072 // check if target holds any <path-permission> that match uri 6073 final PathPermission[] pps = pi.pathPermissions; 6074 if (pps != null) { 6075 final String path = grantUri.uri.getPath(); 6076 int i = pps.length; 6077 while (i > 0 && (!readMet || !writeMet)) { 6078 i--; 6079 PathPermission pp = pps[i]; 6080 if (pp.match(path)) { 6081 if (!readMet) { 6082 final String pprperm = pp.getReadPermission(); 6083 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6084 + pprperm + " for " + pp.getPath() 6085 + ": match=" + pp.match(path) 6086 + " check=" + pm.checkUidPermission(pprperm, uid)); 6087 if (pprperm != null) { 6088 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6089 readMet = true; 6090 } else { 6091 allowDefaultRead = false; 6092 } 6093 } 6094 } 6095 if (!writeMet) { 6096 final String ppwperm = pp.getWritePermission(); 6097 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6098 + ppwperm + " for " + pp.getPath() 6099 + ": match=" + pp.match(path) 6100 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6101 if (ppwperm != null) { 6102 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6103 writeMet = true; 6104 } else { 6105 allowDefaultWrite = false; 6106 } 6107 } 6108 } 6109 } 6110 } 6111 } 6112 6113 // grant unprotected <provider> read/write, if not blocked by 6114 // <path-permission> above 6115 if (allowDefaultRead) readMet = true; 6116 if (allowDefaultWrite) writeMet = true; 6117 6118 } catch (RemoteException e) { 6119 return false; 6120 } 6121 6122 return readMet && writeMet; 6123 } 6124 6125 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6126 ProviderInfo pi = null; 6127 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6128 if (cpr != null) { 6129 pi = cpr.info; 6130 } else { 6131 try { 6132 pi = AppGlobals.getPackageManager().resolveContentProvider( 6133 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6134 } catch (RemoteException ex) { 6135 } 6136 } 6137 return pi; 6138 } 6139 6140 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6141 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6142 if (targetUris != null) { 6143 return targetUris.get(grantUri); 6144 } 6145 return null; 6146 } 6147 6148 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6149 String targetPkg, int targetUid, GrantUri grantUri) { 6150 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6151 if (targetUris == null) { 6152 targetUris = Maps.newArrayMap(); 6153 mGrantedUriPermissions.put(targetUid, targetUris); 6154 } 6155 6156 UriPermission perm = targetUris.get(grantUri); 6157 if (perm == null) { 6158 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6159 targetUris.put(grantUri, perm); 6160 } 6161 6162 return perm; 6163 } 6164 6165 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6166 final int modeFlags) { 6167 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6168 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6169 : UriPermission.STRENGTH_OWNED; 6170 6171 // Root gets to do everything. 6172 if (uid == 0) { 6173 return true; 6174 } 6175 6176 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6177 if (perms == null) return false; 6178 6179 // First look for exact match 6180 final UriPermission exactPerm = perms.get(grantUri); 6181 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6182 return true; 6183 } 6184 6185 // No exact match, look for prefixes 6186 final int N = perms.size(); 6187 for (int i = 0; i < N; i++) { 6188 final UriPermission perm = perms.valueAt(i); 6189 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6190 && perm.getStrength(modeFlags) >= minStrength) { 6191 return true; 6192 } 6193 } 6194 6195 return false; 6196 } 6197 6198 @Override 6199 public int checkUriPermission(Uri uri, int pid, int uid, 6200 final int modeFlags, int userId) { 6201 enforceNotIsolatedCaller("checkUriPermission"); 6202 6203 // Another redirected-binder-call permissions check as in 6204 // {@link checkComponentPermission}. 6205 Identity tlsIdentity = sCallerIdentity.get(); 6206 if (tlsIdentity != null) { 6207 uid = tlsIdentity.uid; 6208 pid = tlsIdentity.pid; 6209 } 6210 6211 // Our own process gets to do everything. 6212 if (pid == MY_PID) { 6213 return PackageManager.PERMISSION_GRANTED; 6214 } 6215 synchronized (this) { 6216 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6217 ? PackageManager.PERMISSION_GRANTED 6218 : PackageManager.PERMISSION_DENIED; 6219 } 6220 } 6221 6222 /** 6223 * Check if the targetPkg can be granted permission to access uri by 6224 * the callingUid using the given modeFlags. Throws a security exception 6225 * if callingUid is not allowed to do this. Returns the uid of the target 6226 * if the URI permission grant should be performed; returns -1 if it is not 6227 * needed (for example targetPkg already has permission to access the URI). 6228 * If you already know the uid of the target, you can supply it in 6229 * lastTargetUid else set that to -1. 6230 */ 6231 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6232 final int modeFlags, int lastTargetUid) { 6233 if (!Intent.isAccessUriMode(modeFlags)) { 6234 return -1; 6235 } 6236 6237 if (targetPkg != null) { 6238 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6239 "Checking grant " + targetPkg + " permission to " + grantUri); 6240 } 6241 6242 final IPackageManager pm = AppGlobals.getPackageManager(); 6243 6244 // If this is not a content: uri, we can't do anything with it. 6245 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6246 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6247 "Can't grant URI permission for non-content URI: " + grantUri); 6248 return -1; 6249 } 6250 6251 final String authority = grantUri.uri.getAuthority(); 6252 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6253 if (pi == null) { 6254 Slog.w(TAG, "No content provider found for permission check: " + 6255 grantUri.uri.toSafeString()); 6256 return -1; 6257 } 6258 6259 int targetUid = lastTargetUid; 6260 if (targetUid < 0 && targetPkg != null) { 6261 try { 6262 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6263 if (targetUid < 0) { 6264 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6265 "Can't grant URI permission no uid for: " + targetPkg); 6266 return -1; 6267 } 6268 } catch (RemoteException ex) { 6269 return -1; 6270 } 6271 } 6272 6273 if (targetUid >= 0) { 6274 // First... does the target actually need this permission? 6275 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6276 // No need to grant the target this permission. 6277 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6278 "Target " + targetPkg + " already has full permission to " + grantUri); 6279 return -1; 6280 } 6281 } else { 6282 // First... there is no target package, so can anyone access it? 6283 boolean allowed = pi.exported; 6284 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6285 if (pi.readPermission != null) { 6286 allowed = false; 6287 } 6288 } 6289 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6290 if (pi.writePermission != null) { 6291 allowed = false; 6292 } 6293 } 6294 if (allowed) { 6295 return -1; 6296 } 6297 } 6298 6299 // Second... is the provider allowing granting of URI permissions? 6300 if (!pi.grantUriPermissions) { 6301 throw new SecurityException("Provider " + pi.packageName 6302 + "/" + pi.name 6303 + " does not allow granting of Uri permissions (uri " 6304 + grantUri + ")"); 6305 } 6306 if (pi.uriPermissionPatterns != null) { 6307 final int N = pi.uriPermissionPatterns.length; 6308 boolean allowed = false; 6309 for (int i=0; i<N; i++) { 6310 if (pi.uriPermissionPatterns[i] != null 6311 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6312 allowed = true; 6313 break; 6314 } 6315 } 6316 if (!allowed) { 6317 throw new SecurityException("Provider " + pi.packageName 6318 + "/" + pi.name 6319 + " does not allow granting of permission to path of Uri " 6320 + grantUri); 6321 } 6322 } 6323 6324 // Third... does the caller itself have permission to access 6325 // this uri? 6326 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6327 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6328 // Require they hold a strong enough Uri permission 6329 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6330 throw new SecurityException("Uid " + callingUid 6331 + " does not have permission to uri " + grantUri); 6332 } 6333 } 6334 } 6335 return targetUid; 6336 } 6337 6338 @Override 6339 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6340 final int modeFlags, int userId) { 6341 enforceNotIsolatedCaller("checkGrantUriPermission"); 6342 synchronized(this) { 6343 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6344 new GrantUri(userId, uri, false), modeFlags, -1); 6345 } 6346 } 6347 6348 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6349 final int modeFlags, UriPermissionOwner owner) { 6350 if (!Intent.isAccessUriMode(modeFlags)) { 6351 return; 6352 } 6353 6354 // So here we are: the caller has the assumed permission 6355 // to the uri, and the target doesn't. Let's now give this to 6356 // the target. 6357 6358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6359 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6360 6361 final String authority = grantUri.uri.getAuthority(); 6362 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6363 if (pi == null) { 6364 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6365 return; 6366 } 6367 6368 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6369 grantUri.prefix = true; 6370 } 6371 final UriPermission perm = findOrCreateUriPermissionLocked( 6372 pi.packageName, targetPkg, targetUid, grantUri); 6373 perm.grantModes(modeFlags, owner); 6374 } 6375 6376 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6377 final int modeFlags, UriPermissionOwner owner) { 6378 if (targetPkg == null) { 6379 throw new NullPointerException("targetPkg"); 6380 } 6381 6382 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6383 -1); 6384 if (targetUid < 0) { 6385 return; 6386 } 6387 6388 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6389 owner); 6390 } 6391 6392 static class NeededUriGrants extends ArrayList<GrantUri> { 6393 final String targetPkg; 6394 final int targetUid; 6395 final int flags; 6396 6397 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6398 this.targetPkg = targetPkg; 6399 this.targetUid = targetUid; 6400 this.flags = flags; 6401 } 6402 } 6403 6404 /** 6405 * Like checkGrantUriPermissionLocked, but takes an Intent. 6406 */ 6407 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6408 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6409 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6410 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6411 + " clip=" + (intent != null ? intent.getClipData() : null) 6412 + " from " + intent + "; flags=0x" 6413 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6414 6415 if (targetPkg == null) { 6416 throw new NullPointerException("targetPkg"); 6417 } 6418 6419 if (intent == null) { 6420 return null; 6421 } 6422 Uri data = intent.getData(); 6423 ClipData clip = intent.getClipData(); 6424 if (data == null && clip == null) { 6425 return null; 6426 } 6427 final IPackageManager pm = AppGlobals.getPackageManager(); 6428 int targetUid; 6429 if (needed != null) { 6430 targetUid = needed.targetUid; 6431 } else { 6432 try { 6433 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6434 } catch (RemoteException ex) { 6435 return null; 6436 } 6437 if (targetUid < 0) { 6438 if (DEBUG_URI_PERMISSION) { 6439 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6440 + " on user " + targetUserId); 6441 } 6442 return null; 6443 } 6444 } 6445 if (data != null) { 6446 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6447 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6448 targetUid); 6449 if (targetUid > 0) { 6450 if (needed == null) { 6451 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6452 } 6453 needed.add(grantUri); 6454 } 6455 } 6456 if (clip != null) { 6457 for (int i=0; i<clip.getItemCount(); i++) { 6458 Uri uri = clip.getItemAt(i).getUri(); 6459 if (uri != null) { 6460 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6461 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6462 targetUid); 6463 if (targetUid > 0) { 6464 if (needed == null) { 6465 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6466 } 6467 needed.add(grantUri); 6468 } 6469 } else { 6470 Intent clipIntent = clip.getItemAt(i).getIntent(); 6471 if (clipIntent != null) { 6472 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6473 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6474 if (newNeeded != null) { 6475 needed = newNeeded; 6476 } 6477 } 6478 } 6479 } 6480 } 6481 6482 return needed; 6483 } 6484 6485 /** 6486 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6487 */ 6488 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6489 UriPermissionOwner owner) { 6490 if (needed != null) { 6491 for (int i=0; i<needed.size(); i++) { 6492 GrantUri grantUri = needed.get(i); 6493 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6494 grantUri, needed.flags, owner); 6495 } 6496 } 6497 } 6498 6499 void grantUriPermissionFromIntentLocked(int callingUid, 6500 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6501 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6502 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6503 if (needed == null) { 6504 return; 6505 } 6506 6507 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6508 } 6509 6510 @Override 6511 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6512 final int modeFlags, int userId) { 6513 enforceNotIsolatedCaller("grantUriPermission"); 6514 GrantUri grantUri = new GrantUri(userId, uri, false); 6515 synchronized(this) { 6516 final ProcessRecord r = getRecordForAppLocked(caller); 6517 if (r == null) { 6518 throw new SecurityException("Unable to find app for caller " 6519 + caller 6520 + " when granting permission to uri " + grantUri); 6521 } 6522 if (targetPkg == null) { 6523 throw new IllegalArgumentException("null target"); 6524 } 6525 if (grantUri == null) { 6526 throw new IllegalArgumentException("null uri"); 6527 } 6528 6529 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6530 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6531 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6532 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6533 6534 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6535 } 6536 } 6537 6538 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6539 if (perm.modeFlags == 0) { 6540 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6541 perm.targetUid); 6542 if (perms != null) { 6543 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6544 "Removing " + perm.targetUid + " permission to " + perm.uri); 6545 6546 perms.remove(perm.uri); 6547 if (perms.isEmpty()) { 6548 mGrantedUriPermissions.remove(perm.targetUid); 6549 } 6550 } 6551 } 6552 } 6553 6554 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6555 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6556 6557 final IPackageManager pm = AppGlobals.getPackageManager(); 6558 final String authority = grantUri.uri.getAuthority(); 6559 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6560 if (pi == null) { 6561 Slog.w(TAG, "No content provider found for permission revoke: " 6562 + grantUri.toSafeString()); 6563 return; 6564 } 6565 6566 // Does the caller have this permission on the URI? 6567 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6568 // Right now, if you are not the original owner of the permission, 6569 // you are not allowed to revoke it. 6570 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6571 throw new SecurityException("Uid " + callingUid 6572 + " does not have permission to uri " + grantUri); 6573 //} 6574 } 6575 6576 boolean persistChanged = false; 6577 6578 // Go through all of the permissions and remove any that match. 6579 int N = mGrantedUriPermissions.size(); 6580 for (int i = 0; i < N; i++) { 6581 final int targetUid = mGrantedUriPermissions.keyAt(i); 6582 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6583 6584 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6585 final UriPermission perm = it.next(); 6586 if (perm.uri.sourceUserId == grantUri.sourceUserId 6587 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6588 if (DEBUG_URI_PERMISSION) 6589 Slog.v(TAG, 6590 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6591 persistChanged |= perm.revokeModes( 6592 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6593 if (perm.modeFlags == 0) { 6594 it.remove(); 6595 } 6596 } 6597 } 6598 6599 if (perms.isEmpty()) { 6600 mGrantedUriPermissions.remove(targetUid); 6601 N--; 6602 i--; 6603 } 6604 } 6605 6606 if (persistChanged) { 6607 schedulePersistUriGrants(); 6608 } 6609 } 6610 6611 @Override 6612 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6613 int userId) { 6614 enforceNotIsolatedCaller("revokeUriPermission"); 6615 synchronized(this) { 6616 final ProcessRecord r = getRecordForAppLocked(caller); 6617 if (r == null) { 6618 throw new SecurityException("Unable to find app for caller " 6619 + caller 6620 + " when revoking permission to uri " + uri); 6621 } 6622 if (uri == null) { 6623 Slog.w(TAG, "revokeUriPermission: null uri"); 6624 return; 6625 } 6626 6627 if (!Intent.isAccessUriMode(modeFlags)) { 6628 return; 6629 } 6630 6631 final IPackageManager pm = AppGlobals.getPackageManager(); 6632 final String authority = uri.getAuthority(); 6633 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6634 if (pi == null) { 6635 Slog.w(TAG, "No content provider found for permission revoke: " 6636 + uri.toSafeString()); 6637 return; 6638 } 6639 6640 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6641 } 6642 } 6643 6644 /** 6645 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6646 * given package. 6647 * 6648 * @param packageName Package name to match, or {@code null} to apply to all 6649 * packages. 6650 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6651 * to all users. 6652 * @param persistable If persistable grants should be removed. 6653 */ 6654 private void removeUriPermissionsForPackageLocked( 6655 String packageName, int userHandle, boolean persistable) { 6656 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6657 throw new IllegalArgumentException("Must narrow by either package or user"); 6658 } 6659 6660 boolean persistChanged = false; 6661 6662 int N = mGrantedUriPermissions.size(); 6663 for (int i = 0; i < N; i++) { 6664 final int targetUid = mGrantedUriPermissions.keyAt(i); 6665 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6666 6667 // Only inspect grants matching user 6668 if (userHandle == UserHandle.USER_ALL 6669 || userHandle == UserHandle.getUserId(targetUid)) { 6670 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6671 final UriPermission perm = it.next(); 6672 6673 // Only inspect grants matching package 6674 if (packageName == null || perm.sourcePkg.equals(packageName) 6675 || perm.targetPkg.equals(packageName)) { 6676 persistChanged |= perm.revokeModes( 6677 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6678 6679 // Only remove when no modes remain; any persisted grants 6680 // will keep this alive. 6681 if (perm.modeFlags == 0) { 6682 it.remove(); 6683 } 6684 } 6685 } 6686 6687 if (perms.isEmpty()) { 6688 mGrantedUriPermissions.remove(targetUid); 6689 N--; 6690 i--; 6691 } 6692 } 6693 } 6694 6695 if (persistChanged) { 6696 schedulePersistUriGrants(); 6697 } 6698 } 6699 6700 @Override 6701 public IBinder newUriPermissionOwner(String name) { 6702 enforceNotIsolatedCaller("newUriPermissionOwner"); 6703 synchronized(this) { 6704 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6705 return owner.getExternalTokenLocked(); 6706 } 6707 } 6708 6709 @Override 6710 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6711 final int modeFlags, int userId) { 6712 synchronized(this) { 6713 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6714 if (owner == null) { 6715 throw new IllegalArgumentException("Unknown owner: " + token); 6716 } 6717 if (fromUid != Binder.getCallingUid()) { 6718 if (Binder.getCallingUid() != Process.myUid()) { 6719 // Only system code can grant URI permissions on behalf 6720 // of other users. 6721 throw new SecurityException("nice try"); 6722 } 6723 } 6724 if (targetPkg == null) { 6725 throw new IllegalArgumentException("null target"); 6726 } 6727 if (uri == null) { 6728 throw new IllegalArgumentException("null uri"); 6729 } 6730 6731 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6732 modeFlags, owner); 6733 } 6734 } 6735 6736 @Override 6737 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6738 synchronized(this) { 6739 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6740 if (owner == null) { 6741 throw new IllegalArgumentException("Unknown owner: " + token); 6742 } 6743 6744 if (uri == null) { 6745 owner.removeUriPermissionsLocked(mode); 6746 } else { 6747 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6748 } 6749 } 6750 } 6751 6752 private void schedulePersistUriGrants() { 6753 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6754 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6755 10 * DateUtils.SECOND_IN_MILLIS); 6756 } 6757 } 6758 6759 private void writeGrantedUriPermissions() { 6760 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6761 6762 // Snapshot permissions so we can persist without lock 6763 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6764 synchronized (this) { 6765 final int size = mGrantedUriPermissions.size(); 6766 for (int i = 0; i < size; i++) { 6767 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6768 for (UriPermission perm : perms.values()) { 6769 if (perm.persistedModeFlags != 0) { 6770 persist.add(perm.snapshot()); 6771 } 6772 } 6773 } 6774 } 6775 6776 FileOutputStream fos = null; 6777 try { 6778 fos = mGrantFile.startWrite(); 6779 6780 XmlSerializer out = new FastXmlSerializer(); 6781 out.setOutput(fos, "utf-8"); 6782 out.startDocument(null, true); 6783 out.startTag(null, TAG_URI_GRANTS); 6784 for (UriPermission.Snapshot perm : persist) { 6785 out.startTag(null, TAG_URI_GRANT); 6786 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6787 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6788 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6789 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6790 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6791 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6792 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6793 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6794 out.endTag(null, TAG_URI_GRANT); 6795 } 6796 out.endTag(null, TAG_URI_GRANTS); 6797 out.endDocument(); 6798 6799 mGrantFile.finishWrite(fos); 6800 } catch (IOException e) { 6801 if (fos != null) { 6802 mGrantFile.failWrite(fos); 6803 } 6804 } 6805 } 6806 6807 private void readGrantedUriPermissionsLocked() { 6808 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6809 6810 final long now = System.currentTimeMillis(); 6811 6812 FileInputStream fis = null; 6813 try { 6814 fis = mGrantFile.openRead(); 6815 final XmlPullParser in = Xml.newPullParser(); 6816 in.setInput(fis, null); 6817 6818 int type; 6819 while ((type = in.next()) != END_DOCUMENT) { 6820 final String tag = in.getName(); 6821 if (type == START_TAG) { 6822 if (TAG_URI_GRANT.equals(tag)) { 6823 final int sourceUserId; 6824 final int targetUserId; 6825 final int userHandle = readIntAttribute(in, 6826 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6827 if (userHandle != UserHandle.USER_NULL) { 6828 // For backwards compatibility. 6829 sourceUserId = userHandle; 6830 targetUserId = userHandle; 6831 } else { 6832 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6833 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6834 } 6835 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6836 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6837 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6838 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6839 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6840 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6841 6842 // Sanity check that provider still belongs to source package 6843 final ProviderInfo pi = getProviderInfoLocked( 6844 uri.getAuthority(), sourceUserId); 6845 if (pi != null && sourcePkg.equals(pi.packageName)) { 6846 int targetUid = -1; 6847 try { 6848 targetUid = AppGlobals.getPackageManager() 6849 .getPackageUid(targetPkg, targetUserId); 6850 } catch (RemoteException e) { 6851 } 6852 if (targetUid != -1) { 6853 final UriPermission perm = findOrCreateUriPermissionLocked( 6854 sourcePkg, targetPkg, targetUid, 6855 new GrantUri(sourceUserId, uri, prefix)); 6856 perm.initPersistedModes(modeFlags, createdTime); 6857 } 6858 } else { 6859 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6860 + " but instead found " + pi); 6861 } 6862 } 6863 } 6864 } 6865 } catch (FileNotFoundException e) { 6866 // Missing grants is okay 6867 } catch (IOException e) { 6868 Log.wtf(TAG, "Failed reading Uri grants", e); 6869 } catch (XmlPullParserException e) { 6870 Log.wtf(TAG, "Failed reading Uri grants", e); 6871 } finally { 6872 IoUtils.closeQuietly(fis); 6873 } 6874 } 6875 6876 @Override 6877 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6878 enforceNotIsolatedCaller("takePersistableUriPermission"); 6879 6880 Preconditions.checkFlagsArgument(modeFlags, 6881 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6882 6883 synchronized (this) { 6884 final int callingUid = Binder.getCallingUid(); 6885 boolean persistChanged = false; 6886 GrantUri grantUri = new GrantUri(userId, uri, false); 6887 6888 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6889 new GrantUri(userId, uri, false)); 6890 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6891 new GrantUri(userId, uri, true)); 6892 6893 final boolean exactValid = (exactPerm != null) 6894 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6895 final boolean prefixValid = (prefixPerm != null) 6896 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6897 6898 if (!(exactValid || prefixValid)) { 6899 throw new SecurityException("No persistable permission grants found for UID " 6900 + callingUid + " and Uri " + grantUri.toSafeString()); 6901 } 6902 6903 if (exactValid) { 6904 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6905 } 6906 if (prefixValid) { 6907 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6908 } 6909 6910 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6911 6912 if (persistChanged) { 6913 schedulePersistUriGrants(); 6914 } 6915 } 6916 } 6917 6918 @Override 6919 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6920 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6921 6922 Preconditions.checkFlagsArgument(modeFlags, 6923 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6924 6925 synchronized (this) { 6926 final int callingUid = Binder.getCallingUid(); 6927 boolean persistChanged = false; 6928 6929 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6930 new GrantUri(userId, uri, false)); 6931 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6932 new GrantUri(userId, uri, true)); 6933 if (exactPerm == null && prefixPerm == null) { 6934 throw new SecurityException("No permission grants found for UID " + callingUid 6935 + " and Uri " + uri.toSafeString()); 6936 } 6937 6938 if (exactPerm != null) { 6939 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6940 removeUriPermissionIfNeededLocked(exactPerm); 6941 } 6942 if (prefixPerm != null) { 6943 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6944 removeUriPermissionIfNeededLocked(prefixPerm); 6945 } 6946 6947 if (persistChanged) { 6948 schedulePersistUriGrants(); 6949 } 6950 } 6951 } 6952 6953 /** 6954 * Prune any older {@link UriPermission} for the given UID until outstanding 6955 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6956 * 6957 * @return if any mutations occured that require persisting. 6958 */ 6959 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6961 if (perms == null) return false; 6962 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6963 6964 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6965 for (UriPermission perm : perms.values()) { 6966 if (perm.persistedModeFlags != 0) { 6967 persisted.add(perm); 6968 } 6969 } 6970 6971 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6972 if (trimCount <= 0) return false; 6973 6974 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6975 for (int i = 0; i < trimCount; i++) { 6976 final UriPermission perm = persisted.get(i); 6977 6978 if (DEBUG_URI_PERMISSION) { 6979 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6980 } 6981 6982 perm.releasePersistableModes(~0); 6983 removeUriPermissionIfNeededLocked(perm); 6984 } 6985 6986 return true; 6987 } 6988 6989 @Override 6990 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6991 String packageName, boolean incoming) { 6992 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6993 Preconditions.checkNotNull(packageName, "packageName"); 6994 6995 final int callingUid = Binder.getCallingUid(); 6996 final IPackageManager pm = AppGlobals.getPackageManager(); 6997 try { 6998 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6999 if (packageUid != callingUid) { 7000 throw new SecurityException( 7001 "Package " + packageName + " does not belong to calling UID " + callingUid); 7002 } 7003 } catch (RemoteException e) { 7004 throw new SecurityException("Failed to verify package name ownership"); 7005 } 7006 7007 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7008 synchronized (this) { 7009 if (incoming) { 7010 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7011 callingUid); 7012 if (perms == null) { 7013 Slog.w(TAG, "No permission grants found for " + packageName); 7014 } else { 7015 for (UriPermission perm : perms.values()) { 7016 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7017 result.add(perm.buildPersistedPublicApiObject()); 7018 } 7019 } 7020 } 7021 } else { 7022 final int size = mGrantedUriPermissions.size(); 7023 for (int i = 0; i < size; i++) { 7024 final ArrayMap<GrantUri, UriPermission> perms = 7025 mGrantedUriPermissions.valueAt(i); 7026 for (UriPermission perm : perms.values()) { 7027 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7028 result.add(perm.buildPersistedPublicApiObject()); 7029 } 7030 } 7031 } 7032 } 7033 } 7034 return new ParceledListSlice<android.content.UriPermission>(result); 7035 } 7036 7037 @Override 7038 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7039 synchronized (this) { 7040 ProcessRecord app = 7041 who != null ? getRecordForAppLocked(who) : null; 7042 if (app == null) return; 7043 7044 Message msg = Message.obtain(); 7045 msg.what = WAIT_FOR_DEBUGGER_MSG; 7046 msg.obj = app; 7047 msg.arg1 = waiting ? 1 : 0; 7048 mHandler.sendMessage(msg); 7049 } 7050 } 7051 7052 @Override 7053 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7054 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7055 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7056 outInfo.availMem = Process.getFreeMemory(); 7057 outInfo.totalMem = Process.getTotalMemory(); 7058 outInfo.threshold = homeAppMem; 7059 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7060 outInfo.hiddenAppThreshold = cachedAppMem; 7061 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7062 ProcessList.SERVICE_ADJ); 7063 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7064 ProcessList.VISIBLE_APP_ADJ); 7065 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7066 ProcessList.FOREGROUND_APP_ADJ); 7067 } 7068 7069 // ========================================================= 7070 // TASK MANAGEMENT 7071 // ========================================================= 7072 7073 @Override 7074 public List<IAppTask> getAppTasks() { 7075 int callingUid = Binder.getCallingUid(); 7076 long ident = Binder.clearCallingIdentity(); 7077 synchronized(this) { 7078 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7079 try { 7080 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7081 7082 final int N = mRecentTasks.size(); 7083 for (int i = 0; i < N; i++) { 7084 TaskRecord tr = mRecentTasks.get(i); 7085 // Skip tasks that are not created by the caller 7086 if (tr.creatorUid == callingUid) { 7087 ActivityManager.RecentTaskInfo taskInfo = 7088 createRecentTaskInfoFromTaskRecord(tr); 7089 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7090 list.add(taskImpl); 7091 } 7092 } 7093 } finally { 7094 Binder.restoreCallingIdentity(ident); 7095 } 7096 return list; 7097 } 7098 } 7099 7100 @Override 7101 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7102 final int callingUid = Binder.getCallingUid(); 7103 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7104 7105 synchronized(this) { 7106 if (localLOGV) Slog.v( 7107 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7108 7109 final boolean allowed = checkCallingPermission( 7110 android.Manifest.permission.GET_TASKS) 7111 == PackageManager.PERMISSION_GRANTED; 7112 if (!allowed) { 7113 Slog.w(TAG, "getTasks: caller " + callingUid 7114 + " does not hold GET_TASKS; limiting output"); 7115 } 7116 7117 // TODO: Improve with MRU list from all ActivityStacks. 7118 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7119 } 7120 7121 return list; 7122 } 7123 7124 TaskRecord getMostRecentTask() { 7125 return mRecentTasks.get(0); 7126 } 7127 7128 /** 7129 * Creates a new RecentTaskInfo from a TaskRecord. 7130 */ 7131 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7132 // Update the task description to reflect any changes in the task stack 7133 tr.updateTaskDescription(); 7134 7135 // Compose the recent task info 7136 ActivityManager.RecentTaskInfo rti 7137 = new ActivityManager.RecentTaskInfo(); 7138 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7139 rti.persistentId = tr.taskId; 7140 rti.baseIntent = new Intent(tr.getBaseIntent()); 7141 rti.origActivity = tr.origActivity; 7142 rti.description = tr.lastDescription; 7143 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7144 rti.userId = tr.userId; 7145 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7146 return rti; 7147 } 7148 7149 @Override 7150 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7151 int flags, int userId) { 7152 final int callingUid = Binder.getCallingUid(); 7153 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7154 false, true, "getRecentTasks", null); 7155 7156 synchronized (this) { 7157 final boolean allowed = checkCallingPermission( 7158 android.Manifest.permission.GET_TASKS) 7159 == PackageManager.PERMISSION_GRANTED; 7160 if (!allowed) { 7161 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7162 + " does not hold GET_TASKS; limiting output"); 7163 } 7164 final boolean detailed = checkCallingPermission( 7165 android.Manifest.permission.GET_DETAILED_TASKS) 7166 == PackageManager.PERMISSION_GRANTED; 7167 7168 IPackageManager pm = AppGlobals.getPackageManager(); 7169 7170 final int N = mRecentTasks.size(); 7171 ArrayList<ActivityManager.RecentTaskInfo> res 7172 = new ArrayList<ActivityManager.RecentTaskInfo>( 7173 maxNum < N ? maxNum : N); 7174 7175 final Set<Integer> includedUsers; 7176 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7177 includedUsers = getProfileIdsLocked(userId); 7178 } else { 7179 includedUsers = new HashSet<Integer>(); 7180 } 7181 includedUsers.add(Integer.valueOf(userId)); 7182 for (int i=0; i<N && maxNum > 0; i++) { 7183 TaskRecord tr = mRecentTasks.get(i); 7184 // Only add calling user or related users recent tasks 7185 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7186 7187 // Return the entry if desired by the caller. We always return 7188 // the first entry, because callers always expect this to be the 7189 // foreground app. We may filter others if the caller has 7190 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7191 // we should exclude the entry. 7192 7193 if (i == 0 7194 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7195 || (tr.intent == null) 7196 || ((tr.intent.getFlags() 7197 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7198 if (!allowed) { 7199 // If the caller doesn't have the GET_TASKS permission, then only 7200 // allow them to see a small subset of tasks -- their own and home. 7201 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7202 continue; 7203 } 7204 } 7205 7206 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7207 if (!detailed) { 7208 rti.baseIntent.replaceExtras((Bundle)null); 7209 } 7210 7211 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7212 // Check whether this activity is currently available. 7213 try { 7214 if (rti.origActivity != null) { 7215 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7216 == null) { 7217 continue; 7218 } 7219 } else if (rti.baseIntent != null) { 7220 if (pm.queryIntentActivities(rti.baseIntent, 7221 null, 0, userId) == null) { 7222 continue; 7223 } 7224 } 7225 } catch (RemoteException e) { 7226 // Will never happen. 7227 } 7228 } 7229 7230 res.add(rti); 7231 maxNum--; 7232 } 7233 } 7234 return res; 7235 } 7236 } 7237 7238 private TaskRecord recentTaskForIdLocked(int id) { 7239 final int N = mRecentTasks.size(); 7240 for (int i=0; i<N; i++) { 7241 TaskRecord tr = mRecentTasks.get(i); 7242 if (tr.taskId == id) { 7243 return tr; 7244 } 7245 } 7246 return null; 7247 } 7248 7249 @Override 7250 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7251 synchronized (this) { 7252 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7253 "getTaskThumbnails()"); 7254 TaskRecord tr = recentTaskForIdLocked(id); 7255 if (tr != null) { 7256 return tr.getTaskThumbnailsLocked(); 7257 } 7258 } 7259 return null; 7260 } 7261 7262 @Override 7263 public Bitmap getTaskTopThumbnail(int id) { 7264 synchronized (this) { 7265 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7266 "getTaskTopThumbnail()"); 7267 TaskRecord tr = recentTaskForIdLocked(id); 7268 if (tr != null) { 7269 return tr.getTaskTopThumbnailLocked(); 7270 } 7271 } 7272 return null; 7273 } 7274 7275 @Override 7276 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7277 synchronized (this) { 7278 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7279 if (r != null) { 7280 r.taskDescription = td; 7281 r.task.updateTaskDescription(); 7282 } 7283 } 7284 } 7285 7286 @Override 7287 public boolean removeSubTask(int taskId, int subTaskIndex) { 7288 synchronized (this) { 7289 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7290 "removeSubTask()"); 7291 long ident = Binder.clearCallingIdentity(); 7292 try { 7293 TaskRecord tr = recentTaskForIdLocked(taskId); 7294 if (tr != null) { 7295 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7296 } 7297 return false; 7298 } finally { 7299 Binder.restoreCallingIdentity(ident); 7300 } 7301 } 7302 } 7303 7304 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7305 if (!pr.killedByAm) { 7306 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7307 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7308 pr.processName, pr.setAdj, reason); 7309 pr.killedByAm = true; 7310 Process.killProcessQuiet(pr.pid); 7311 } 7312 } 7313 7314 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7315 tr.disposeThumbnail(); 7316 mRecentTasks.remove(tr); 7317 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7318 Intent baseIntent = new Intent( 7319 tr.intent != null ? tr.intent : tr.affinityIntent); 7320 ComponentName component = baseIntent.getComponent(); 7321 if (component == null) { 7322 Slog.w(TAG, "Now component for base intent of task: " + tr); 7323 return; 7324 } 7325 7326 // Find any running services associated with this app. 7327 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7328 7329 if (killProcesses) { 7330 // Find any running processes associated with this app. 7331 final String pkg = component.getPackageName(); 7332 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7333 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7334 for (int i=0; i<pmap.size(); i++) { 7335 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7336 for (int j=0; j<uids.size(); j++) { 7337 ProcessRecord proc = uids.valueAt(j); 7338 if (proc.userId != tr.userId) { 7339 continue; 7340 } 7341 if (!proc.pkgList.containsKey(pkg)) { 7342 continue; 7343 } 7344 procs.add(proc); 7345 } 7346 } 7347 7348 // Kill the running processes. 7349 for (int i=0; i<procs.size(); i++) { 7350 ProcessRecord pr = procs.get(i); 7351 if (pr == mHomeProcess) { 7352 // Don't kill the home process along with tasks from the same package. 7353 continue; 7354 } 7355 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7356 killUnneededProcessLocked(pr, "remove task"); 7357 } else { 7358 pr.waitingToKill = "remove task"; 7359 } 7360 } 7361 } 7362 } 7363 7364 /** 7365 * Removes the task with the specified task id. 7366 * 7367 * @param taskId Identifier of the task to be removed. 7368 * @param flags Additional operational flags. May be 0 or 7369 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7370 * @return Returns true if the given task was found and removed. 7371 */ 7372 private boolean removeTaskByIdLocked(int taskId, int flags) { 7373 TaskRecord tr = recentTaskForIdLocked(taskId); 7374 if (tr != null) { 7375 tr.removeTaskActivitiesLocked(-1, false); 7376 cleanUpRemovedTaskLocked(tr, flags); 7377 if (tr.isPersistable) { 7378 notifyTaskPersisterLocked(tr, true); 7379 } 7380 return true; 7381 } 7382 return false; 7383 } 7384 7385 @Override 7386 public boolean removeTask(int taskId, int flags) { 7387 synchronized (this) { 7388 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7389 "removeTask()"); 7390 long ident = Binder.clearCallingIdentity(); 7391 try { 7392 return removeTaskByIdLocked(taskId, flags); 7393 } finally { 7394 Binder.restoreCallingIdentity(ident); 7395 } 7396 } 7397 } 7398 7399 /** 7400 * TODO: Add mController hook 7401 */ 7402 @Override 7403 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7404 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7405 "moveTaskToFront()"); 7406 7407 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7408 synchronized(this) { 7409 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7410 Binder.getCallingUid(), "Task to front")) { 7411 ActivityOptions.abort(options); 7412 return; 7413 } 7414 final long origId = Binder.clearCallingIdentity(); 7415 try { 7416 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7417 if (task == null) { 7418 return; 7419 } 7420 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7421 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7422 return; 7423 } 7424 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7425 } finally { 7426 Binder.restoreCallingIdentity(origId); 7427 } 7428 ActivityOptions.abort(options); 7429 } 7430 } 7431 7432 @Override 7433 public void moveTaskToBack(int taskId) { 7434 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7435 "moveTaskToBack()"); 7436 7437 synchronized(this) { 7438 TaskRecord tr = recentTaskForIdLocked(taskId); 7439 if (tr != null) { 7440 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7441 ActivityStack stack = tr.stack; 7442 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7443 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7444 Binder.getCallingUid(), "Task to back")) { 7445 return; 7446 } 7447 } 7448 final long origId = Binder.clearCallingIdentity(); 7449 try { 7450 stack.moveTaskToBackLocked(taskId, null); 7451 } finally { 7452 Binder.restoreCallingIdentity(origId); 7453 } 7454 } 7455 } 7456 } 7457 7458 /** 7459 * Moves an activity, and all of the other activities within the same task, to the bottom 7460 * of the history stack. The activity's order within the task is unchanged. 7461 * 7462 * @param token A reference to the activity we wish to move 7463 * @param nonRoot If false then this only works if the activity is the root 7464 * of a task; if true it will work for any activity in a task. 7465 * @return Returns true if the move completed, false if not. 7466 */ 7467 @Override 7468 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7469 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7470 synchronized(this) { 7471 final long origId = Binder.clearCallingIdentity(); 7472 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7473 if (taskId >= 0) { 7474 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7475 } 7476 Binder.restoreCallingIdentity(origId); 7477 } 7478 return false; 7479 } 7480 7481 @Override 7482 public void moveTaskBackwards(int task) { 7483 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7484 "moveTaskBackwards()"); 7485 7486 synchronized(this) { 7487 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7488 Binder.getCallingUid(), "Task backwards")) { 7489 return; 7490 } 7491 final long origId = Binder.clearCallingIdentity(); 7492 moveTaskBackwardsLocked(task); 7493 Binder.restoreCallingIdentity(origId); 7494 } 7495 } 7496 7497 private final void moveTaskBackwardsLocked(int task) { 7498 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7499 } 7500 7501 @Override 7502 public IBinder getHomeActivityToken() throws RemoteException { 7503 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7504 "getHomeActivityToken()"); 7505 synchronized (this) { 7506 return mStackSupervisor.getHomeActivityToken(); 7507 } 7508 } 7509 7510 @Override 7511 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7512 IActivityContainerCallback callback) throws RemoteException { 7513 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7514 "createActivityContainer()"); 7515 synchronized (this) { 7516 if (parentActivityToken == null) { 7517 throw new IllegalArgumentException("parent token must not be null"); 7518 } 7519 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7520 if (r == null) { 7521 return null; 7522 } 7523 if (callback == null) { 7524 throw new IllegalArgumentException("callback must not be null"); 7525 } 7526 return mStackSupervisor.createActivityContainer(r, callback); 7527 } 7528 } 7529 7530 @Override 7531 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7532 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7533 "deleteActivityContainer()"); 7534 synchronized (this) { 7535 mStackSupervisor.deleteActivityContainer(container); 7536 } 7537 } 7538 7539 @Override 7540 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7541 throws RemoteException { 7542 synchronized (this) { 7543 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7544 if (stack != null) { 7545 return stack.mActivityContainer; 7546 } 7547 return null; 7548 } 7549 } 7550 7551 @Override 7552 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7553 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7554 "moveTaskToStack()"); 7555 if (stackId == HOME_STACK_ID) { 7556 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7557 new RuntimeException("here").fillInStackTrace()); 7558 } 7559 synchronized (this) { 7560 long ident = Binder.clearCallingIdentity(); 7561 try { 7562 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7563 + stackId + " toTop=" + toTop); 7564 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7565 } finally { 7566 Binder.restoreCallingIdentity(ident); 7567 } 7568 } 7569 } 7570 7571 @Override 7572 public void resizeStack(int stackBoxId, Rect bounds) { 7573 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7574 "resizeStackBox()"); 7575 long ident = Binder.clearCallingIdentity(); 7576 try { 7577 mWindowManager.resizeStack(stackBoxId, bounds); 7578 } finally { 7579 Binder.restoreCallingIdentity(ident); 7580 } 7581 } 7582 7583 @Override 7584 public List<StackInfo> getAllStackInfos() { 7585 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7586 "getAllStackInfos()"); 7587 long ident = Binder.clearCallingIdentity(); 7588 try { 7589 synchronized (this) { 7590 return mStackSupervisor.getAllStackInfosLocked(); 7591 } 7592 } finally { 7593 Binder.restoreCallingIdentity(ident); 7594 } 7595 } 7596 7597 @Override 7598 public StackInfo getStackInfo(int stackId) { 7599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7600 "getStackInfo()"); 7601 long ident = Binder.clearCallingIdentity(); 7602 try { 7603 synchronized (this) { 7604 return mStackSupervisor.getStackInfoLocked(stackId); 7605 } 7606 } finally { 7607 Binder.restoreCallingIdentity(ident); 7608 } 7609 } 7610 7611 @Override 7612 public boolean isInHomeStack(int taskId) { 7613 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7614 "getStackInfo()"); 7615 long ident = Binder.clearCallingIdentity(); 7616 try { 7617 synchronized (this) { 7618 TaskRecord tr = recentTaskForIdLocked(taskId); 7619 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7620 } 7621 } finally { 7622 Binder.restoreCallingIdentity(ident); 7623 } 7624 } 7625 7626 @Override 7627 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7628 synchronized(this) { 7629 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7630 } 7631 } 7632 7633 private boolean isLockTaskAuthorized(ComponentName name) { 7634 final DevicePolicyManager dpm = (DevicePolicyManager) 7635 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7636 return dpm != null && dpm.isLockTaskPermitted(name); 7637 } 7638 7639 private void startLockTaskMode(TaskRecord task) { 7640 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7641 return; 7642 } 7643 long ident = Binder.clearCallingIdentity(); 7644 try { 7645 synchronized (this) { 7646 // Since we lost lock on task, make sure it is still there. 7647 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7648 if (task != null) { 7649 mStackSupervisor.setLockTaskModeLocked(task); 7650 } 7651 } 7652 } finally { 7653 Binder.restoreCallingIdentity(ident); 7654 } 7655 } 7656 7657 @Override 7658 public void startLockTaskMode(int taskId) { 7659 long ident = Binder.clearCallingIdentity(); 7660 try { 7661 final TaskRecord task; 7662 synchronized (this) { 7663 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7664 } 7665 if (task != null) { 7666 startLockTaskMode(task); 7667 } 7668 } finally { 7669 Binder.restoreCallingIdentity(ident); 7670 } 7671 } 7672 7673 @Override 7674 public void startLockTaskMode(IBinder token) { 7675 long ident = Binder.clearCallingIdentity(); 7676 try { 7677 final TaskRecord task; 7678 synchronized (this) { 7679 final ActivityRecord r = ActivityRecord.forToken(token); 7680 if (r == null) { 7681 return; 7682 } 7683 task = r.task; 7684 } 7685 if (task != null) { 7686 startLockTaskMode(task); 7687 } 7688 } finally { 7689 Binder.restoreCallingIdentity(ident); 7690 } 7691 } 7692 7693 @Override 7694 public void stopLockTaskMode() { 7695 // Check if the calling task is eligible to use lock task 7696 final int uid = Binder.getCallingUid(); 7697 try { 7698 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7699 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7700 return; 7701 } 7702 } catch (RemoteException e) { 7703 Log.d(TAG, "stopLockTaskMode " + e); 7704 return; 7705 } 7706 // Stop lock task 7707 synchronized (this) { 7708 mStackSupervisor.setLockTaskModeLocked(null); 7709 } 7710 } 7711 7712 @Override 7713 public boolean isInLockTaskMode() { 7714 synchronized (this) { 7715 return mStackSupervisor.isInLockTaskMode(); 7716 } 7717 } 7718 7719 // ========================================================= 7720 // CONTENT PROVIDERS 7721 // ========================================================= 7722 7723 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7724 List<ProviderInfo> providers = null; 7725 try { 7726 providers = AppGlobals.getPackageManager(). 7727 queryContentProviders(app.processName, app.uid, 7728 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7729 } catch (RemoteException ex) { 7730 } 7731 if (DEBUG_MU) 7732 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7733 int userId = app.userId; 7734 if (providers != null) { 7735 int N = providers.size(); 7736 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7737 for (int i=0; i<N; i++) { 7738 ProviderInfo cpi = 7739 (ProviderInfo)providers.get(i); 7740 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7741 cpi.name, cpi.flags); 7742 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7743 // This is a singleton provider, but a user besides the 7744 // default user is asking to initialize a process it runs 7745 // in... well, no, it doesn't actually run in this process, 7746 // it runs in the process of the default user. Get rid of it. 7747 providers.remove(i); 7748 N--; 7749 i--; 7750 continue; 7751 } 7752 7753 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7754 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7755 if (cpr == null) { 7756 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7757 mProviderMap.putProviderByClass(comp, cpr); 7758 } 7759 if (DEBUG_MU) 7760 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7761 app.pubProviders.put(cpi.name, cpr); 7762 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7763 // Don't add this if it is a platform component that is marked 7764 // to run in multiple processes, because this is actually 7765 // part of the framework so doesn't make sense to track as a 7766 // separate apk in the process. 7767 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7768 } 7769 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7770 } 7771 } 7772 return providers; 7773 } 7774 7775 /** 7776 * Check if {@link ProcessRecord} has a possible chance at accessing the 7777 * given {@link ProviderInfo}. Final permission checking is always done 7778 * in {@link ContentProvider}. 7779 */ 7780 private final String checkContentProviderPermissionLocked( 7781 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7782 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7783 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7784 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7785 // Looking for cross-user grants before to enforce the typical cross-users permissions 7786 if (userId != UserHandle.getUserId(callingUid)) { 7787 if (perms != null) { 7788 for (GrantUri grantUri : perms.keySet()) { 7789 if (grantUri.sourceUserId == userId) { 7790 String authority = grantUri.uri.getAuthority(); 7791 if (authority.equals(cpi.authority)) { 7792 return null; 7793 } 7794 } 7795 } 7796 } 7797 } 7798 if (checkUser) { 7799 userId = handleIncomingUser(callingPid, callingUid, userId, 7800 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7801 } 7802 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7803 cpi.applicationInfo.uid, cpi.exported) 7804 == PackageManager.PERMISSION_GRANTED) { 7805 return null; 7806 } 7807 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7808 cpi.applicationInfo.uid, cpi.exported) 7809 == PackageManager.PERMISSION_GRANTED) { 7810 return null; 7811 } 7812 7813 PathPermission[] pps = cpi.pathPermissions; 7814 if (pps != null) { 7815 int i = pps.length; 7816 while (i > 0) { 7817 i--; 7818 PathPermission pp = pps[i]; 7819 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7820 cpi.applicationInfo.uid, cpi.exported) 7821 == PackageManager.PERMISSION_GRANTED) { 7822 return null; 7823 } 7824 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7825 cpi.applicationInfo.uid, cpi.exported) 7826 == PackageManager.PERMISSION_GRANTED) { 7827 return null; 7828 } 7829 } 7830 } 7831 7832 if (perms != null) { 7833 for (GrantUri grantUri : perms.keySet()) { 7834 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7835 return null; 7836 } 7837 } 7838 } 7839 7840 String msg; 7841 if (!cpi.exported) { 7842 msg = "Permission Denial: opening provider " + cpi.name 7843 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7844 + ", uid=" + callingUid + ") that is not exported from uid " 7845 + cpi.applicationInfo.uid; 7846 } else { 7847 msg = "Permission Denial: opening provider " + cpi.name 7848 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7849 + ", uid=" + callingUid + ") requires " 7850 + cpi.readPermission + " or " + cpi.writePermission; 7851 } 7852 Slog.w(TAG, msg); 7853 return msg; 7854 } 7855 7856 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7857 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7858 if (r != null) { 7859 for (int i=0; i<r.conProviders.size(); i++) { 7860 ContentProviderConnection conn = r.conProviders.get(i); 7861 if (conn.provider == cpr) { 7862 if (DEBUG_PROVIDER) Slog.v(TAG, 7863 "Adding provider requested by " 7864 + r.processName + " from process " 7865 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7866 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7867 if (stable) { 7868 conn.stableCount++; 7869 conn.numStableIncs++; 7870 } else { 7871 conn.unstableCount++; 7872 conn.numUnstableIncs++; 7873 } 7874 return conn; 7875 } 7876 } 7877 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7878 if (stable) { 7879 conn.stableCount = 1; 7880 conn.numStableIncs = 1; 7881 } else { 7882 conn.unstableCount = 1; 7883 conn.numUnstableIncs = 1; 7884 } 7885 cpr.connections.add(conn); 7886 r.conProviders.add(conn); 7887 return conn; 7888 } 7889 cpr.addExternalProcessHandleLocked(externalProcessToken); 7890 return null; 7891 } 7892 7893 boolean decProviderCountLocked(ContentProviderConnection conn, 7894 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7895 if (conn != null) { 7896 cpr = conn.provider; 7897 if (DEBUG_PROVIDER) Slog.v(TAG, 7898 "Removing provider requested by " 7899 + conn.client.processName + " from process " 7900 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7901 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7902 if (stable) { 7903 conn.stableCount--; 7904 } else { 7905 conn.unstableCount--; 7906 } 7907 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7908 cpr.connections.remove(conn); 7909 conn.client.conProviders.remove(conn); 7910 return true; 7911 } 7912 return false; 7913 } 7914 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7915 return false; 7916 } 7917 7918 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7919 String name, IBinder token, boolean stable, int userId) { 7920 ContentProviderRecord cpr; 7921 ContentProviderConnection conn = null; 7922 ProviderInfo cpi = null; 7923 7924 synchronized(this) { 7925 ProcessRecord r = null; 7926 if (caller != null) { 7927 r = getRecordForAppLocked(caller); 7928 if (r == null) { 7929 throw new SecurityException( 7930 "Unable to find app for caller " + caller 7931 + " (pid=" + Binder.getCallingPid() 7932 + ") when getting content provider " + name); 7933 } 7934 } 7935 7936 boolean checkCrossUser = true; 7937 7938 // First check if this content provider has been published... 7939 cpr = mProviderMap.getProviderByName(name, userId); 7940 // If that didn't work, check if it exists for user 0 and then 7941 // verify that it's a singleton provider before using it. 7942 if (cpr == null && userId != UserHandle.USER_OWNER) { 7943 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 7944 if (cpr != null) { 7945 cpi = cpr.info; 7946 if (isSingleton(cpi.processName, cpi.applicationInfo, 7947 cpi.name, cpi.flags) 7948 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 7949 userId = UserHandle.USER_OWNER; 7950 checkCrossUser = false; 7951 } else { 7952 cpr = null; 7953 cpi = null; 7954 } 7955 } 7956 } 7957 7958 boolean providerRunning = cpr != null; 7959 if (providerRunning) { 7960 cpi = cpr.info; 7961 String msg; 7962 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 7963 != null) { 7964 throw new SecurityException(msg); 7965 } 7966 7967 if (r != null && cpr.canRunHere(r)) { 7968 // This provider has been published or is in the process 7969 // of being published... but it is also allowed to run 7970 // in the caller's process, so don't make a connection 7971 // and just let the caller instantiate its own instance. 7972 ContentProviderHolder holder = cpr.newHolder(null); 7973 // don't give caller the provider object, it needs 7974 // to make its own. 7975 holder.provider = null; 7976 return holder; 7977 } 7978 7979 final long origId = Binder.clearCallingIdentity(); 7980 7981 // In this case the provider instance already exists, so we can 7982 // return it right away. 7983 conn = incProviderCountLocked(r, cpr, token, stable); 7984 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7985 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7986 // If this is a perceptible app accessing the provider, 7987 // make sure to count it as being accessed and thus 7988 // back up on the LRU list. This is good because 7989 // content providers are often expensive to start. 7990 updateLruProcessLocked(cpr.proc, false, null); 7991 } 7992 } 7993 7994 if (cpr.proc != null) { 7995 if (false) { 7996 if (cpr.name.flattenToShortString().equals( 7997 "com.android.providers.calendar/.CalendarProvider2")) { 7998 Slog.v(TAG, "****************** KILLING " 7999 + cpr.name.flattenToShortString()); 8000 Process.killProcess(cpr.proc.pid); 8001 } 8002 } 8003 boolean success = updateOomAdjLocked(cpr.proc); 8004 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8005 // NOTE: there is still a race here where a signal could be 8006 // pending on the process even though we managed to update its 8007 // adj level. Not sure what to do about this, but at least 8008 // the race is now smaller. 8009 if (!success) { 8010 // Uh oh... it looks like the provider's process 8011 // has been killed on us. We need to wait for a new 8012 // process to be started, and make sure its death 8013 // doesn't kill our process. 8014 Slog.i(TAG, 8015 "Existing provider " + cpr.name.flattenToShortString() 8016 + " is crashing; detaching " + r); 8017 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8018 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8019 if (!lastRef) { 8020 // This wasn't the last ref our process had on 8021 // the provider... we have now been killed, bail. 8022 return null; 8023 } 8024 providerRunning = false; 8025 conn = null; 8026 } 8027 } 8028 8029 Binder.restoreCallingIdentity(origId); 8030 } 8031 8032 boolean singleton; 8033 if (!providerRunning) { 8034 try { 8035 cpi = AppGlobals.getPackageManager(). 8036 resolveContentProvider(name, 8037 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8038 } catch (RemoteException ex) { 8039 } 8040 if (cpi == null) { 8041 return null; 8042 } 8043 // If the provider is a singleton AND 8044 // (it's a call within the same user || the provider is a 8045 // privileged app) 8046 // Then allow connecting to the singleton provider 8047 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8048 cpi.name, cpi.flags) 8049 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8050 if (singleton) { 8051 userId = UserHandle.USER_OWNER; 8052 } 8053 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8054 8055 String msg; 8056 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8057 != null) { 8058 throw new SecurityException(msg); 8059 } 8060 8061 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8062 && !cpi.processName.equals("system")) { 8063 // If this content provider does not run in the system 8064 // process, and the system is not yet ready to run other 8065 // processes, then fail fast instead of hanging. 8066 throw new IllegalArgumentException( 8067 "Attempt to launch content provider before system ready"); 8068 } 8069 8070 // Make sure that the user who owns this provider is started. If not, 8071 // we don't want to allow it to run. 8072 if (mStartedUsers.get(userId) == null) { 8073 Slog.w(TAG, "Unable to launch app " 8074 + cpi.applicationInfo.packageName + "/" 8075 + cpi.applicationInfo.uid + " for provider " 8076 + name + ": user " + userId + " is stopped"); 8077 return null; 8078 } 8079 8080 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8081 cpr = mProviderMap.getProviderByClass(comp, userId); 8082 final boolean firstClass = cpr == null; 8083 if (firstClass) { 8084 try { 8085 ApplicationInfo ai = 8086 AppGlobals.getPackageManager(). 8087 getApplicationInfo( 8088 cpi.applicationInfo.packageName, 8089 STOCK_PM_FLAGS, userId); 8090 if (ai == null) { 8091 Slog.w(TAG, "No package info for content provider " 8092 + cpi.name); 8093 return null; 8094 } 8095 ai = getAppInfoForUser(ai, userId); 8096 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8097 } catch (RemoteException ex) { 8098 // pm is in same process, this will never happen. 8099 } 8100 } 8101 8102 if (r != null && cpr.canRunHere(r)) { 8103 // If this is a multiprocess provider, then just return its 8104 // info and allow the caller to instantiate it. Only do 8105 // this if the provider is the same user as the caller's 8106 // process, or can run as root (so can be in any process). 8107 return cpr.newHolder(null); 8108 } 8109 8110 if (DEBUG_PROVIDER) { 8111 RuntimeException e = new RuntimeException("here"); 8112 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8113 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8114 } 8115 8116 // This is single process, and our app is now connecting to it. 8117 // See if we are already in the process of launching this 8118 // provider. 8119 final int N = mLaunchingProviders.size(); 8120 int i; 8121 for (i=0; i<N; i++) { 8122 if (mLaunchingProviders.get(i) == cpr) { 8123 break; 8124 } 8125 } 8126 8127 // If the provider is not already being launched, then get it 8128 // started. 8129 if (i >= N) { 8130 final long origId = Binder.clearCallingIdentity(); 8131 8132 try { 8133 // Content provider is now in use, its package can't be stopped. 8134 try { 8135 AppGlobals.getPackageManager().setPackageStoppedState( 8136 cpr.appInfo.packageName, false, userId); 8137 } catch (RemoteException e) { 8138 } catch (IllegalArgumentException e) { 8139 Slog.w(TAG, "Failed trying to unstop package " 8140 + cpr.appInfo.packageName + ": " + e); 8141 } 8142 8143 // Use existing process if already started 8144 ProcessRecord proc = getProcessRecordLocked( 8145 cpi.processName, cpr.appInfo.uid, false); 8146 if (proc != null && proc.thread != null) { 8147 if (DEBUG_PROVIDER) { 8148 Slog.d(TAG, "Installing in existing process " + proc); 8149 } 8150 proc.pubProviders.put(cpi.name, cpr); 8151 try { 8152 proc.thread.scheduleInstallProvider(cpi); 8153 } catch (RemoteException e) { 8154 } 8155 } else { 8156 proc = startProcessLocked(cpi.processName, 8157 cpr.appInfo, false, 0, "content provider", 8158 new ComponentName(cpi.applicationInfo.packageName, 8159 cpi.name), false, false, false); 8160 if (proc == null) { 8161 Slog.w(TAG, "Unable to launch app " 8162 + cpi.applicationInfo.packageName + "/" 8163 + cpi.applicationInfo.uid + " for provider " 8164 + name + ": process is bad"); 8165 return null; 8166 } 8167 } 8168 cpr.launchingApp = proc; 8169 mLaunchingProviders.add(cpr); 8170 } finally { 8171 Binder.restoreCallingIdentity(origId); 8172 } 8173 } 8174 8175 // Make sure the provider is published (the same provider class 8176 // may be published under multiple names). 8177 if (firstClass) { 8178 mProviderMap.putProviderByClass(comp, cpr); 8179 } 8180 8181 mProviderMap.putProviderByName(name, cpr); 8182 conn = incProviderCountLocked(r, cpr, token, stable); 8183 if (conn != null) { 8184 conn.waiting = true; 8185 } 8186 } 8187 } 8188 8189 // Wait for the provider to be published... 8190 synchronized (cpr) { 8191 while (cpr.provider == null) { 8192 if (cpr.launchingApp == null) { 8193 Slog.w(TAG, "Unable to launch app " 8194 + cpi.applicationInfo.packageName + "/" 8195 + cpi.applicationInfo.uid + " for provider " 8196 + name + ": launching app became null"); 8197 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8198 UserHandle.getUserId(cpi.applicationInfo.uid), 8199 cpi.applicationInfo.packageName, 8200 cpi.applicationInfo.uid, name); 8201 return null; 8202 } 8203 try { 8204 if (DEBUG_MU) { 8205 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8206 + cpr.launchingApp); 8207 } 8208 if (conn != null) { 8209 conn.waiting = true; 8210 } 8211 cpr.wait(); 8212 } catch (InterruptedException ex) { 8213 } finally { 8214 if (conn != null) { 8215 conn.waiting = false; 8216 } 8217 } 8218 } 8219 } 8220 return cpr != null ? cpr.newHolder(conn) : null; 8221 } 8222 8223 @Override 8224 public final ContentProviderHolder getContentProvider( 8225 IApplicationThread caller, String name, int userId, boolean stable) { 8226 enforceNotIsolatedCaller("getContentProvider"); 8227 if (caller == null) { 8228 String msg = "null IApplicationThread when getting content provider " 8229 + name; 8230 Slog.w(TAG, msg); 8231 throw new SecurityException(msg); 8232 } 8233 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8234 // with cross-user grant. 8235 return getContentProviderImpl(caller, name, null, stable, userId); 8236 } 8237 8238 public ContentProviderHolder getContentProviderExternal( 8239 String name, int userId, IBinder token) { 8240 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8241 "Do not have permission in call getContentProviderExternal()"); 8242 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8243 false, true, "getContentProvider", null); 8244 return getContentProviderExternalUnchecked(name, token, userId); 8245 } 8246 8247 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8248 IBinder token, int userId) { 8249 return getContentProviderImpl(null, name, token, true, userId); 8250 } 8251 8252 /** 8253 * Drop a content provider from a ProcessRecord's bookkeeping 8254 */ 8255 public void removeContentProvider(IBinder connection, boolean stable) { 8256 enforceNotIsolatedCaller("removeContentProvider"); 8257 long ident = Binder.clearCallingIdentity(); 8258 try { 8259 synchronized (this) { 8260 ContentProviderConnection conn; 8261 try { 8262 conn = (ContentProviderConnection)connection; 8263 } catch (ClassCastException e) { 8264 String msg ="removeContentProvider: " + connection 8265 + " not a ContentProviderConnection"; 8266 Slog.w(TAG, msg); 8267 throw new IllegalArgumentException(msg); 8268 } 8269 if (conn == null) { 8270 throw new NullPointerException("connection is null"); 8271 } 8272 if (decProviderCountLocked(conn, null, null, stable)) { 8273 updateOomAdjLocked(); 8274 } 8275 } 8276 } finally { 8277 Binder.restoreCallingIdentity(ident); 8278 } 8279 } 8280 8281 public void removeContentProviderExternal(String name, IBinder token) { 8282 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8283 "Do not have permission in call removeContentProviderExternal()"); 8284 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8285 } 8286 8287 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8288 synchronized (this) { 8289 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8290 if(cpr == null) { 8291 //remove from mProvidersByClass 8292 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8293 return; 8294 } 8295 8296 //update content provider record entry info 8297 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8298 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8299 if (localCpr.hasExternalProcessHandles()) { 8300 if (localCpr.removeExternalProcessHandleLocked(token)) { 8301 updateOomAdjLocked(); 8302 } else { 8303 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8304 + " with no external reference for token: " 8305 + token + "."); 8306 } 8307 } else { 8308 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8309 + " with no external references."); 8310 } 8311 } 8312 } 8313 8314 public final void publishContentProviders(IApplicationThread caller, 8315 List<ContentProviderHolder> providers) { 8316 if (providers == null) { 8317 return; 8318 } 8319 8320 enforceNotIsolatedCaller("publishContentProviders"); 8321 synchronized (this) { 8322 final ProcessRecord r = getRecordForAppLocked(caller); 8323 if (DEBUG_MU) 8324 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8325 if (r == null) { 8326 throw new SecurityException( 8327 "Unable to find app for caller " + caller 8328 + " (pid=" + Binder.getCallingPid() 8329 + ") when publishing content providers"); 8330 } 8331 8332 final long origId = Binder.clearCallingIdentity(); 8333 8334 final int N = providers.size(); 8335 for (int i=0; i<N; i++) { 8336 ContentProviderHolder src = providers.get(i); 8337 if (src == null || src.info == null || src.provider == null) { 8338 continue; 8339 } 8340 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8341 if (DEBUG_MU) 8342 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8343 if (dst != null) { 8344 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8345 mProviderMap.putProviderByClass(comp, dst); 8346 String names[] = dst.info.authority.split(";"); 8347 for (int j = 0; j < names.length; j++) { 8348 mProviderMap.putProviderByName(names[j], dst); 8349 } 8350 8351 int NL = mLaunchingProviders.size(); 8352 int j; 8353 for (j=0; j<NL; j++) { 8354 if (mLaunchingProviders.get(j) == dst) { 8355 mLaunchingProviders.remove(j); 8356 j--; 8357 NL--; 8358 } 8359 } 8360 synchronized (dst) { 8361 dst.provider = src.provider; 8362 dst.proc = r; 8363 dst.notifyAll(); 8364 } 8365 updateOomAdjLocked(r); 8366 } 8367 } 8368 8369 Binder.restoreCallingIdentity(origId); 8370 } 8371 } 8372 8373 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8374 ContentProviderConnection conn; 8375 try { 8376 conn = (ContentProviderConnection)connection; 8377 } catch (ClassCastException e) { 8378 String msg ="refContentProvider: " + connection 8379 + " not a ContentProviderConnection"; 8380 Slog.w(TAG, msg); 8381 throw new IllegalArgumentException(msg); 8382 } 8383 if (conn == null) { 8384 throw new NullPointerException("connection is null"); 8385 } 8386 8387 synchronized (this) { 8388 if (stable > 0) { 8389 conn.numStableIncs += stable; 8390 } 8391 stable = conn.stableCount + stable; 8392 if (stable < 0) { 8393 throw new IllegalStateException("stableCount < 0: " + stable); 8394 } 8395 8396 if (unstable > 0) { 8397 conn.numUnstableIncs += unstable; 8398 } 8399 unstable = conn.unstableCount + unstable; 8400 if (unstable < 0) { 8401 throw new IllegalStateException("unstableCount < 0: " + unstable); 8402 } 8403 8404 if ((stable+unstable) <= 0) { 8405 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8406 + stable + " unstable=" + unstable); 8407 } 8408 conn.stableCount = stable; 8409 conn.unstableCount = unstable; 8410 return !conn.dead; 8411 } 8412 } 8413 8414 public void unstableProviderDied(IBinder connection) { 8415 ContentProviderConnection conn; 8416 try { 8417 conn = (ContentProviderConnection)connection; 8418 } catch (ClassCastException e) { 8419 String msg ="refContentProvider: " + connection 8420 + " not a ContentProviderConnection"; 8421 Slog.w(TAG, msg); 8422 throw new IllegalArgumentException(msg); 8423 } 8424 if (conn == null) { 8425 throw new NullPointerException("connection is null"); 8426 } 8427 8428 // Safely retrieve the content provider associated with the connection. 8429 IContentProvider provider; 8430 synchronized (this) { 8431 provider = conn.provider.provider; 8432 } 8433 8434 if (provider == null) { 8435 // Um, yeah, we're way ahead of you. 8436 return; 8437 } 8438 8439 // Make sure the caller is being honest with us. 8440 if (provider.asBinder().pingBinder()) { 8441 // Er, no, still looks good to us. 8442 synchronized (this) { 8443 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8444 + " says " + conn + " died, but we don't agree"); 8445 return; 8446 } 8447 } 8448 8449 // Well look at that! It's dead! 8450 synchronized (this) { 8451 if (conn.provider.provider != provider) { 8452 // But something changed... good enough. 8453 return; 8454 } 8455 8456 ProcessRecord proc = conn.provider.proc; 8457 if (proc == null || proc.thread == null) { 8458 // Seems like the process is already cleaned up. 8459 return; 8460 } 8461 8462 // As far as we're concerned, this is just like receiving a 8463 // death notification... just a bit prematurely. 8464 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8465 + ") early provider death"); 8466 final long ident = Binder.clearCallingIdentity(); 8467 try { 8468 appDiedLocked(proc, proc.pid, proc.thread); 8469 } finally { 8470 Binder.restoreCallingIdentity(ident); 8471 } 8472 } 8473 } 8474 8475 @Override 8476 public void appNotRespondingViaProvider(IBinder connection) { 8477 enforceCallingPermission( 8478 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8479 8480 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8481 if (conn == null) { 8482 Slog.w(TAG, "ContentProviderConnection is null"); 8483 return; 8484 } 8485 8486 final ProcessRecord host = conn.provider.proc; 8487 if (host == null) { 8488 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8489 return; 8490 } 8491 8492 final long token = Binder.clearCallingIdentity(); 8493 try { 8494 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8495 } finally { 8496 Binder.restoreCallingIdentity(token); 8497 } 8498 } 8499 8500 public final void installSystemProviders() { 8501 List<ProviderInfo> providers; 8502 synchronized (this) { 8503 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8504 providers = generateApplicationProvidersLocked(app); 8505 if (providers != null) { 8506 for (int i=providers.size()-1; i>=0; i--) { 8507 ProviderInfo pi = (ProviderInfo)providers.get(i); 8508 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8509 Slog.w(TAG, "Not installing system proc provider " + pi.name 8510 + ": not system .apk"); 8511 providers.remove(i); 8512 } 8513 } 8514 } 8515 } 8516 if (providers != null) { 8517 mSystemThread.installSystemProviders(providers); 8518 } 8519 8520 mCoreSettingsObserver = new CoreSettingsObserver(this); 8521 8522 mUsageStatsService.monitorPackages(); 8523 } 8524 8525 /** 8526 * Allows app to retrieve the MIME type of a URI without having permission 8527 * to access its content provider. 8528 * 8529 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8530 * 8531 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8532 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8533 */ 8534 public String getProviderMimeType(Uri uri, int userId) { 8535 enforceNotIsolatedCaller("getProviderMimeType"); 8536 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8537 userId, false, true, "getProviderMimeType", null); 8538 final String name = uri.getAuthority(); 8539 final long ident = Binder.clearCallingIdentity(); 8540 ContentProviderHolder holder = null; 8541 8542 try { 8543 holder = getContentProviderExternalUnchecked(name, null, userId); 8544 if (holder != null) { 8545 return holder.provider.getType(uri); 8546 } 8547 } catch (RemoteException e) { 8548 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8549 return null; 8550 } finally { 8551 if (holder != null) { 8552 removeContentProviderExternalUnchecked(name, null, userId); 8553 } 8554 Binder.restoreCallingIdentity(ident); 8555 } 8556 8557 return null; 8558 } 8559 8560 // ========================================================= 8561 // GLOBAL MANAGEMENT 8562 // ========================================================= 8563 8564 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8565 boolean isolated) { 8566 String proc = customProcess != null ? customProcess : info.processName; 8567 BatteryStatsImpl.Uid.Proc ps = null; 8568 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8569 int uid = info.uid; 8570 if (isolated) { 8571 int userId = UserHandle.getUserId(uid); 8572 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8573 while (true) { 8574 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8575 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8576 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8577 } 8578 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8579 mNextIsolatedProcessUid++; 8580 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8581 // No process for this uid, use it. 8582 break; 8583 } 8584 stepsLeft--; 8585 if (stepsLeft <= 0) { 8586 return null; 8587 } 8588 } 8589 } 8590 return new ProcessRecord(stats, info, proc, uid); 8591 } 8592 8593 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8594 String abiOverride) { 8595 ProcessRecord app; 8596 if (!isolated) { 8597 app = getProcessRecordLocked(info.processName, info.uid, true); 8598 } else { 8599 app = null; 8600 } 8601 8602 if (app == null) { 8603 app = newProcessRecordLocked(info, null, isolated); 8604 mProcessNames.put(info.processName, app.uid, app); 8605 if (isolated) { 8606 mIsolatedProcesses.put(app.uid, app); 8607 } 8608 updateLruProcessLocked(app, false, null); 8609 updateOomAdjLocked(); 8610 } 8611 8612 // This package really, really can not be stopped. 8613 try { 8614 AppGlobals.getPackageManager().setPackageStoppedState( 8615 info.packageName, false, UserHandle.getUserId(app.uid)); 8616 } catch (RemoteException e) { 8617 } catch (IllegalArgumentException e) { 8618 Slog.w(TAG, "Failed trying to unstop package " 8619 + info.packageName + ": " + e); 8620 } 8621 8622 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8623 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8624 app.persistent = true; 8625 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8626 } 8627 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8628 mPersistentStartingProcesses.add(app); 8629 startProcessLocked(app, "added application", app.processName, 8630 abiOverride); 8631 } 8632 8633 return app; 8634 } 8635 8636 public void unhandledBack() { 8637 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8638 "unhandledBack()"); 8639 8640 synchronized(this) { 8641 final long origId = Binder.clearCallingIdentity(); 8642 try { 8643 getFocusedStack().unhandledBackLocked(); 8644 } finally { 8645 Binder.restoreCallingIdentity(origId); 8646 } 8647 } 8648 } 8649 8650 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8651 enforceNotIsolatedCaller("openContentUri"); 8652 final int userId = UserHandle.getCallingUserId(); 8653 String name = uri.getAuthority(); 8654 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8655 ParcelFileDescriptor pfd = null; 8656 if (cph != null) { 8657 // We record the binder invoker's uid in thread-local storage before 8658 // going to the content provider to open the file. Later, in the code 8659 // that handles all permissions checks, we look for this uid and use 8660 // that rather than the Activity Manager's own uid. The effect is that 8661 // we do the check against the caller's permissions even though it looks 8662 // to the content provider like the Activity Manager itself is making 8663 // the request. 8664 sCallerIdentity.set(new Identity( 8665 Binder.getCallingPid(), Binder.getCallingUid())); 8666 try { 8667 pfd = cph.provider.openFile(null, uri, "r", null); 8668 } catch (FileNotFoundException e) { 8669 // do nothing; pfd will be returned null 8670 } finally { 8671 // Ensure that whatever happens, we clean up the identity state 8672 sCallerIdentity.remove(); 8673 } 8674 8675 // We've got the fd now, so we're done with the provider. 8676 removeContentProviderExternalUnchecked(name, null, userId); 8677 } else { 8678 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8679 } 8680 return pfd; 8681 } 8682 8683 // Actually is sleeping or shutting down or whatever else in the future 8684 // is an inactive state. 8685 public boolean isSleepingOrShuttingDown() { 8686 return mSleeping || mShuttingDown; 8687 } 8688 8689 public boolean isSleeping() { 8690 return mSleeping; 8691 } 8692 8693 void goingToSleep() { 8694 synchronized(this) { 8695 mWentToSleep = true; 8696 updateEventDispatchingLocked(); 8697 goToSleepIfNeededLocked(); 8698 } 8699 } 8700 8701 void finishRunningVoiceLocked() { 8702 if (mRunningVoice) { 8703 mRunningVoice = false; 8704 goToSleepIfNeededLocked(); 8705 } 8706 } 8707 8708 void goToSleepIfNeededLocked() { 8709 if (mWentToSleep && !mRunningVoice) { 8710 if (!mSleeping) { 8711 mSleeping = true; 8712 mStackSupervisor.goingToSleepLocked(); 8713 8714 // Initialize the wake times of all processes. 8715 checkExcessivePowerUsageLocked(false); 8716 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8717 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8718 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8719 } 8720 } 8721 } 8722 8723 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8724 mTaskPersister.notify(task, flush); 8725 } 8726 8727 @Override 8728 public boolean shutdown(int timeout) { 8729 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8730 != PackageManager.PERMISSION_GRANTED) { 8731 throw new SecurityException("Requires permission " 8732 + android.Manifest.permission.SHUTDOWN); 8733 } 8734 8735 boolean timedout = false; 8736 8737 synchronized(this) { 8738 mShuttingDown = true; 8739 updateEventDispatchingLocked(); 8740 timedout = mStackSupervisor.shutdownLocked(timeout); 8741 } 8742 8743 mAppOpsService.shutdown(); 8744 mUsageStatsService.shutdown(); 8745 mBatteryStatsService.shutdown(); 8746 synchronized (this) { 8747 mProcessStats.shutdownLocked(); 8748 } 8749 notifyTaskPersisterLocked(null, true); 8750 8751 return timedout; 8752 } 8753 8754 public final void activitySlept(IBinder token) { 8755 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8756 8757 final long origId = Binder.clearCallingIdentity(); 8758 8759 synchronized (this) { 8760 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8761 if (r != null) { 8762 mStackSupervisor.activitySleptLocked(r); 8763 } 8764 } 8765 8766 Binder.restoreCallingIdentity(origId); 8767 } 8768 8769 void logLockScreen(String msg) { 8770 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8771 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8772 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8773 mStackSupervisor.mDismissKeyguardOnNextActivity); 8774 } 8775 8776 private void comeOutOfSleepIfNeededLocked() { 8777 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8778 if (mSleeping) { 8779 mSleeping = false; 8780 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8781 } 8782 } 8783 } 8784 8785 void wakingUp() { 8786 synchronized(this) { 8787 mWentToSleep = false; 8788 updateEventDispatchingLocked(); 8789 comeOutOfSleepIfNeededLocked(); 8790 } 8791 } 8792 8793 void startRunningVoiceLocked() { 8794 if (!mRunningVoice) { 8795 mRunningVoice = true; 8796 comeOutOfSleepIfNeededLocked(); 8797 } 8798 } 8799 8800 private void updateEventDispatchingLocked() { 8801 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8802 } 8803 8804 public void setLockScreenShown(boolean shown) { 8805 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8806 != PackageManager.PERMISSION_GRANTED) { 8807 throw new SecurityException("Requires permission " 8808 + android.Manifest.permission.DEVICE_POWER); 8809 } 8810 8811 synchronized(this) { 8812 long ident = Binder.clearCallingIdentity(); 8813 try { 8814 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8815 mLockScreenShown = shown; 8816 comeOutOfSleepIfNeededLocked(); 8817 } finally { 8818 Binder.restoreCallingIdentity(ident); 8819 } 8820 } 8821 } 8822 8823 public void stopAppSwitches() { 8824 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8825 != PackageManager.PERMISSION_GRANTED) { 8826 throw new SecurityException("Requires permission " 8827 + android.Manifest.permission.STOP_APP_SWITCHES); 8828 } 8829 8830 synchronized(this) { 8831 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8832 + APP_SWITCH_DELAY_TIME; 8833 mDidAppSwitch = false; 8834 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8835 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8836 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8837 } 8838 } 8839 8840 public void resumeAppSwitches() { 8841 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8842 != PackageManager.PERMISSION_GRANTED) { 8843 throw new SecurityException("Requires permission " 8844 + android.Manifest.permission.STOP_APP_SWITCHES); 8845 } 8846 8847 synchronized(this) { 8848 // Note that we don't execute any pending app switches... we will 8849 // let those wait until either the timeout, or the next start 8850 // activity request. 8851 mAppSwitchesAllowedTime = 0; 8852 } 8853 } 8854 8855 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8856 String name) { 8857 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8858 return true; 8859 } 8860 8861 final int perm = checkComponentPermission( 8862 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8863 callingUid, -1, true); 8864 if (perm == PackageManager.PERMISSION_GRANTED) { 8865 return true; 8866 } 8867 8868 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8869 return false; 8870 } 8871 8872 public void setDebugApp(String packageName, boolean waitForDebugger, 8873 boolean persistent) { 8874 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8875 "setDebugApp()"); 8876 8877 long ident = Binder.clearCallingIdentity(); 8878 try { 8879 // Note that this is not really thread safe if there are multiple 8880 // callers into it at the same time, but that's not a situation we 8881 // care about. 8882 if (persistent) { 8883 final ContentResolver resolver = mContext.getContentResolver(); 8884 Settings.Global.putString( 8885 resolver, Settings.Global.DEBUG_APP, 8886 packageName); 8887 Settings.Global.putInt( 8888 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8889 waitForDebugger ? 1 : 0); 8890 } 8891 8892 synchronized (this) { 8893 if (!persistent) { 8894 mOrigDebugApp = mDebugApp; 8895 mOrigWaitForDebugger = mWaitForDebugger; 8896 } 8897 mDebugApp = packageName; 8898 mWaitForDebugger = waitForDebugger; 8899 mDebugTransient = !persistent; 8900 if (packageName != null) { 8901 forceStopPackageLocked(packageName, -1, false, false, true, true, 8902 false, UserHandle.USER_ALL, "set debug app"); 8903 } 8904 } 8905 } finally { 8906 Binder.restoreCallingIdentity(ident); 8907 } 8908 } 8909 8910 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8911 synchronized (this) { 8912 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8913 if (!isDebuggable) { 8914 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8915 throw new SecurityException("Process not debuggable: " + app.packageName); 8916 } 8917 } 8918 8919 mOpenGlTraceApp = processName; 8920 } 8921 } 8922 8923 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8924 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8925 synchronized (this) { 8926 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8927 if (!isDebuggable) { 8928 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8929 throw new SecurityException("Process not debuggable: " + app.packageName); 8930 } 8931 } 8932 mProfileApp = processName; 8933 mProfileFile = profileFile; 8934 if (mProfileFd != null) { 8935 try { 8936 mProfileFd.close(); 8937 } catch (IOException e) { 8938 } 8939 mProfileFd = null; 8940 } 8941 mProfileFd = profileFd; 8942 mProfileType = 0; 8943 mAutoStopProfiler = autoStopProfiler; 8944 } 8945 } 8946 8947 @Override 8948 public void setAlwaysFinish(boolean enabled) { 8949 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8950 "setAlwaysFinish()"); 8951 8952 Settings.Global.putInt( 8953 mContext.getContentResolver(), 8954 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8955 8956 synchronized (this) { 8957 mAlwaysFinishActivities = enabled; 8958 } 8959 } 8960 8961 @Override 8962 public void setActivityController(IActivityController controller) { 8963 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8964 "setActivityController()"); 8965 synchronized (this) { 8966 mController = controller; 8967 Watchdog.getInstance().setActivityController(controller); 8968 } 8969 } 8970 8971 @Override 8972 public void setUserIsMonkey(boolean userIsMonkey) { 8973 synchronized (this) { 8974 synchronized (mPidsSelfLocked) { 8975 final int callingPid = Binder.getCallingPid(); 8976 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8977 if (precessRecord == null) { 8978 throw new SecurityException("Unknown process: " + callingPid); 8979 } 8980 if (precessRecord.instrumentationUiAutomationConnection == null) { 8981 throw new SecurityException("Only an instrumentation process " 8982 + "with a UiAutomation can call setUserIsMonkey"); 8983 } 8984 } 8985 mUserIsMonkey = userIsMonkey; 8986 } 8987 } 8988 8989 @Override 8990 public boolean isUserAMonkey() { 8991 synchronized (this) { 8992 // If there is a controller also implies the user is a monkey. 8993 return (mUserIsMonkey || mController != null); 8994 } 8995 } 8996 8997 public void requestBugReport() { 8998 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8999 SystemProperties.set("ctl.start", "bugreport"); 9000 } 9001 9002 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9003 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9004 } 9005 9006 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9007 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9008 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9009 } 9010 return KEY_DISPATCHING_TIMEOUT; 9011 } 9012 9013 @Override 9014 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9015 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9016 != PackageManager.PERMISSION_GRANTED) { 9017 throw new SecurityException("Requires permission " 9018 + android.Manifest.permission.FILTER_EVENTS); 9019 } 9020 ProcessRecord proc; 9021 long timeout; 9022 synchronized (this) { 9023 synchronized (mPidsSelfLocked) { 9024 proc = mPidsSelfLocked.get(pid); 9025 } 9026 timeout = getInputDispatchingTimeoutLocked(proc); 9027 } 9028 9029 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9030 return -1; 9031 } 9032 9033 return timeout; 9034 } 9035 9036 /** 9037 * Handle input dispatching timeouts. 9038 * Returns whether input dispatching should be aborted or not. 9039 */ 9040 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9041 final ActivityRecord activity, final ActivityRecord parent, 9042 final boolean aboveSystem, String reason) { 9043 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9044 != PackageManager.PERMISSION_GRANTED) { 9045 throw new SecurityException("Requires permission " 9046 + android.Manifest.permission.FILTER_EVENTS); 9047 } 9048 9049 final String annotation; 9050 if (reason == null) { 9051 annotation = "Input dispatching timed out"; 9052 } else { 9053 annotation = "Input dispatching timed out (" + reason + ")"; 9054 } 9055 9056 if (proc != null) { 9057 synchronized (this) { 9058 if (proc.debugging) { 9059 return false; 9060 } 9061 9062 if (mDidDexOpt) { 9063 // Give more time since we were dexopting. 9064 mDidDexOpt = false; 9065 return false; 9066 } 9067 9068 if (proc.instrumentationClass != null) { 9069 Bundle info = new Bundle(); 9070 info.putString("shortMsg", "keyDispatchingTimedOut"); 9071 info.putString("longMsg", annotation); 9072 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9073 return true; 9074 } 9075 } 9076 mHandler.post(new Runnable() { 9077 @Override 9078 public void run() { 9079 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9080 } 9081 }); 9082 } 9083 9084 return true; 9085 } 9086 9087 public Bundle getAssistContextExtras(int requestType) { 9088 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9089 "getAssistContextExtras()"); 9090 PendingAssistExtras pae; 9091 Bundle extras = new Bundle(); 9092 synchronized (this) { 9093 ActivityRecord activity = getFocusedStack().mResumedActivity; 9094 if (activity == null) { 9095 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9096 return null; 9097 } 9098 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9099 if (activity.app == null || activity.app.thread == null) { 9100 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9101 return extras; 9102 } 9103 if (activity.app.pid == Binder.getCallingPid()) { 9104 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9105 return extras; 9106 } 9107 pae = new PendingAssistExtras(activity); 9108 try { 9109 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9110 requestType); 9111 mPendingAssistExtras.add(pae); 9112 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9113 } catch (RemoteException e) { 9114 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9115 return extras; 9116 } 9117 } 9118 synchronized (pae) { 9119 while (!pae.haveResult) { 9120 try { 9121 pae.wait(); 9122 } catch (InterruptedException e) { 9123 } 9124 } 9125 if (pae.result != null) { 9126 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9127 } 9128 } 9129 synchronized (this) { 9130 mPendingAssistExtras.remove(pae); 9131 mHandler.removeCallbacks(pae); 9132 } 9133 return extras; 9134 } 9135 9136 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9137 PendingAssistExtras pae = (PendingAssistExtras)token; 9138 synchronized (pae) { 9139 pae.result = extras; 9140 pae.haveResult = true; 9141 pae.notifyAll(); 9142 } 9143 } 9144 9145 public void registerProcessObserver(IProcessObserver observer) { 9146 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9147 "registerProcessObserver()"); 9148 synchronized (this) { 9149 mProcessObservers.register(observer); 9150 } 9151 } 9152 9153 @Override 9154 public void unregisterProcessObserver(IProcessObserver observer) { 9155 synchronized (this) { 9156 mProcessObservers.unregister(observer); 9157 } 9158 } 9159 9160 @Override 9161 public boolean convertFromTranslucent(IBinder token) { 9162 final long origId = Binder.clearCallingIdentity(); 9163 try { 9164 synchronized (this) { 9165 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9166 if (r == null) { 9167 return false; 9168 } 9169 if (r.changeWindowTranslucency(true)) { 9170 mWindowManager.setAppFullscreen(token, true); 9171 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9172 return true; 9173 } 9174 return false; 9175 } 9176 } finally { 9177 Binder.restoreCallingIdentity(origId); 9178 } 9179 } 9180 9181 @Override 9182 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9183 final long origId = Binder.clearCallingIdentity(); 9184 try { 9185 synchronized (this) { 9186 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9187 if (r == null) { 9188 return false; 9189 } 9190 if (r.changeWindowTranslucency(false)) { 9191 r.task.stack.convertToTranslucent(r, options); 9192 mWindowManager.setAppFullscreen(token, false); 9193 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9194 return true; 9195 } 9196 return false; 9197 } 9198 } finally { 9199 Binder.restoreCallingIdentity(origId); 9200 } 9201 } 9202 9203 @Override 9204 public ActivityOptions getActivityOptions(IBinder token) { 9205 final long origId = Binder.clearCallingIdentity(); 9206 try { 9207 synchronized (this) { 9208 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9209 if (r != null) { 9210 final ActivityOptions activityOptions = r.pendingOptions; 9211 r.pendingOptions = null; 9212 return activityOptions; 9213 } 9214 return null; 9215 } 9216 } finally { 9217 Binder.restoreCallingIdentity(origId); 9218 } 9219 } 9220 9221 @Override 9222 public void setImmersive(IBinder token, boolean immersive) { 9223 synchronized(this) { 9224 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9225 if (r == null) { 9226 throw new IllegalArgumentException(); 9227 } 9228 r.immersive = immersive; 9229 9230 // update associated state if we're frontmost 9231 if (r == mFocusedActivity) { 9232 if (DEBUG_IMMERSIVE) { 9233 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9234 } 9235 applyUpdateLockStateLocked(r); 9236 } 9237 } 9238 } 9239 9240 @Override 9241 public boolean isImmersive(IBinder token) { 9242 synchronized (this) { 9243 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9244 if (r == null) { 9245 throw new IllegalArgumentException(); 9246 } 9247 return r.immersive; 9248 } 9249 } 9250 9251 public boolean isTopActivityImmersive() { 9252 enforceNotIsolatedCaller("startActivity"); 9253 synchronized (this) { 9254 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9255 return (r != null) ? r.immersive : false; 9256 } 9257 } 9258 9259 public final void enterSafeMode() { 9260 synchronized(this) { 9261 // It only makes sense to do this before the system is ready 9262 // and started launching other packages. 9263 if (!mSystemReady) { 9264 try { 9265 AppGlobals.getPackageManager().enterSafeMode(); 9266 } catch (RemoteException e) { 9267 } 9268 } 9269 9270 mSafeMode = true; 9271 } 9272 } 9273 9274 public final void showSafeModeOverlay() { 9275 View v = LayoutInflater.from(mContext).inflate( 9276 com.android.internal.R.layout.safe_mode, null); 9277 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9278 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9279 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9280 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9281 lp.gravity = Gravity.BOTTOM | Gravity.START; 9282 lp.format = v.getBackground().getOpacity(); 9283 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9284 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9285 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9286 ((WindowManager)mContext.getSystemService( 9287 Context.WINDOW_SERVICE)).addView(v, lp); 9288 } 9289 9290 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9291 if (!(sender instanceof PendingIntentRecord)) { 9292 return; 9293 } 9294 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9295 synchronized (stats) { 9296 if (mBatteryStatsService.isOnBattery()) { 9297 mBatteryStatsService.enforceCallingPermission(); 9298 PendingIntentRecord rec = (PendingIntentRecord)sender; 9299 int MY_UID = Binder.getCallingUid(); 9300 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9301 BatteryStatsImpl.Uid.Pkg pkg = 9302 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9303 sourcePkg != null ? sourcePkg : rec.key.packageName); 9304 pkg.incWakeupsLocked(); 9305 } 9306 } 9307 } 9308 9309 public boolean killPids(int[] pids, String pReason, boolean secure) { 9310 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9311 throw new SecurityException("killPids only available to the system"); 9312 } 9313 String reason = (pReason == null) ? "Unknown" : pReason; 9314 // XXX Note: don't acquire main activity lock here, because the window 9315 // manager calls in with its locks held. 9316 9317 boolean killed = false; 9318 synchronized (mPidsSelfLocked) { 9319 int[] types = new int[pids.length]; 9320 int worstType = 0; 9321 for (int i=0; i<pids.length; i++) { 9322 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9323 if (proc != null) { 9324 int type = proc.setAdj; 9325 types[i] = type; 9326 if (type > worstType) { 9327 worstType = type; 9328 } 9329 } 9330 } 9331 9332 // If the worst oom_adj is somewhere in the cached proc LRU range, 9333 // then constrain it so we will kill all cached procs. 9334 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9335 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9336 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9337 } 9338 9339 // If this is not a secure call, don't let it kill processes that 9340 // are important. 9341 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9342 worstType = ProcessList.SERVICE_ADJ; 9343 } 9344 9345 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9346 for (int i=0; i<pids.length; i++) { 9347 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9348 if (proc == null) { 9349 continue; 9350 } 9351 int adj = proc.setAdj; 9352 if (adj >= worstType && !proc.killedByAm) { 9353 killUnneededProcessLocked(proc, reason); 9354 killed = true; 9355 } 9356 } 9357 } 9358 return killed; 9359 } 9360 9361 @Override 9362 public void killUid(int uid, String reason) { 9363 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9364 throw new SecurityException("killUid only available to the system"); 9365 } 9366 synchronized (this) { 9367 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9368 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9369 reason != null ? reason : "kill uid"); 9370 } 9371 } 9372 9373 @Override 9374 public boolean killProcessesBelowForeground(String reason) { 9375 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9376 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9377 } 9378 9379 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9380 } 9381 9382 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9383 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9384 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9385 } 9386 9387 boolean killed = false; 9388 synchronized (mPidsSelfLocked) { 9389 final int size = mPidsSelfLocked.size(); 9390 for (int i = 0; i < size; i++) { 9391 final int pid = mPidsSelfLocked.keyAt(i); 9392 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9393 if (proc == null) continue; 9394 9395 final int adj = proc.setAdj; 9396 if (adj > belowAdj && !proc.killedByAm) { 9397 killUnneededProcessLocked(proc, reason); 9398 killed = true; 9399 } 9400 } 9401 } 9402 return killed; 9403 } 9404 9405 @Override 9406 public void hang(final IBinder who, boolean allowRestart) { 9407 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9408 != PackageManager.PERMISSION_GRANTED) { 9409 throw new SecurityException("Requires permission " 9410 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9411 } 9412 9413 final IBinder.DeathRecipient death = new DeathRecipient() { 9414 @Override 9415 public void binderDied() { 9416 synchronized (this) { 9417 notifyAll(); 9418 } 9419 } 9420 }; 9421 9422 try { 9423 who.linkToDeath(death, 0); 9424 } catch (RemoteException e) { 9425 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9426 return; 9427 } 9428 9429 synchronized (this) { 9430 Watchdog.getInstance().setAllowRestart(allowRestart); 9431 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9432 synchronized (death) { 9433 while (who.isBinderAlive()) { 9434 try { 9435 death.wait(); 9436 } catch (InterruptedException e) { 9437 } 9438 } 9439 } 9440 Watchdog.getInstance().setAllowRestart(true); 9441 } 9442 } 9443 9444 @Override 9445 public void restart() { 9446 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9447 != PackageManager.PERMISSION_GRANTED) { 9448 throw new SecurityException("Requires permission " 9449 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9450 } 9451 9452 Log.i(TAG, "Sending shutdown broadcast..."); 9453 9454 BroadcastReceiver br = new BroadcastReceiver() { 9455 @Override public void onReceive(Context context, Intent intent) { 9456 // Now the broadcast is done, finish up the low-level shutdown. 9457 Log.i(TAG, "Shutting down activity manager..."); 9458 shutdown(10000); 9459 Log.i(TAG, "Shutdown complete, restarting!"); 9460 Process.killProcess(Process.myPid()); 9461 System.exit(10); 9462 } 9463 }; 9464 9465 // First send the high-level shut down broadcast. 9466 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9467 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9468 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9469 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9470 mContext.sendOrderedBroadcastAsUser(intent, 9471 UserHandle.ALL, null, br, mHandler, 0, null, null); 9472 */ 9473 br.onReceive(mContext, intent); 9474 } 9475 9476 private long getLowRamTimeSinceIdle(long now) { 9477 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9478 } 9479 9480 @Override 9481 public void performIdleMaintenance() { 9482 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9483 != PackageManager.PERMISSION_GRANTED) { 9484 throw new SecurityException("Requires permission " 9485 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9486 } 9487 9488 synchronized (this) { 9489 final long now = SystemClock.uptimeMillis(); 9490 final long timeSinceLastIdle = now - mLastIdleTime; 9491 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9492 mLastIdleTime = now; 9493 mLowRamTimeSinceLastIdle = 0; 9494 if (mLowRamStartTime != 0) { 9495 mLowRamStartTime = now; 9496 } 9497 9498 StringBuilder sb = new StringBuilder(128); 9499 sb.append("Idle maintenance over "); 9500 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9501 sb.append(" low RAM for "); 9502 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9503 Slog.i(TAG, sb.toString()); 9504 9505 // If at least 1/3 of our time since the last idle period has been spent 9506 // with RAM low, then we want to kill processes. 9507 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9508 9509 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9510 ProcessRecord proc = mLruProcesses.get(i); 9511 if (proc.notCachedSinceIdle) { 9512 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9513 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9514 if (doKilling && proc.initialIdlePss != 0 9515 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9516 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9517 + " from " + proc.initialIdlePss + ")"); 9518 } 9519 } 9520 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9521 proc.notCachedSinceIdle = true; 9522 proc.initialIdlePss = 0; 9523 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9524 isSleeping(), now); 9525 } 9526 } 9527 9528 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9529 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9530 } 9531 } 9532 9533 private void retrieveSettings() { 9534 final ContentResolver resolver = mContext.getContentResolver(); 9535 String debugApp = Settings.Global.getString( 9536 resolver, Settings.Global.DEBUG_APP); 9537 boolean waitForDebugger = Settings.Global.getInt( 9538 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9539 boolean alwaysFinishActivities = Settings.Global.getInt( 9540 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9541 boolean forceRtl = Settings.Global.getInt( 9542 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9543 // Transfer any global setting for forcing RTL layout, into a System Property 9544 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9545 9546 Configuration configuration = new Configuration(); 9547 Settings.System.getConfiguration(resolver, configuration); 9548 if (forceRtl) { 9549 // This will take care of setting the correct layout direction flags 9550 configuration.setLayoutDirection(configuration.locale); 9551 } 9552 9553 synchronized (this) { 9554 mDebugApp = mOrigDebugApp = debugApp; 9555 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9556 mAlwaysFinishActivities = alwaysFinishActivities; 9557 // This happens before any activities are started, so we can 9558 // change mConfiguration in-place. 9559 updateConfigurationLocked(configuration, null, false, true); 9560 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9561 } 9562 } 9563 9564 public boolean testIsSystemReady() { 9565 // no need to synchronize(this) just to read & return the value 9566 return mSystemReady; 9567 } 9568 9569 private static File getCalledPreBootReceiversFile() { 9570 File dataDir = Environment.getDataDirectory(); 9571 File systemDir = new File(dataDir, "system"); 9572 File fname = new File(systemDir, "called_pre_boots.dat"); 9573 return fname; 9574 } 9575 9576 static final int LAST_DONE_VERSION = 10000; 9577 9578 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9579 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9580 File file = getCalledPreBootReceiversFile(); 9581 FileInputStream fis = null; 9582 try { 9583 fis = new FileInputStream(file); 9584 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9585 int fvers = dis.readInt(); 9586 if (fvers == LAST_DONE_VERSION) { 9587 String vers = dis.readUTF(); 9588 String codename = dis.readUTF(); 9589 String build = dis.readUTF(); 9590 if (android.os.Build.VERSION.RELEASE.equals(vers) 9591 && android.os.Build.VERSION.CODENAME.equals(codename) 9592 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9593 int num = dis.readInt(); 9594 while (num > 0) { 9595 num--; 9596 String pkg = dis.readUTF(); 9597 String cls = dis.readUTF(); 9598 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9599 } 9600 } 9601 } 9602 } catch (FileNotFoundException e) { 9603 } catch (IOException e) { 9604 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9605 } finally { 9606 if (fis != null) { 9607 try { 9608 fis.close(); 9609 } catch (IOException e) { 9610 } 9611 } 9612 } 9613 return lastDoneReceivers; 9614 } 9615 9616 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9617 File file = getCalledPreBootReceiversFile(); 9618 FileOutputStream fos = null; 9619 DataOutputStream dos = null; 9620 try { 9621 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9622 fos = new FileOutputStream(file); 9623 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9624 dos.writeInt(LAST_DONE_VERSION); 9625 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9626 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9627 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9628 dos.writeInt(list.size()); 9629 for (int i=0; i<list.size(); i++) { 9630 dos.writeUTF(list.get(i).getPackageName()); 9631 dos.writeUTF(list.get(i).getClassName()); 9632 } 9633 } catch (IOException e) { 9634 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9635 file.delete(); 9636 } finally { 9637 FileUtils.sync(fos); 9638 if (dos != null) { 9639 try { 9640 dos.close(); 9641 } catch (IOException e) { 9642 // TODO Auto-generated catch block 9643 e.printStackTrace(); 9644 } 9645 } 9646 } 9647 } 9648 9649 public void systemReady(final Runnable goingCallback) { 9650 synchronized(this) { 9651 if (mSystemReady) { 9652 if (goingCallback != null) goingCallback.run(); 9653 return; 9654 } 9655 9656 if (mRecentTasks == null) { 9657 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9658 if (!mRecentTasks.isEmpty()) { 9659 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9660 } 9661 mTaskPersister.startPersisting(); 9662 } 9663 9664 // Check to see if there are any update receivers to run. 9665 if (!mDidUpdate) { 9666 if (mWaitingUpdate) { 9667 return; 9668 } 9669 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9670 List<ResolveInfo> ris = null; 9671 try { 9672 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9673 intent, null, 0, 0); 9674 } catch (RemoteException e) { 9675 } 9676 if (ris != null) { 9677 for (int i=ris.size()-1; i>=0; i--) { 9678 if ((ris.get(i).activityInfo.applicationInfo.flags 9679 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9680 ris.remove(i); 9681 } 9682 } 9683 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9684 9685 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9686 9687 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9688 for (int i=0; i<ris.size(); i++) { 9689 ActivityInfo ai = ris.get(i).activityInfo; 9690 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9691 if (lastDoneReceivers.contains(comp)) { 9692 // We already did the pre boot receiver for this app with the current 9693 // platform version, so don't do it again... 9694 ris.remove(i); 9695 i--; 9696 // ...however, do keep it as one that has been done, so we don't 9697 // forget about it when rewriting the file of last done receivers. 9698 doneReceivers.add(comp); 9699 } 9700 } 9701 9702 final int[] users = getUsersLocked(); 9703 for (int i=0; i<ris.size(); i++) { 9704 ActivityInfo ai = ris.get(i).activityInfo; 9705 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9706 doneReceivers.add(comp); 9707 intent.setComponent(comp); 9708 for (int j=0; j<users.length; j++) { 9709 IIntentReceiver finisher = null; 9710 if (i == ris.size()-1 && j == users.length-1) { 9711 finisher = new IIntentReceiver.Stub() { 9712 public void performReceive(Intent intent, int resultCode, 9713 String data, Bundle extras, boolean ordered, 9714 boolean sticky, int sendingUser) { 9715 // The raw IIntentReceiver interface is called 9716 // with the AM lock held, so redispatch to 9717 // execute our code without the lock. 9718 mHandler.post(new Runnable() { 9719 public void run() { 9720 synchronized (ActivityManagerService.this) { 9721 mDidUpdate = true; 9722 } 9723 writeLastDonePreBootReceivers(doneReceivers); 9724 showBootMessage(mContext.getText( 9725 R.string.android_upgrading_complete), 9726 false); 9727 systemReady(goingCallback); 9728 } 9729 }); 9730 } 9731 }; 9732 } 9733 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9734 + " for user " + users[j]); 9735 broadcastIntentLocked(null, null, intent, null, finisher, 9736 0, null, null, null, AppOpsManager.OP_NONE, 9737 true, false, MY_PID, Process.SYSTEM_UID, 9738 users[j]); 9739 if (finisher != null) { 9740 mWaitingUpdate = true; 9741 } 9742 } 9743 } 9744 } 9745 if (mWaitingUpdate) { 9746 return; 9747 } 9748 mDidUpdate = true; 9749 } 9750 9751 mAppOpsService.systemReady(); 9752 mUsageStatsService.systemReady(); 9753 mSystemReady = true; 9754 } 9755 9756 ArrayList<ProcessRecord> procsToKill = null; 9757 synchronized(mPidsSelfLocked) { 9758 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9759 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9760 if (!isAllowedWhileBooting(proc.info)){ 9761 if (procsToKill == null) { 9762 procsToKill = new ArrayList<ProcessRecord>(); 9763 } 9764 procsToKill.add(proc); 9765 } 9766 } 9767 } 9768 9769 synchronized(this) { 9770 if (procsToKill != null) { 9771 for (int i=procsToKill.size()-1; i>=0; i--) { 9772 ProcessRecord proc = procsToKill.get(i); 9773 Slog.i(TAG, "Removing system update proc: " + proc); 9774 removeProcessLocked(proc, true, false, "system update done"); 9775 } 9776 } 9777 9778 // Now that we have cleaned up any update processes, we 9779 // are ready to start launching real processes and know that 9780 // we won't trample on them any more. 9781 mProcessesReady = true; 9782 } 9783 9784 Slog.i(TAG, "System now ready"); 9785 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9786 SystemClock.uptimeMillis()); 9787 9788 synchronized(this) { 9789 // Make sure we have no pre-ready processes sitting around. 9790 9791 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9792 ResolveInfo ri = mContext.getPackageManager() 9793 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9794 STOCK_PM_FLAGS); 9795 CharSequence errorMsg = null; 9796 if (ri != null) { 9797 ActivityInfo ai = ri.activityInfo; 9798 ApplicationInfo app = ai.applicationInfo; 9799 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9800 mTopAction = Intent.ACTION_FACTORY_TEST; 9801 mTopData = null; 9802 mTopComponent = new ComponentName(app.packageName, 9803 ai.name); 9804 } else { 9805 errorMsg = mContext.getResources().getText( 9806 com.android.internal.R.string.factorytest_not_system); 9807 } 9808 } else { 9809 errorMsg = mContext.getResources().getText( 9810 com.android.internal.R.string.factorytest_no_action); 9811 } 9812 if (errorMsg != null) { 9813 mTopAction = null; 9814 mTopData = null; 9815 mTopComponent = null; 9816 Message msg = Message.obtain(); 9817 msg.what = SHOW_FACTORY_ERROR_MSG; 9818 msg.getData().putCharSequence("msg", errorMsg); 9819 mHandler.sendMessage(msg); 9820 } 9821 } 9822 } 9823 9824 retrieveSettings(); 9825 9826 synchronized (this) { 9827 readGrantedUriPermissionsLocked(); 9828 } 9829 9830 if (goingCallback != null) goingCallback.run(); 9831 9832 mSystemServiceManager.startUser(mCurrentUserId); 9833 9834 synchronized (this) { 9835 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9836 try { 9837 List apps = AppGlobals.getPackageManager(). 9838 getPersistentApplications(STOCK_PM_FLAGS); 9839 if (apps != null) { 9840 int N = apps.size(); 9841 int i; 9842 for (i=0; i<N; i++) { 9843 ApplicationInfo info 9844 = (ApplicationInfo)apps.get(i); 9845 if (info != null && 9846 !info.packageName.equals("android")) { 9847 addAppLocked(info, false, null /* ABI override */); 9848 } 9849 } 9850 } 9851 } catch (RemoteException ex) { 9852 // pm is in same process, this will never happen. 9853 } 9854 } 9855 9856 // Start up initial activity. 9857 mBooting = true; 9858 9859 try { 9860 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9861 Message msg = Message.obtain(); 9862 msg.what = SHOW_UID_ERROR_MSG; 9863 mHandler.sendMessage(msg); 9864 } 9865 } catch (RemoteException e) { 9866 } 9867 9868 long ident = Binder.clearCallingIdentity(); 9869 try { 9870 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9871 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9872 | Intent.FLAG_RECEIVER_FOREGROUND); 9873 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9874 broadcastIntentLocked(null, null, intent, 9875 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9876 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9877 intent = new Intent(Intent.ACTION_USER_STARTING); 9878 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9879 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9880 broadcastIntentLocked(null, null, intent, 9881 null, new IIntentReceiver.Stub() { 9882 @Override 9883 public void performReceive(Intent intent, int resultCode, String data, 9884 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9885 throws RemoteException { 9886 } 9887 }, 0, null, null, 9888 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9889 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9890 } catch (Throwable t) { 9891 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9892 } finally { 9893 Binder.restoreCallingIdentity(ident); 9894 } 9895 mStackSupervisor.resumeTopActivitiesLocked(); 9896 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9897 } 9898 } 9899 9900 private boolean makeAppCrashingLocked(ProcessRecord app, 9901 String shortMsg, String longMsg, String stackTrace) { 9902 app.crashing = true; 9903 app.crashingReport = generateProcessError(app, 9904 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9905 startAppProblemLocked(app); 9906 app.stopFreezingAllLocked(); 9907 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9908 } 9909 9910 private void makeAppNotRespondingLocked(ProcessRecord app, 9911 String activity, String shortMsg, String longMsg) { 9912 app.notResponding = true; 9913 app.notRespondingReport = generateProcessError(app, 9914 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9915 activity, shortMsg, longMsg, null); 9916 startAppProblemLocked(app); 9917 app.stopFreezingAllLocked(); 9918 } 9919 9920 /** 9921 * Generate a process error record, suitable for attachment to a ProcessRecord. 9922 * 9923 * @param app The ProcessRecord in which the error occurred. 9924 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9925 * ActivityManager.AppErrorStateInfo 9926 * @param activity The activity associated with the crash, if known. 9927 * @param shortMsg Short message describing the crash. 9928 * @param longMsg Long message describing the crash. 9929 * @param stackTrace Full crash stack trace, may be null. 9930 * 9931 * @return Returns a fully-formed AppErrorStateInfo record. 9932 */ 9933 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9934 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9935 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9936 9937 report.condition = condition; 9938 report.processName = app.processName; 9939 report.pid = app.pid; 9940 report.uid = app.info.uid; 9941 report.tag = activity; 9942 report.shortMsg = shortMsg; 9943 report.longMsg = longMsg; 9944 report.stackTrace = stackTrace; 9945 9946 return report; 9947 } 9948 9949 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9950 synchronized (this) { 9951 app.crashing = false; 9952 app.crashingReport = null; 9953 app.notResponding = false; 9954 app.notRespondingReport = null; 9955 if (app.anrDialog == fromDialog) { 9956 app.anrDialog = null; 9957 } 9958 if (app.waitDialog == fromDialog) { 9959 app.waitDialog = null; 9960 } 9961 if (app.pid > 0 && app.pid != MY_PID) { 9962 handleAppCrashLocked(app, null, null, null); 9963 killUnneededProcessLocked(app, "user request after error"); 9964 } 9965 } 9966 } 9967 9968 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9969 String stackTrace) { 9970 long now = SystemClock.uptimeMillis(); 9971 9972 Long crashTime; 9973 if (!app.isolated) { 9974 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9975 } else { 9976 crashTime = null; 9977 } 9978 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9979 // This process loses! 9980 Slog.w(TAG, "Process " + app.info.processName 9981 + " has crashed too many times: killing!"); 9982 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9983 app.userId, app.info.processName, app.uid); 9984 mStackSupervisor.handleAppCrashLocked(app); 9985 if (!app.persistent) { 9986 // We don't want to start this process again until the user 9987 // explicitly does so... but for persistent process, we really 9988 // need to keep it running. If a persistent process is actually 9989 // repeatedly crashing, then badness for everyone. 9990 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9991 app.info.processName); 9992 if (!app.isolated) { 9993 // XXX We don't have a way to mark isolated processes 9994 // as bad, since they don't have a peristent identity. 9995 mBadProcesses.put(app.info.processName, app.uid, 9996 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9997 mProcessCrashTimes.remove(app.info.processName, app.uid); 9998 } 9999 app.bad = true; 10000 app.removed = true; 10001 // Don't let services in this process be restarted and potentially 10002 // annoy the user repeatedly. Unless it is persistent, since those 10003 // processes run critical code. 10004 removeProcessLocked(app, false, false, "crash"); 10005 mStackSupervisor.resumeTopActivitiesLocked(); 10006 return false; 10007 } 10008 mStackSupervisor.resumeTopActivitiesLocked(); 10009 } else { 10010 mStackSupervisor.finishTopRunningActivityLocked(app); 10011 } 10012 10013 // Bump up the crash count of any services currently running in the proc. 10014 for (int i=app.services.size()-1; i>=0; i--) { 10015 // Any services running in the application need to be placed 10016 // back in the pending list. 10017 ServiceRecord sr = app.services.valueAt(i); 10018 sr.crashCount++; 10019 } 10020 10021 // If the crashing process is what we consider to be the "home process" and it has been 10022 // replaced by a third-party app, clear the package preferred activities from packages 10023 // with a home activity running in the process to prevent a repeatedly crashing app 10024 // from blocking the user to manually clear the list. 10025 final ArrayList<ActivityRecord> activities = app.activities; 10026 if (app == mHomeProcess && activities.size() > 0 10027 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10028 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10029 final ActivityRecord r = activities.get(activityNdx); 10030 if (r.isHomeActivity()) { 10031 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10032 try { 10033 ActivityThread.getPackageManager() 10034 .clearPackagePreferredActivities(r.packageName); 10035 } catch (RemoteException c) { 10036 // pm is in same process, this will never happen. 10037 } 10038 } 10039 } 10040 } 10041 10042 if (!app.isolated) { 10043 // XXX Can't keep track of crash times for isolated processes, 10044 // because they don't have a perisistent identity. 10045 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10046 } 10047 10048 return true; 10049 } 10050 10051 void startAppProblemLocked(ProcessRecord app) { 10052 if (app.userId == mCurrentUserId) { 10053 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10054 mContext, app.info.packageName, app.info.flags); 10055 } else { 10056 // If this app is not running under the current user, then we 10057 // can't give it a report button because that would require 10058 // launching the report UI under a different user. 10059 app.errorReportReceiver = null; 10060 } 10061 skipCurrentReceiverLocked(app); 10062 } 10063 10064 void skipCurrentReceiverLocked(ProcessRecord app) { 10065 for (BroadcastQueue queue : mBroadcastQueues) { 10066 queue.skipCurrentReceiverLocked(app); 10067 } 10068 } 10069 10070 /** 10071 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10072 * The application process will exit immediately after this call returns. 10073 * @param app object of the crashing app, null for the system server 10074 * @param crashInfo describing the exception 10075 */ 10076 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10077 ProcessRecord r = findAppProcess(app, "Crash"); 10078 final String processName = app == null ? "system_server" 10079 : (r == null ? "unknown" : r.processName); 10080 10081 handleApplicationCrashInner("crash", r, processName, crashInfo); 10082 } 10083 10084 /* Native crash reporting uses this inner version because it needs to be somewhat 10085 * decoupled from the AM-managed cleanup lifecycle 10086 */ 10087 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10088 ApplicationErrorReport.CrashInfo crashInfo) { 10089 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10090 UserHandle.getUserId(Binder.getCallingUid()), processName, 10091 r == null ? -1 : r.info.flags, 10092 crashInfo.exceptionClassName, 10093 crashInfo.exceptionMessage, 10094 crashInfo.throwFileName, 10095 crashInfo.throwLineNumber); 10096 10097 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10098 10099 crashApplication(r, crashInfo); 10100 } 10101 10102 public void handleApplicationStrictModeViolation( 10103 IBinder app, 10104 int violationMask, 10105 StrictMode.ViolationInfo info) { 10106 ProcessRecord r = findAppProcess(app, "StrictMode"); 10107 if (r == null) { 10108 return; 10109 } 10110 10111 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10112 Integer stackFingerprint = info.hashCode(); 10113 boolean logIt = true; 10114 synchronized (mAlreadyLoggedViolatedStacks) { 10115 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10116 logIt = false; 10117 // TODO: sub-sample into EventLog for these, with 10118 // the info.durationMillis? Then we'd get 10119 // the relative pain numbers, without logging all 10120 // the stack traces repeatedly. We'd want to do 10121 // likewise in the client code, which also does 10122 // dup suppression, before the Binder call. 10123 } else { 10124 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10125 mAlreadyLoggedViolatedStacks.clear(); 10126 } 10127 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10128 } 10129 } 10130 if (logIt) { 10131 logStrictModeViolationToDropBox(r, info); 10132 } 10133 } 10134 10135 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10136 AppErrorResult result = new AppErrorResult(); 10137 synchronized (this) { 10138 final long origId = Binder.clearCallingIdentity(); 10139 10140 Message msg = Message.obtain(); 10141 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10142 HashMap<String, Object> data = new HashMap<String, Object>(); 10143 data.put("result", result); 10144 data.put("app", r); 10145 data.put("violationMask", violationMask); 10146 data.put("info", info); 10147 msg.obj = data; 10148 mHandler.sendMessage(msg); 10149 10150 Binder.restoreCallingIdentity(origId); 10151 } 10152 int res = result.get(); 10153 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10154 } 10155 } 10156 10157 // Depending on the policy in effect, there could be a bunch of 10158 // these in quick succession so we try to batch these together to 10159 // minimize disk writes, number of dropbox entries, and maximize 10160 // compression, by having more fewer, larger records. 10161 private void logStrictModeViolationToDropBox( 10162 ProcessRecord process, 10163 StrictMode.ViolationInfo info) { 10164 if (info == null) { 10165 return; 10166 } 10167 final boolean isSystemApp = process == null || 10168 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10169 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10170 final String processName = process == null ? "unknown" : process.processName; 10171 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10172 final DropBoxManager dbox = (DropBoxManager) 10173 mContext.getSystemService(Context.DROPBOX_SERVICE); 10174 10175 // Exit early if the dropbox isn't configured to accept this report type. 10176 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10177 10178 boolean bufferWasEmpty; 10179 boolean needsFlush; 10180 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10181 synchronized (sb) { 10182 bufferWasEmpty = sb.length() == 0; 10183 appendDropBoxProcessHeaders(process, processName, sb); 10184 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10185 sb.append("System-App: ").append(isSystemApp).append("\n"); 10186 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10187 if (info.violationNumThisLoop != 0) { 10188 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10189 } 10190 if (info.numAnimationsRunning != 0) { 10191 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10192 } 10193 if (info.broadcastIntentAction != null) { 10194 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10195 } 10196 if (info.durationMillis != -1) { 10197 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10198 } 10199 if (info.numInstances != -1) { 10200 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10201 } 10202 if (info.tags != null) { 10203 for (String tag : info.tags) { 10204 sb.append("Span-Tag: ").append(tag).append("\n"); 10205 } 10206 } 10207 sb.append("\n"); 10208 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10209 sb.append(info.crashInfo.stackTrace); 10210 } 10211 sb.append("\n"); 10212 10213 // Only buffer up to ~64k. Various logging bits truncate 10214 // things at 128k. 10215 needsFlush = (sb.length() > 64 * 1024); 10216 } 10217 10218 // Flush immediately if the buffer's grown too large, or this 10219 // is a non-system app. Non-system apps are isolated with a 10220 // different tag & policy and not batched. 10221 // 10222 // Batching is useful during internal testing with 10223 // StrictMode settings turned up high. Without batching, 10224 // thousands of separate files could be created on boot. 10225 if (!isSystemApp || needsFlush) { 10226 new Thread("Error dump: " + dropboxTag) { 10227 @Override 10228 public void run() { 10229 String report; 10230 synchronized (sb) { 10231 report = sb.toString(); 10232 sb.delete(0, sb.length()); 10233 sb.trimToSize(); 10234 } 10235 if (report.length() != 0) { 10236 dbox.addText(dropboxTag, report); 10237 } 10238 } 10239 }.start(); 10240 return; 10241 } 10242 10243 // System app batching: 10244 if (!bufferWasEmpty) { 10245 // An existing dropbox-writing thread is outstanding, so 10246 // we don't need to start it up. The existing thread will 10247 // catch the buffer appends we just did. 10248 return; 10249 } 10250 10251 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10252 // (After this point, we shouldn't access AMS internal data structures.) 10253 new Thread("Error dump: " + dropboxTag) { 10254 @Override 10255 public void run() { 10256 // 5 second sleep to let stacks arrive and be batched together 10257 try { 10258 Thread.sleep(5000); // 5 seconds 10259 } catch (InterruptedException e) {} 10260 10261 String errorReport; 10262 synchronized (mStrictModeBuffer) { 10263 errorReport = mStrictModeBuffer.toString(); 10264 if (errorReport.length() == 0) { 10265 return; 10266 } 10267 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10268 mStrictModeBuffer.trimToSize(); 10269 } 10270 dbox.addText(dropboxTag, errorReport); 10271 } 10272 }.start(); 10273 } 10274 10275 /** 10276 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10277 * @param app object of the crashing app, null for the system server 10278 * @param tag reported by the caller 10279 * @param crashInfo describing the context of the error 10280 * @return true if the process should exit immediately (WTF is fatal) 10281 */ 10282 public boolean handleApplicationWtf(IBinder app, String tag, 10283 ApplicationErrorReport.CrashInfo crashInfo) { 10284 ProcessRecord r = findAppProcess(app, "WTF"); 10285 final String processName = app == null ? "system_server" 10286 : (r == null ? "unknown" : r.processName); 10287 10288 EventLog.writeEvent(EventLogTags.AM_WTF, 10289 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10290 processName, 10291 r == null ? -1 : r.info.flags, 10292 tag, crashInfo.exceptionMessage); 10293 10294 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10295 10296 if (r != null && r.pid != Process.myPid() && 10297 Settings.Global.getInt(mContext.getContentResolver(), 10298 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10299 crashApplication(r, crashInfo); 10300 return true; 10301 } else { 10302 return false; 10303 } 10304 } 10305 10306 /** 10307 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10308 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10309 */ 10310 private ProcessRecord findAppProcess(IBinder app, String reason) { 10311 if (app == null) { 10312 return null; 10313 } 10314 10315 synchronized (this) { 10316 final int NP = mProcessNames.getMap().size(); 10317 for (int ip=0; ip<NP; ip++) { 10318 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10319 final int NA = apps.size(); 10320 for (int ia=0; ia<NA; ia++) { 10321 ProcessRecord p = apps.valueAt(ia); 10322 if (p.thread != null && p.thread.asBinder() == app) { 10323 return p; 10324 } 10325 } 10326 } 10327 10328 Slog.w(TAG, "Can't find mystery application for " + reason 10329 + " from pid=" + Binder.getCallingPid() 10330 + " uid=" + Binder.getCallingUid() + ": " + app); 10331 return null; 10332 } 10333 } 10334 10335 /** 10336 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10337 * to append various headers to the dropbox log text. 10338 */ 10339 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10340 StringBuilder sb) { 10341 // Watchdog thread ends up invoking this function (with 10342 // a null ProcessRecord) to add the stack file to dropbox. 10343 // Do not acquire a lock on this (am) in such cases, as it 10344 // could cause a potential deadlock, if and when watchdog 10345 // is invoked due to unavailability of lock on am and it 10346 // would prevent watchdog from killing system_server. 10347 if (process == null) { 10348 sb.append("Process: ").append(processName).append("\n"); 10349 return; 10350 } 10351 // Note: ProcessRecord 'process' is guarded by the service 10352 // instance. (notably process.pkgList, which could otherwise change 10353 // concurrently during execution of this method) 10354 synchronized (this) { 10355 sb.append("Process: ").append(processName).append("\n"); 10356 int flags = process.info.flags; 10357 IPackageManager pm = AppGlobals.getPackageManager(); 10358 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10359 for (int ip=0; ip<process.pkgList.size(); ip++) { 10360 String pkg = process.pkgList.keyAt(ip); 10361 sb.append("Package: ").append(pkg); 10362 try { 10363 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10364 if (pi != null) { 10365 sb.append(" v").append(pi.versionCode); 10366 if (pi.versionName != null) { 10367 sb.append(" (").append(pi.versionName).append(")"); 10368 } 10369 } 10370 } catch (RemoteException e) { 10371 Slog.e(TAG, "Error getting package info: " + pkg, e); 10372 } 10373 sb.append("\n"); 10374 } 10375 } 10376 } 10377 10378 private static String processClass(ProcessRecord process) { 10379 if (process == null || process.pid == MY_PID) { 10380 return "system_server"; 10381 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10382 return "system_app"; 10383 } else { 10384 return "data_app"; 10385 } 10386 } 10387 10388 /** 10389 * Write a description of an error (crash, WTF, ANR) to the drop box. 10390 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10391 * @param process which caused the error, null means the system server 10392 * @param activity which triggered the error, null if unknown 10393 * @param parent activity related to the error, null if unknown 10394 * @param subject line related to the error, null if absent 10395 * @param report in long form describing the error, null if absent 10396 * @param logFile to include in the report, null if none 10397 * @param crashInfo giving an application stack trace, null if absent 10398 */ 10399 public void addErrorToDropBox(String eventType, 10400 ProcessRecord process, String processName, ActivityRecord activity, 10401 ActivityRecord parent, String subject, 10402 final String report, final File logFile, 10403 final ApplicationErrorReport.CrashInfo crashInfo) { 10404 // NOTE -- this must never acquire the ActivityManagerService lock, 10405 // otherwise the watchdog may be prevented from resetting the system. 10406 10407 final String dropboxTag = processClass(process) + "_" + eventType; 10408 final DropBoxManager dbox = (DropBoxManager) 10409 mContext.getSystemService(Context.DROPBOX_SERVICE); 10410 10411 // Exit early if the dropbox isn't configured to accept this report type. 10412 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10413 10414 final StringBuilder sb = new StringBuilder(1024); 10415 appendDropBoxProcessHeaders(process, processName, sb); 10416 if (activity != null) { 10417 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10418 } 10419 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10420 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10421 } 10422 if (parent != null && parent != activity) { 10423 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10424 } 10425 if (subject != null) { 10426 sb.append("Subject: ").append(subject).append("\n"); 10427 } 10428 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10429 if (Debug.isDebuggerConnected()) { 10430 sb.append("Debugger: Connected\n"); 10431 } 10432 sb.append("\n"); 10433 10434 // Do the rest in a worker thread to avoid blocking the caller on I/O 10435 // (After this point, we shouldn't access AMS internal data structures.) 10436 Thread worker = new Thread("Error dump: " + dropboxTag) { 10437 @Override 10438 public void run() { 10439 if (report != null) { 10440 sb.append(report); 10441 } 10442 if (logFile != null) { 10443 try { 10444 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10445 "\n\n[[TRUNCATED]]")); 10446 } catch (IOException e) { 10447 Slog.e(TAG, "Error reading " + logFile, e); 10448 } 10449 } 10450 if (crashInfo != null && crashInfo.stackTrace != null) { 10451 sb.append(crashInfo.stackTrace); 10452 } 10453 10454 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10455 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10456 if (lines > 0) { 10457 sb.append("\n"); 10458 10459 // Merge several logcat streams, and take the last N lines 10460 InputStreamReader input = null; 10461 try { 10462 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10463 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10464 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10465 10466 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10467 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10468 input = new InputStreamReader(logcat.getInputStream()); 10469 10470 int num; 10471 char[] buf = new char[8192]; 10472 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10473 } catch (IOException e) { 10474 Slog.e(TAG, "Error running logcat", e); 10475 } finally { 10476 if (input != null) try { input.close(); } catch (IOException e) {} 10477 } 10478 } 10479 10480 dbox.addText(dropboxTag, sb.toString()); 10481 } 10482 }; 10483 10484 if (process == null) { 10485 // If process is null, we are being called from some internal code 10486 // and may be about to die -- run this synchronously. 10487 worker.run(); 10488 } else { 10489 worker.start(); 10490 } 10491 } 10492 10493 /** 10494 * Bring up the "unexpected error" dialog box for a crashing app. 10495 * Deal with edge cases (intercepts from instrumented applications, 10496 * ActivityController, error intent receivers, that sort of thing). 10497 * @param r the application crashing 10498 * @param crashInfo describing the failure 10499 */ 10500 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10501 long timeMillis = System.currentTimeMillis(); 10502 String shortMsg = crashInfo.exceptionClassName; 10503 String longMsg = crashInfo.exceptionMessage; 10504 String stackTrace = crashInfo.stackTrace; 10505 if (shortMsg != null && longMsg != null) { 10506 longMsg = shortMsg + ": " + longMsg; 10507 } else if (shortMsg != null) { 10508 longMsg = shortMsg; 10509 } 10510 10511 AppErrorResult result = new AppErrorResult(); 10512 synchronized (this) { 10513 if (mController != null) { 10514 try { 10515 String name = r != null ? r.processName : null; 10516 int pid = r != null ? r.pid : Binder.getCallingPid(); 10517 if (!mController.appCrashed(name, pid, 10518 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10519 Slog.w(TAG, "Force-killing crashed app " + name 10520 + " at watcher's request"); 10521 Process.killProcess(pid); 10522 return; 10523 } 10524 } catch (RemoteException e) { 10525 mController = null; 10526 Watchdog.getInstance().setActivityController(null); 10527 } 10528 } 10529 10530 final long origId = Binder.clearCallingIdentity(); 10531 10532 // If this process is running instrumentation, finish it. 10533 if (r != null && r.instrumentationClass != null) { 10534 Slog.w(TAG, "Error in app " + r.processName 10535 + " running instrumentation " + r.instrumentationClass + ":"); 10536 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10537 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10538 Bundle info = new Bundle(); 10539 info.putString("shortMsg", shortMsg); 10540 info.putString("longMsg", longMsg); 10541 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10542 Binder.restoreCallingIdentity(origId); 10543 return; 10544 } 10545 10546 // If we can't identify the process or it's already exceeded its crash quota, 10547 // quit right away without showing a crash dialog. 10548 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10549 Binder.restoreCallingIdentity(origId); 10550 return; 10551 } 10552 10553 Message msg = Message.obtain(); 10554 msg.what = SHOW_ERROR_MSG; 10555 HashMap data = new HashMap(); 10556 data.put("result", result); 10557 data.put("app", r); 10558 msg.obj = data; 10559 mHandler.sendMessage(msg); 10560 10561 Binder.restoreCallingIdentity(origId); 10562 } 10563 10564 int res = result.get(); 10565 10566 Intent appErrorIntent = null; 10567 synchronized (this) { 10568 if (r != null && !r.isolated) { 10569 // XXX Can't keep track of crash time for isolated processes, 10570 // since they don't have a persistent identity. 10571 mProcessCrashTimes.put(r.info.processName, r.uid, 10572 SystemClock.uptimeMillis()); 10573 } 10574 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10575 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10576 } 10577 } 10578 10579 if (appErrorIntent != null) { 10580 try { 10581 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10582 } catch (ActivityNotFoundException e) { 10583 Slog.w(TAG, "bug report receiver dissappeared", e); 10584 } 10585 } 10586 } 10587 10588 Intent createAppErrorIntentLocked(ProcessRecord r, 10589 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10590 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10591 if (report == null) { 10592 return null; 10593 } 10594 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10595 result.setComponent(r.errorReportReceiver); 10596 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10597 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10598 return result; 10599 } 10600 10601 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10602 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10603 if (r.errorReportReceiver == null) { 10604 return null; 10605 } 10606 10607 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10608 return null; 10609 } 10610 10611 ApplicationErrorReport report = new ApplicationErrorReport(); 10612 report.packageName = r.info.packageName; 10613 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10614 report.processName = r.processName; 10615 report.time = timeMillis; 10616 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10617 10618 if (r.crashing || r.forceCrashReport) { 10619 report.type = ApplicationErrorReport.TYPE_CRASH; 10620 report.crashInfo = crashInfo; 10621 } else if (r.notResponding) { 10622 report.type = ApplicationErrorReport.TYPE_ANR; 10623 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10624 10625 report.anrInfo.activity = r.notRespondingReport.tag; 10626 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10627 report.anrInfo.info = r.notRespondingReport.longMsg; 10628 } 10629 10630 return report; 10631 } 10632 10633 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10634 enforceNotIsolatedCaller("getProcessesInErrorState"); 10635 // assume our apps are happy - lazy create the list 10636 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10637 10638 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10639 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10640 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10641 10642 synchronized (this) { 10643 10644 // iterate across all processes 10645 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10646 ProcessRecord app = mLruProcesses.get(i); 10647 if (!allUsers && app.userId != userId) { 10648 continue; 10649 } 10650 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10651 // This one's in trouble, so we'll generate a report for it 10652 // crashes are higher priority (in case there's a crash *and* an anr) 10653 ActivityManager.ProcessErrorStateInfo report = null; 10654 if (app.crashing) { 10655 report = app.crashingReport; 10656 } else if (app.notResponding) { 10657 report = app.notRespondingReport; 10658 } 10659 10660 if (report != null) { 10661 if (errList == null) { 10662 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10663 } 10664 errList.add(report); 10665 } else { 10666 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10667 " crashing = " + app.crashing + 10668 " notResponding = " + app.notResponding); 10669 } 10670 } 10671 } 10672 } 10673 10674 return errList; 10675 } 10676 10677 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10678 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10679 if (currApp != null) { 10680 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10681 } 10682 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10683 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10684 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10685 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10686 if (currApp != null) { 10687 currApp.lru = 0; 10688 } 10689 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10690 } else if (adj >= ProcessList.SERVICE_ADJ) { 10691 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10692 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10693 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10694 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10695 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10696 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10697 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10698 } else { 10699 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10700 } 10701 } 10702 10703 private void fillInProcMemInfo(ProcessRecord app, 10704 ActivityManager.RunningAppProcessInfo outInfo) { 10705 outInfo.pid = app.pid; 10706 outInfo.uid = app.info.uid; 10707 if (mHeavyWeightProcess == app) { 10708 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10709 } 10710 if (app.persistent) { 10711 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10712 } 10713 if (app.activities.size() > 0) { 10714 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10715 } 10716 outInfo.lastTrimLevel = app.trimMemoryLevel; 10717 int adj = app.curAdj; 10718 outInfo.importance = oomAdjToImportance(adj, outInfo); 10719 outInfo.importanceReasonCode = app.adjTypeCode; 10720 outInfo.processState = app.curProcState; 10721 } 10722 10723 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10724 enforceNotIsolatedCaller("getRunningAppProcesses"); 10725 // Lazy instantiation of list 10726 List<ActivityManager.RunningAppProcessInfo> runList = null; 10727 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10728 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10729 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10730 synchronized (this) { 10731 // Iterate across all processes 10732 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10733 ProcessRecord app = mLruProcesses.get(i); 10734 if (!allUsers && app.userId != userId) { 10735 continue; 10736 } 10737 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10738 // Generate process state info for running application 10739 ActivityManager.RunningAppProcessInfo currApp = 10740 new ActivityManager.RunningAppProcessInfo(app.processName, 10741 app.pid, app.getPackageList()); 10742 fillInProcMemInfo(app, currApp); 10743 if (app.adjSource instanceof ProcessRecord) { 10744 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10745 currApp.importanceReasonImportance = oomAdjToImportance( 10746 app.adjSourceOom, null); 10747 } else if (app.adjSource instanceof ActivityRecord) { 10748 ActivityRecord r = (ActivityRecord)app.adjSource; 10749 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10750 } 10751 if (app.adjTarget instanceof ComponentName) { 10752 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10753 } 10754 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10755 // + " lru=" + currApp.lru); 10756 if (runList == null) { 10757 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10758 } 10759 runList.add(currApp); 10760 } 10761 } 10762 } 10763 return runList; 10764 } 10765 10766 public List<ApplicationInfo> getRunningExternalApplications() { 10767 enforceNotIsolatedCaller("getRunningExternalApplications"); 10768 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10769 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10770 if (runningApps != null && runningApps.size() > 0) { 10771 Set<String> extList = new HashSet<String>(); 10772 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10773 if (app.pkgList != null) { 10774 for (String pkg : app.pkgList) { 10775 extList.add(pkg); 10776 } 10777 } 10778 } 10779 IPackageManager pm = AppGlobals.getPackageManager(); 10780 for (String pkg : extList) { 10781 try { 10782 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10783 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10784 retList.add(info); 10785 } 10786 } catch (RemoteException e) { 10787 } 10788 } 10789 } 10790 return retList; 10791 } 10792 10793 @Override 10794 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10795 enforceNotIsolatedCaller("getMyMemoryState"); 10796 synchronized (this) { 10797 ProcessRecord proc; 10798 synchronized (mPidsSelfLocked) { 10799 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10800 } 10801 fillInProcMemInfo(proc, outInfo); 10802 } 10803 } 10804 10805 @Override 10806 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10807 if (checkCallingPermission(android.Manifest.permission.DUMP) 10808 != PackageManager.PERMISSION_GRANTED) { 10809 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10810 + Binder.getCallingPid() 10811 + ", uid=" + Binder.getCallingUid() 10812 + " without permission " 10813 + android.Manifest.permission.DUMP); 10814 return; 10815 } 10816 10817 boolean dumpAll = false; 10818 boolean dumpClient = false; 10819 String dumpPackage = null; 10820 10821 int opti = 0; 10822 while (opti < args.length) { 10823 String opt = args[opti]; 10824 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10825 break; 10826 } 10827 opti++; 10828 if ("-a".equals(opt)) { 10829 dumpAll = true; 10830 } else if ("-c".equals(opt)) { 10831 dumpClient = true; 10832 } else if ("-h".equals(opt)) { 10833 pw.println("Activity manager dump options:"); 10834 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10835 pw.println(" cmd may be one of:"); 10836 pw.println(" a[ctivities]: activity stack state"); 10837 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10838 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10839 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10840 pw.println(" o[om]: out of memory management"); 10841 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10842 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10843 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10844 pw.println(" service [COMP_SPEC]: service client-side state"); 10845 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10846 pw.println(" all: dump all activities"); 10847 pw.println(" top: dump the top activity"); 10848 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10849 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10850 pw.println(" a partial substring in a component name, a"); 10851 pw.println(" hex object identifier."); 10852 pw.println(" -a: include all available server state."); 10853 pw.println(" -c: include client state."); 10854 return; 10855 } else { 10856 pw.println("Unknown argument: " + opt + "; use -h for help"); 10857 } 10858 } 10859 10860 long origId = Binder.clearCallingIdentity(); 10861 boolean more = false; 10862 // Is the caller requesting to dump a particular piece of data? 10863 if (opti < args.length) { 10864 String cmd = args[opti]; 10865 opti++; 10866 if ("activities".equals(cmd) || "a".equals(cmd)) { 10867 synchronized (this) { 10868 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10869 } 10870 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10871 String[] newArgs; 10872 String name; 10873 if (opti >= args.length) { 10874 name = null; 10875 newArgs = EMPTY_STRING_ARRAY; 10876 } else { 10877 name = args[opti]; 10878 opti++; 10879 newArgs = new String[args.length - opti]; 10880 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10881 args.length - opti); 10882 } 10883 synchronized (this) { 10884 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10885 } 10886 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10887 String[] newArgs; 10888 String name; 10889 if (opti >= args.length) { 10890 name = null; 10891 newArgs = EMPTY_STRING_ARRAY; 10892 } else { 10893 name = args[opti]; 10894 opti++; 10895 newArgs = new String[args.length - opti]; 10896 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10897 args.length - opti); 10898 } 10899 synchronized (this) { 10900 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10901 } 10902 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10903 String[] newArgs; 10904 String name; 10905 if (opti >= args.length) { 10906 name = null; 10907 newArgs = EMPTY_STRING_ARRAY; 10908 } else { 10909 name = args[opti]; 10910 opti++; 10911 newArgs = new String[args.length - opti]; 10912 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10913 args.length - opti); 10914 } 10915 synchronized (this) { 10916 dumpProcessesLocked(fd, pw, args, opti, true, name); 10917 } 10918 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10919 synchronized (this) { 10920 dumpOomLocked(fd, pw, args, opti, true); 10921 } 10922 } else if ("provider".equals(cmd)) { 10923 String[] newArgs; 10924 String name; 10925 if (opti >= args.length) { 10926 name = null; 10927 newArgs = EMPTY_STRING_ARRAY; 10928 } else { 10929 name = args[opti]; 10930 opti++; 10931 newArgs = new String[args.length - opti]; 10932 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10933 } 10934 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10935 pw.println("No providers match: " + name); 10936 pw.println("Use -h for help."); 10937 } 10938 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10939 synchronized (this) { 10940 dumpProvidersLocked(fd, pw, args, opti, true, null); 10941 } 10942 } else if ("service".equals(cmd)) { 10943 String[] newArgs; 10944 String name; 10945 if (opti >= args.length) { 10946 name = null; 10947 newArgs = EMPTY_STRING_ARRAY; 10948 } else { 10949 name = args[opti]; 10950 opti++; 10951 newArgs = new String[args.length - opti]; 10952 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10953 args.length - opti); 10954 } 10955 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10956 pw.println("No services match: " + name); 10957 pw.println("Use -h for help."); 10958 } 10959 } else if ("package".equals(cmd)) { 10960 String[] newArgs; 10961 if (opti >= args.length) { 10962 pw.println("package: no package name specified"); 10963 pw.println("Use -h for help."); 10964 } else { 10965 dumpPackage = args[opti]; 10966 opti++; 10967 newArgs = new String[args.length - opti]; 10968 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10969 args.length - opti); 10970 args = newArgs; 10971 opti = 0; 10972 more = true; 10973 } 10974 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10975 synchronized (this) { 10976 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10977 } 10978 } else { 10979 // Dumping a single activity? 10980 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10981 pw.println("Bad activity command, or no activities match: " + cmd); 10982 pw.println("Use -h for help."); 10983 } 10984 } 10985 if (!more) { 10986 Binder.restoreCallingIdentity(origId); 10987 return; 10988 } 10989 } 10990 10991 // No piece of data specified, dump everything. 10992 synchronized (this) { 10993 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10994 pw.println(); 10995 if (dumpAll) { 10996 pw.println("-------------------------------------------------------------------------------"); 10997 } 10998 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10999 pw.println(); 11000 if (dumpAll) { 11001 pw.println("-------------------------------------------------------------------------------"); 11002 } 11003 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11004 pw.println(); 11005 if (dumpAll) { 11006 pw.println("-------------------------------------------------------------------------------"); 11007 } 11008 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11009 pw.println(); 11010 if (dumpAll) { 11011 pw.println("-------------------------------------------------------------------------------"); 11012 } 11013 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11014 pw.println(); 11015 if (dumpAll) { 11016 pw.println("-------------------------------------------------------------------------------"); 11017 } 11018 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11019 } 11020 Binder.restoreCallingIdentity(origId); 11021 } 11022 11023 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11024 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11025 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11026 11027 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11028 dumpPackage); 11029 boolean needSep = printedAnything; 11030 11031 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11032 dumpPackage, needSep, " mFocusedActivity: "); 11033 if (printed) { 11034 printedAnything = true; 11035 needSep = false; 11036 } 11037 11038 if (dumpPackage == null) { 11039 if (needSep) { 11040 pw.println(); 11041 } 11042 needSep = true; 11043 printedAnything = true; 11044 mStackSupervisor.dump(pw, " "); 11045 } 11046 11047 if (mRecentTasks.size() > 0) { 11048 boolean printedHeader = false; 11049 11050 final int N = mRecentTasks.size(); 11051 for (int i=0; i<N; i++) { 11052 TaskRecord tr = mRecentTasks.get(i); 11053 if (dumpPackage != null) { 11054 if (tr.realActivity == null || 11055 !dumpPackage.equals(tr.realActivity)) { 11056 continue; 11057 } 11058 } 11059 if (!printedHeader) { 11060 if (needSep) { 11061 pw.println(); 11062 } 11063 pw.println(" Recent tasks:"); 11064 printedHeader = true; 11065 printedAnything = true; 11066 } 11067 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11068 pw.println(tr); 11069 if (dumpAll) { 11070 mRecentTasks.get(i).dump(pw, " "); 11071 } 11072 } 11073 } 11074 11075 if (!printedAnything) { 11076 pw.println(" (nothing)"); 11077 } 11078 } 11079 11080 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11081 int opti, boolean dumpAll, String dumpPackage) { 11082 boolean needSep = false; 11083 boolean printedAnything = false; 11084 int numPers = 0; 11085 11086 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11087 11088 if (dumpAll) { 11089 final int NP = mProcessNames.getMap().size(); 11090 for (int ip=0; ip<NP; ip++) { 11091 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11092 final int NA = procs.size(); 11093 for (int ia=0; ia<NA; ia++) { 11094 ProcessRecord r = procs.valueAt(ia); 11095 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11096 continue; 11097 } 11098 if (!needSep) { 11099 pw.println(" All known processes:"); 11100 needSep = true; 11101 printedAnything = true; 11102 } 11103 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11104 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11105 pw.print(" "); pw.println(r); 11106 r.dump(pw, " "); 11107 if (r.persistent) { 11108 numPers++; 11109 } 11110 } 11111 } 11112 } 11113 11114 if (mIsolatedProcesses.size() > 0) { 11115 boolean printed = false; 11116 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11117 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11118 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11119 continue; 11120 } 11121 if (!printed) { 11122 if (needSep) { 11123 pw.println(); 11124 } 11125 pw.println(" Isolated process list (sorted by uid):"); 11126 printedAnything = true; 11127 printed = true; 11128 needSep = true; 11129 } 11130 pw.println(String.format("%sIsolated #%2d: %s", 11131 " ", i, r.toString())); 11132 } 11133 } 11134 11135 if (mLruProcesses.size() > 0) { 11136 if (needSep) { 11137 pw.println(); 11138 } 11139 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11140 pw.print(" total, non-act at "); 11141 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11142 pw.print(", non-svc at "); 11143 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11144 pw.println("):"); 11145 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11146 needSep = true; 11147 printedAnything = true; 11148 } 11149 11150 if (dumpAll || dumpPackage != null) { 11151 synchronized (mPidsSelfLocked) { 11152 boolean printed = false; 11153 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11154 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11155 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11156 continue; 11157 } 11158 if (!printed) { 11159 if (needSep) pw.println(); 11160 needSep = true; 11161 pw.println(" PID mappings:"); 11162 printed = true; 11163 printedAnything = true; 11164 } 11165 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11166 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11167 } 11168 } 11169 } 11170 11171 if (mForegroundProcesses.size() > 0) { 11172 synchronized (mPidsSelfLocked) { 11173 boolean printed = false; 11174 for (int i=0; i<mForegroundProcesses.size(); i++) { 11175 ProcessRecord r = mPidsSelfLocked.get( 11176 mForegroundProcesses.valueAt(i).pid); 11177 if (dumpPackage != null && (r == null 11178 || !r.pkgList.containsKey(dumpPackage))) { 11179 continue; 11180 } 11181 if (!printed) { 11182 if (needSep) pw.println(); 11183 needSep = true; 11184 pw.println(" Foreground Processes:"); 11185 printed = true; 11186 printedAnything = true; 11187 } 11188 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11189 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11190 } 11191 } 11192 } 11193 11194 if (mPersistentStartingProcesses.size() > 0) { 11195 if (needSep) pw.println(); 11196 needSep = true; 11197 printedAnything = true; 11198 pw.println(" Persisent processes that are starting:"); 11199 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11200 "Starting Norm", "Restarting PERS", dumpPackage); 11201 } 11202 11203 if (mRemovedProcesses.size() > 0) { 11204 if (needSep) pw.println(); 11205 needSep = true; 11206 printedAnything = true; 11207 pw.println(" Processes that are being removed:"); 11208 dumpProcessList(pw, this, mRemovedProcesses, " ", 11209 "Removed Norm", "Removed PERS", dumpPackage); 11210 } 11211 11212 if (mProcessesOnHold.size() > 0) { 11213 if (needSep) pw.println(); 11214 needSep = true; 11215 printedAnything = true; 11216 pw.println(" Processes that are on old until the system is ready:"); 11217 dumpProcessList(pw, this, mProcessesOnHold, " ", 11218 "OnHold Norm", "OnHold PERS", dumpPackage); 11219 } 11220 11221 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11222 11223 if (mProcessCrashTimes.getMap().size() > 0) { 11224 boolean printed = false; 11225 long now = SystemClock.uptimeMillis(); 11226 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11227 final int NP = pmap.size(); 11228 for (int ip=0; ip<NP; ip++) { 11229 String pname = pmap.keyAt(ip); 11230 SparseArray<Long> uids = pmap.valueAt(ip); 11231 final int N = uids.size(); 11232 for (int i=0; i<N; i++) { 11233 int puid = uids.keyAt(i); 11234 ProcessRecord r = mProcessNames.get(pname, puid); 11235 if (dumpPackage != null && (r == null 11236 || !r.pkgList.containsKey(dumpPackage))) { 11237 continue; 11238 } 11239 if (!printed) { 11240 if (needSep) pw.println(); 11241 needSep = true; 11242 pw.println(" Time since processes crashed:"); 11243 printed = true; 11244 printedAnything = true; 11245 } 11246 pw.print(" Process "); pw.print(pname); 11247 pw.print(" uid "); pw.print(puid); 11248 pw.print(": last crashed "); 11249 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11250 pw.println(" ago"); 11251 } 11252 } 11253 } 11254 11255 if (mBadProcesses.getMap().size() > 0) { 11256 boolean printed = false; 11257 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11258 final int NP = pmap.size(); 11259 for (int ip=0; ip<NP; ip++) { 11260 String pname = pmap.keyAt(ip); 11261 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11262 final int N = uids.size(); 11263 for (int i=0; i<N; i++) { 11264 int puid = uids.keyAt(i); 11265 ProcessRecord r = mProcessNames.get(pname, puid); 11266 if (dumpPackage != null && (r == null 11267 || !r.pkgList.containsKey(dumpPackage))) { 11268 continue; 11269 } 11270 if (!printed) { 11271 if (needSep) pw.println(); 11272 needSep = true; 11273 pw.println(" Bad processes:"); 11274 printedAnything = true; 11275 } 11276 BadProcessInfo info = uids.valueAt(i); 11277 pw.print(" Bad process "); pw.print(pname); 11278 pw.print(" uid "); pw.print(puid); 11279 pw.print(": crashed at time "); pw.println(info.time); 11280 if (info.shortMsg != null) { 11281 pw.print(" Short msg: "); pw.println(info.shortMsg); 11282 } 11283 if (info.longMsg != null) { 11284 pw.print(" Long msg: "); pw.println(info.longMsg); 11285 } 11286 if (info.stack != null) { 11287 pw.println(" Stack:"); 11288 int lastPos = 0; 11289 for (int pos=0; pos<info.stack.length(); pos++) { 11290 if (info.stack.charAt(pos) == '\n') { 11291 pw.print(" "); 11292 pw.write(info.stack, lastPos, pos-lastPos); 11293 pw.println(); 11294 lastPos = pos+1; 11295 } 11296 } 11297 if (lastPos < info.stack.length()) { 11298 pw.print(" "); 11299 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11300 pw.println(); 11301 } 11302 } 11303 } 11304 } 11305 } 11306 11307 if (dumpPackage == null) { 11308 pw.println(); 11309 needSep = false; 11310 pw.println(" mStartedUsers:"); 11311 for (int i=0; i<mStartedUsers.size(); i++) { 11312 UserStartedState uss = mStartedUsers.valueAt(i); 11313 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11314 pw.print(": "); uss.dump("", pw); 11315 } 11316 pw.print(" mStartedUserArray: ["); 11317 for (int i=0; i<mStartedUserArray.length; i++) { 11318 if (i > 0) pw.print(", "); 11319 pw.print(mStartedUserArray[i]); 11320 } 11321 pw.println("]"); 11322 pw.print(" mUserLru: ["); 11323 for (int i=0; i<mUserLru.size(); i++) { 11324 if (i > 0) pw.print(", "); 11325 pw.print(mUserLru.get(i)); 11326 } 11327 pw.println("]"); 11328 if (dumpAll) { 11329 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11330 } 11331 } 11332 if (mHomeProcess != null && (dumpPackage == null 11333 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11334 if (needSep) { 11335 pw.println(); 11336 needSep = false; 11337 } 11338 pw.println(" mHomeProcess: " + mHomeProcess); 11339 } 11340 if (mPreviousProcess != null && (dumpPackage == null 11341 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11342 if (needSep) { 11343 pw.println(); 11344 needSep = false; 11345 } 11346 pw.println(" mPreviousProcess: " + mPreviousProcess); 11347 } 11348 if (dumpAll) { 11349 StringBuilder sb = new StringBuilder(128); 11350 sb.append(" mPreviousProcessVisibleTime: "); 11351 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11352 pw.println(sb); 11353 } 11354 if (mHeavyWeightProcess != null && (dumpPackage == null 11355 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11356 if (needSep) { 11357 pw.println(); 11358 needSep = false; 11359 } 11360 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11361 } 11362 if (dumpPackage == null) { 11363 pw.println(" mConfiguration: " + mConfiguration); 11364 } 11365 if (dumpAll) { 11366 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11367 if (mCompatModePackages.getPackages().size() > 0) { 11368 boolean printed = false; 11369 for (Map.Entry<String, Integer> entry 11370 : mCompatModePackages.getPackages().entrySet()) { 11371 String pkg = entry.getKey(); 11372 int mode = entry.getValue(); 11373 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11374 continue; 11375 } 11376 if (!printed) { 11377 pw.println(" mScreenCompatPackages:"); 11378 printed = true; 11379 } 11380 pw.print(" "); pw.print(pkg); pw.print(": "); 11381 pw.print(mode); pw.println(); 11382 } 11383 } 11384 } 11385 if (dumpPackage == null) { 11386 if (mSleeping || mWentToSleep || mLockScreenShown) { 11387 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11388 + " mLockScreenShown " + mLockScreenShown); 11389 } 11390 if (mShuttingDown || mRunningVoice) { 11391 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11392 } 11393 } 11394 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11395 || mOrigWaitForDebugger) { 11396 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11397 || dumpPackage.equals(mOrigDebugApp)) { 11398 if (needSep) { 11399 pw.println(); 11400 needSep = false; 11401 } 11402 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11403 + " mDebugTransient=" + mDebugTransient 11404 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11405 } 11406 } 11407 if (mOpenGlTraceApp != null) { 11408 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11409 if (needSep) { 11410 pw.println(); 11411 needSep = false; 11412 } 11413 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11414 } 11415 } 11416 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11417 || mProfileFd != null) { 11418 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11419 if (needSep) { 11420 pw.println(); 11421 needSep = false; 11422 } 11423 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11424 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11425 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11426 + mAutoStopProfiler); 11427 } 11428 } 11429 if (dumpPackage == null) { 11430 if (mAlwaysFinishActivities || mController != null) { 11431 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11432 + " mController=" + mController); 11433 } 11434 if (dumpAll) { 11435 pw.println(" Total persistent processes: " + numPers); 11436 pw.println(" mProcessesReady=" + mProcessesReady 11437 + " mSystemReady=" + mSystemReady); 11438 pw.println(" mBooting=" + mBooting 11439 + " mBooted=" + mBooted 11440 + " mFactoryTest=" + mFactoryTest); 11441 pw.print(" mLastPowerCheckRealtime="); 11442 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11443 pw.println(""); 11444 pw.print(" mLastPowerCheckUptime="); 11445 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11446 pw.println(""); 11447 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11448 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11449 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11450 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11451 + " (" + mLruProcesses.size() + " total)" 11452 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11453 + " mNumServiceProcs=" + mNumServiceProcs 11454 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11455 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11456 + " mLastMemoryLevel" + mLastMemoryLevel 11457 + " mLastNumProcesses" + mLastNumProcesses); 11458 long now = SystemClock.uptimeMillis(); 11459 pw.print(" mLastIdleTime="); 11460 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11461 pw.print(" mLowRamSinceLastIdle="); 11462 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11463 pw.println(); 11464 } 11465 } 11466 11467 if (!printedAnything) { 11468 pw.println(" (nothing)"); 11469 } 11470 } 11471 11472 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11473 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11474 if (mProcessesToGc.size() > 0) { 11475 boolean printed = false; 11476 long now = SystemClock.uptimeMillis(); 11477 for (int i=0; i<mProcessesToGc.size(); i++) { 11478 ProcessRecord proc = mProcessesToGc.get(i); 11479 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11480 continue; 11481 } 11482 if (!printed) { 11483 if (needSep) pw.println(); 11484 needSep = true; 11485 pw.println(" Processes that are waiting to GC:"); 11486 printed = true; 11487 } 11488 pw.print(" Process "); pw.println(proc); 11489 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11490 pw.print(", last gced="); 11491 pw.print(now-proc.lastRequestedGc); 11492 pw.print(" ms ago, last lowMem="); 11493 pw.print(now-proc.lastLowMemory); 11494 pw.println(" ms ago"); 11495 11496 } 11497 } 11498 return needSep; 11499 } 11500 11501 void printOomLevel(PrintWriter pw, String name, int adj) { 11502 pw.print(" "); 11503 if (adj >= 0) { 11504 pw.print(' '); 11505 if (adj < 10) pw.print(' '); 11506 } else { 11507 if (adj > -10) pw.print(' '); 11508 } 11509 pw.print(adj); 11510 pw.print(": "); 11511 pw.print(name); 11512 pw.print(" ("); 11513 pw.print(mProcessList.getMemLevel(adj)/1024); 11514 pw.println(" kB)"); 11515 } 11516 11517 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11518 int opti, boolean dumpAll) { 11519 boolean needSep = false; 11520 11521 if (mLruProcesses.size() > 0) { 11522 if (needSep) pw.println(); 11523 needSep = true; 11524 pw.println(" OOM levels:"); 11525 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11526 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11527 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11528 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11529 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11530 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11531 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11532 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11533 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11534 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11535 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11536 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11537 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11538 11539 if (needSep) pw.println(); 11540 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11541 pw.print(" total, non-act at "); 11542 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11543 pw.print(", non-svc at "); 11544 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11545 pw.println("):"); 11546 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11547 needSep = true; 11548 } 11549 11550 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11551 11552 pw.println(); 11553 pw.println(" mHomeProcess: " + mHomeProcess); 11554 pw.println(" mPreviousProcess: " + mPreviousProcess); 11555 if (mHeavyWeightProcess != null) { 11556 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11557 } 11558 11559 return true; 11560 } 11561 11562 /** 11563 * There are three ways to call this: 11564 * - no provider specified: dump all the providers 11565 * - a flattened component name that matched an existing provider was specified as the 11566 * first arg: dump that one provider 11567 * - the first arg isn't the flattened component name of an existing provider: 11568 * dump all providers whose component contains the first arg as a substring 11569 */ 11570 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11571 int opti, boolean dumpAll) { 11572 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11573 } 11574 11575 static class ItemMatcher { 11576 ArrayList<ComponentName> components; 11577 ArrayList<String> strings; 11578 ArrayList<Integer> objects; 11579 boolean all; 11580 11581 ItemMatcher() { 11582 all = true; 11583 } 11584 11585 void build(String name) { 11586 ComponentName componentName = ComponentName.unflattenFromString(name); 11587 if (componentName != null) { 11588 if (components == null) { 11589 components = new ArrayList<ComponentName>(); 11590 } 11591 components.add(componentName); 11592 all = false; 11593 } else { 11594 int objectId = 0; 11595 // Not a '/' separated full component name; maybe an object ID? 11596 try { 11597 objectId = Integer.parseInt(name, 16); 11598 if (objects == null) { 11599 objects = new ArrayList<Integer>(); 11600 } 11601 objects.add(objectId); 11602 all = false; 11603 } catch (RuntimeException e) { 11604 // Not an integer; just do string match. 11605 if (strings == null) { 11606 strings = new ArrayList<String>(); 11607 } 11608 strings.add(name); 11609 all = false; 11610 } 11611 } 11612 } 11613 11614 int build(String[] args, int opti) { 11615 for (; opti<args.length; opti++) { 11616 String name = args[opti]; 11617 if ("--".equals(name)) { 11618 return opti+1; 11619 } 11620 build(name); 11621 } 11622 return opti; 11623 } 11624 11625 boolean match(Object object, ComponentName comp) { 11626 if (all) { 11627 return true; 11628 } 11629 if (components != null) { 11630 for (int i=0; i<components.size(); i++) { 11631 if (components.get(i).equals(comp)) { 11632 return true; 11633 } 11634 } 11635 } 11636 if (objects != null) { 11637 for (int i=0; i<objects.size(); i++) { 11638 if (System.identityHashCode(object) == objects.get(i)) { 11639 return true; 11640 } 11641 } 11642 } 11643 if (strings != null) { 11644 String flat = comp.flattenToString(); 11645 for (int i=0; i<strings.size(); i++) { 11646 if (flat.contains(strings.get(i))) { 11647 return true; 11648 } 11649 } 11650 } 11651 return false; 11652 } 11653 } 11654 11655 /** 11656 * There are three things that cmd can be: 11657 * - a flattened component name that matches an existing activity 11658 * - the cmd arg isn't the flattened component name of an existing activity: 11659 * dump all activity whose component contains the cmd as a substring 11660 * - A hex number of the ActivityRecord object instance. 11661 */ 11662 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11663 int opti, boolean dumpAll) { 11664 ArrayList<ActivityRecord> activities; 11665 11666 synchronized (this) { 11667 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11668 } 11669 11670 if (activities.size() <= 0) { 11671 return false; 11672 } 11673 11674 String[] newArgs = new String[args.length - opti]; 11675 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11676 11677 TaskRecord lastTask = null; 11678 boolean needSep = false; 11679 for (int i=activities.size()-1; i>=0; i--) { 11680 ActivityRecord r = activities.get(i); 11681 if (needSep) { 11682 pw.println(); 11683 } 11684 needSep = true; 11685 synchronized (this) { 11686 if (lastTask != r.task) { 11687 lastTask = r.task; 11688 pw.print("TASK "); pw.print(lastTask.affinity); 11689 pw.print(" id="); pw.println(lastTask.taskId); 11690 if (dumpAll) { 11691 lastTask.dump(pw, " "); 11692 } 11693 } 11694 } 11695 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11696 } 11697 return true; 11698 } 11699 11700 /** 11701 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11702 * there is a thread associated with the activity. 11703 */ 11704 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11705 final ActivityRecord r, String[] args, boolean dumpAll) { 11706 String innerPrefix = prefix + " "; 11707 synchronized (this) { 11708 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11709 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11710 pw.print(" pid="); 11711 if (r.app != null) pw.println(r.app.pid); 11712 else pw.println("(not running)"); 11713 if (dumpAll) { 11714 r.dump(pw, innerPrefix); 11715 } 11716 } 11717 if (r.app != null && r.app.thread != null) { 11718 // flush anything that is already in the PrintWriter since the thread is going 11719 // to write to the file descriptor directly 11720 pw.flush(); 11721 try { 11722 TransferPipe tp = new TransferPipe(); 11723 try { 11724 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11725 r.appToken, innerPrefix, args); 11726 tp.go(fd); 11727 } finally { 11728 tp.kill(); 11729 } 11730 } catch (IOException e) { 11731 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11732 } catch (RemoteException e) { 11733 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11734 } 11735 } 11736 } 11737 11738 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11739 int opti, boolean dumpAll, String dumpPackage) { 11740 boolean needSep = false; 11741 boolean onlyHistory = false; 11742 boolean printedAnything = false; 11743 11744 if ("history".equals(dumpPackage)) { 11745 if (opti < args.length && "-s".equals(args[opti])) { 11746 dumpAll = false; 11747 } 11748 onlyHistory = true; 11749 dumpPackage = null; 11750 } 11751 11752 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11753 if (!onlyHistory && dumpAll) { 11754 if (mRegisteredReceivers.size() > 0) { 11755 boolean printed = false; 11756 Iterator it = mRegisteredReceivers.values().iterator(); 11757 while (it.hasNext()) { 11758 ReceiverList r = (ReceiverList)it.next(); 11759 if (dumpPackage != null && (r.app == null || 11760 !dumpPackage.equals(r.app.info.packageName))) { 11761 continue; 11762 } 11763 if (!printed) { 11764 pw.println(" Registered Receivers:"); 11765 needSep = true; 11766 printed = true; 11767 printedAnything = true; 11768 } 11769 pw.print(" * "); pw.println(r); 11770 r.dump(pw, " "); 11771 } 11772 } 11773 11774 if (mReceiverResolver.dump(pw, needSep ? 11775 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11776 " ", dumpPackage, false)) { 11777 needSep = true; 11778 printedAnything = true; 11779 } 11780 } 11781 11782 for (BroadcastQueue q : mBroadcastQueues) { 11783 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11784 printedAnything |= needSep; 11785 } 11786 11787 needSep = true; 11788 11789 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11790 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11791 if (needSep) { 11792 pw.println(); 11793 } 11794 needSep = true; 11795 printedAnything = true; 11796 pw.print(" Sticky broadcasts for user "); 11797 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11798 StringBuilder sb = new StringBuilder(128); 11799 for (Map.Entry<String, ArrayList<Intent>> ent 11800 : mStickyBroadcasts.valueAt(user).entrySet()) { 11801 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11802 if (dumpAll) { 11803 pw.println(":"); 11804 ArrayList<Intent> intents = ent.getValue(); 11805 final int N = intents.size(); 11806 for (int i=0; i<N; i++) { 11807 sb.setLength(0); 11808 sb.append(" Intent: "); 11809 intents.get(i).toShortString(sb, false, true, false, false); 11810 pw.println(sb.toString()); 11811 Bundle bundle = intents.get(i).getExtras(); 11812 if (bundle != null) { 11813 pw.print(" "); 11814 pw.println(bundle.toString()); 11815 } 11816 } 11817 } else { 11818 pw.println(""); 11819 } 11820 } 11821 } 11822 } 11823 11824 if (!onlyHistory && dumpAll) { 11825 pw.println(); 11826 for (BroadcastQueue queue : mBroadcastQueues) { 11827 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11828 + queue.mBroadcastsScheduled); 11829 } 11830 pw.println(" mHandler:"); 11831 mHandler.dump(new PrintWriterPrinter(pw), " "); 11832 needSep = true; 11833 printedAnything = true; 11834 } 11835 11836 if (!printedAnything) { 11837 pw.println(" (nothing)"); 11838 } 11839 } 11840 11841 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11842 int opti, boolean dumpAll, String dumpPackage) { 11843 boolean needSep; 11844 boolean printedAnything = false; 11845 11846 ItemMatcher matcher = new ItemMatcher(); 11847 matcher.build(args, opti); 11848 11849 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11850 11851 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11852 printedAnything |= needSep; 11853 11854 if (mLaunchingProviders.size() > 0) { 11855 boolean printed = false; 11856 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11857 ContentProviderRecord r = mLaunchingProviders.get(i); 11858 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11859 continue; 11860 } 11861 if (!printed) { 11862 if (needSep) pw.println(); 11863 needSep = true; 11864 pw.println(" Launching content providers:"); 11865 printed = true; 11866 printedAnything = true; 11867 } 11868 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11869 pw.println(r); 11870 } 11871 } 11872 11873 if (mGrantedUriPermissions.size() > 0) { 11874 boolean printed = false; 11875 int dumpUid = -2; 11876 if (dumpPackage != null) { 11877 try { 11878 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11879 } catch (NameNotFoundException e) { 11880 dumpUid = -1; 11881 } 11882 } 11883 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11884 int uid = mGrantedUriPermissions.keyAt(i); 11885 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11886 continue; 11887 } 11888 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11889 if (!printed) { 11890 if (needSep) pw.println(); 11891 needSep = true; 11892 pw.println(" Granted Uri Permissions:"); 11893 printed = true; 11894 printedAnything = true; 11895 } 11896 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11897 for (UriPermission perm : perms.values()) { 11898 pw.print(" "); pw.println(perm); 11899 if (dumpAll) { 11900 perm.dump(pw, " "); 11901 } 11902 } 11903 } 11904 } 11905 11906 if (!printedAnything) { 11907 pw.println(" (nothing)"); 11908 } 11909 } 11910 11911 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11912 int opti, boolean dumpAll, String dumpPackage) { 11913 boolean printed = false; 11914 11915 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11916 11917 if (mIntentSenderRecords.size() > 0) { 11918 Iterator<WeakReference<PendingIntentRecord>> it 11919 = mIntentSenderRecords.values().iterator(); 11920 while (it.hasNext()) { 11921 WeakReference<PendingIntentRecord> ref = it.next(); 11922 PendingIntentRecord rec = ref != null ? ref.get(): null; 11923 if (dumpPackage != null && (rec == null 11924 || !dumpPackage.equals(rec.key.packageName))) { 11925 continue; 11926 } 11927 printed = true; 11928 if (rec != null) { 11929 pw.print(" * "); pw.println(rec); 11930 if (dumpAll) { 11931 rec.dump(pw, " "); 11932 } 11933 } else { 11934 pw.print(" * "); pw.println(ref); 11935 } 11936 } 11937 } 11938 11939 if (!printed) { 11940 pw.println(" (nothing)"); 11941 } 11942 } 11943 11944 private static final int dumpProcessList(PrintWriter pw, 11945 ActivityManagerService service, List list, 11946 String prefix, String normalLabel, String persistentLabel, 11947 String dumpPackage) { 11948 int numPers = 0; 11949 final int N = list.size()-1; 11950 for (int i=N; i>=0; i--) { 11951 ProcessRecord r = (ProcessRecord)list.get(i); 11952 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11953 continue; 11954 } 11955 pw.println(String.format("%s%s #%2d: %s", 11956 prefix, (r.persistent ? persistentLabel : normalLabel), 11957 i, r.toString())); 11958 if (r.persistent) { 11959 numPers++; 11960 } 11961 } 11962 return numPers; 11963 } 11964 11965 private static final boolean dumpProcessOomList(PrintWriter pw, 11966 ActivityManagerService service, List<ProcessRecord> origList, 11967 String prefix, String normalLabel, String persistentLabel, 11968 boolean inclDetails, String dumpPackage) { 11969 11970 ArrayList<Pair<ProcessRecord, Integer>> list 11971 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11972 for (int i=0; i<origList.size(); i++) { 11973 ProcessRecord r = origList.get(i); 11974 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11975 continue; 11976 } 11977 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11978 } 11979 11980 if (list.size() <= 0) { 11981 return false; 11982 } 11983 11984 Comparator<Pair<ProcessRecord, Integer>> comparator 11985 = new Comparator<Pair<ProcessRecord, Integer>>() { 11986 @Override 11987 public int compare(Pair<ProcessRecord, Integer> object1, 11988 Pair<ProcessRecord, Integer> object2) { 11989 if (object1.first.setAdj != object2.first.setAdj) { 11990 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11991 } 11992 if (object1.second.intValue() != object2.second.intValue()) { 11993 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11994 } 11995 return 0; 11996 } 11997 }; 11998 11999 Collections.sort(list, comparator); 12000 12001 final long curRealtime = SystemClock.elapsedRealtime(); 12002 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12003 final long curUptime = SystemClock.uptimeMillis(); 12004 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12005 12006 for (int i=list.size()-1; i>=0; i--) { 12007 ProcessRecord r = list.get(i).first; 12008 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12009 char schedGroup; 12010 switch (r.setSchedGroup) { 12011 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12012 schedGroup = 'B'; 12013 break; 12014 case Process.THREAD_GROUP_DEFAULT: 12015 schedGroup = 'F'; 12016 break; 12017 default: 12018 schedGroup = '?'; 12019 break; 12020 } 12021 char foreground; 12022 if (r.foregroundActivities) { 12023 foreground = 'A'; 12024 } else if (r.foregroundServices) { 12025 foreground = 'S'; 12026 } else { 12027 foreground = ' '; 12028 } 12029 String procState = ProcessList.makeProcStateString(r.curProcState); 12030 pw.print(prefix); 12031 pw.print(r.persistent ? persistentLabel : normalLabel); 12032 pw.print(" #"); 12033 int num = (origList.size()-1)-list.get(i).second; 12034 if (num < 10) pw.print(' '); 12035 pw.print(num); 12036 pw.print(": "); 12037 pw.print(oomAdj); 12038 pw.print(' '); 12039 pw.print(schedGroup); 12040 pw.print('/'); 12041 pw.print(foreground); 12042 pw.print('/'); 12043 pw.print(procState); 12044 pw.print(" trm:"); 12045 if (r.trimMemoryLevel < 10) pw.print(' '); 12046 pw.print(r.trimMemoryLevel); 12047 pw.print(' '); 12048 pw.print(r.toShortString()); 12049 pw.print(" ("); 12050 pw.print(r.adjType); 12051 pw.println(')'); 12052 if (r.adjSource != null || r.adjTarget != null) { 12053 pw.print(prefix); 12054 pw.print(" "); 12055 if (r.adjTarget instanceof ComponentName) { 12056 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12057 } else if (r.adjTarget != null) { 12058 pw.print(r.adjTarget.toString()); 12059 } else { 12060 pw.print("{null}"); 12061 } 12062 pw.print("<="); 12063 if (r.adjSource instanceof ProcessRecord) { 12064 pw.print("Proc{"); 12065 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12066 pw.println("}"); 12067 } else if (r.adjSource != null) { 12068 pw.println(r.adjSource.toString()); 12069 } else { 12070 pw.println("{null}"); 12071 } 12072 } 12073 if (inclDetails) { 12074 pw.print(prefix); 12075 pw.print(" "); 12076 pw.print("oom: max="); pw.print(r.maxAdj); 12077 pw.print(" curRaw="); pw.print(r.curRawAdj); 12078 pw.print(" setRaw="); pw.print(r.setRawAdj); 12079 pw.print(" cur="); pw.print(r.curAdj); 12080 pw.print(" set="); pw.println(r.setAdj); 12081 pw.print(prefix); 12082 pw.print(" "); 12083 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12084 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12085 pw.print(" lastPss="); pw.print(r.lastPss); 12086 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12087 pw.print(prefix); 12088 pw.print(" "); 12089 pw.print("keeping="); pw.print(r.keeping); 12090 pw.print(" cached="); pw.print(r.cached); 12091 pw.print(" empty="); pw.print(r.empty); 12092 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12093 12094 if (!r.keeping) { 12095 if (r.lastWakeTime != 0) { 12096 long wtime; 12097 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12098 synchronized (stats) { 12099 wtime = stats.getProcessWakeTime(r.info.uid, 12100 r.pid, curRealtime); 12101 } 12102 long timeUsed = wtime - r.lastWakeTime; 12103 pw.print(prefix); 12104 pw.print(" "); 12105 pw.print("keep awake over "); 12106 TimeUtils.formatDuration(realtimeSince, pw); 12107 pw.print(" used "); 12108 TimeUtils.formatDuration(timeUsed, pw); 12109 pw.print(" ("); 12110 pw.print((timeUsed*100)/realtimeSince); 12111 pw.println("%)"); 12112 } 12113 if (r.lastCpuTime != 0) { 12114 long timeUsed = r.curCpuTime - r.lastCpuTime; 12115 pw.print(prefix); 12116 pw.print(" "); 12117 pw.print("run cpu over "); 12118 TimeUtils.formatDuration(uptimeSince, pw); 12119 pw.print(" used "); 12120 TimeUtils.formatDuration(timeUsed, pw); 12121 pw.print(" ("); 12122 pw.print((timeUsed*100)/uptimeSince); 12123 pw.println("%)"); 12124 } 12125 } 12126 } 12127 } 12128 return true; 12129 } 12130 12131 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12132 ArrayList<ProcessRecord> procs; 12133 synchronized (this) { 12134 if (args != null && args.length > start 12135 && args[start].charAt(0) != '-') { 12136 procs = new ArrayList<ProcessRecord>(); 12137 int pid = -1; 12138 try { 12139 pid = Integer.parseInt(args[start]); 12140 } catch (NumberFormatException e) { 12141 } 12142 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12143 ProcessRecord proc = mLruProcesses.get(i); 12144 if (proc.pid == pid) { 12145 procs.add(proc); 12146 } else if (proc.processName.equals(args[start])) { 12147 procs.add(proc); 12148 } 12149 } 12150 if (procs.size() <= 0) { 12151 return null; 12152 } 12153 } else { 12154 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12155 } 12156 } 12157 return procs; 12158 } 12159 12160 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12161 PrintWriter pw, String[] args) { 12162 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12163 if (procs == null) { 12164 pw.println("No process found for: " + args[0]); 12165 return; 12166 } 12167 12168 long uptime = SystemClock.uptimeMillis(); 12169 long realtime = SystemClock.elapsedRealtime(); 12170 pw.println("Applications Graphics Acceleration Info:"); 12171 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12172 12173 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12174 ProcessRecord r = procs.get(i); 12175 if (r.thread != null) { 12176 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12177 pw.flush(); 12178 try { 12179 TransferPipe tp = new TransferPipe(); 12180 try { 12181 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12182 tp.go(fd); 12183 } finally { 12184 tp.kill(); 12185 } 12186 } catch (IOException e) { 12187 pw.println("Failure while dumping the app: " + r); 12188 pw.flush(); 12189 } catch (RemoteException e) { 12190 pw.println("Got a RemoteException while dumping the app " + r); 12191 pw.flush(); 12192 } 12193 } 12194 } 12195 } 12196 12197 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12198 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12199 if (procs == null) { 12200 pw.println("No process found for: " + args[0]); 12201 return; 12202 } 12203 12204 pw.println("Applications Database Info:"); 12205 12206 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12207 ProcessRecord r = procs.get(i); 12208 if (r.thread != null) { 12209 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12210 pw.flush(); 12211 try { 12212 TransferPipe tp = new TransferPipe(); 12213 try { 12214 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12215 tp.go(fd); 12216 } finally { 12217 tp.kill(); 12218 } 12219 } catch (IOException e) { 12220 pw.println("Failure while dumping the app: " + r); 12221 pw.flush(); 12222 } catch (RemoteException e) { 12223 pw.println("Got a RemoteException while dumping the app " + r); 12224 pw.flush(); 12225 } 12226 } 12227 } 12228 } 12229 12230 final static class MemItem { 12231 final boolean isProc; 12232 final String label; 12233 final String shortLabel; 12234 final long pss; 12235 final int id; 12236 final boolean hasActivities; 12237 ArrayList<MemItem> subitems; 12238 12239 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12240 boolean _hasActivities) { 12241 isProc = true; 12242 label = _label; 12243 shortLabel = _shortLabel; 12244 pss = _pss; 12245 id = _id; 12246 hasActivities = _hasActivities; 12247 } 12248 12249 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12250 isProc = false; 12251 label = _label; 12252 shortLabel = _shortLabel; 12253 pss = _pss; 12254 id = _id; 12255 hasActivities = false; 12256 } 12257 } 12258 12259 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12260 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12261 if (sort && !isCompact) { 12262 Collections.sort(items, new Comparator<MemItem>() { 12263 @Override 12264 public int compare(MemItem lhs, MemItem rhs) { 12265 if (lhs.pss < rhs.pss) { 12266 return 1; 12267 } else if (lhs.pss > rhs.pss) { 12268 return -1; 12269 } 12270 return 0; 12271 } 12272 }); 12273 } 12274 12275 for (int i=0; i<items.size(); i++) { 12276 MemItem mi = items.get(i); 12277 if (!isCompact) { 12278 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12279 } else if (mi.isProc) { 12280 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12281 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12282 pw.println(mi.hasActivities ? ",a" : ",e"); 12283 } else { 12284 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12285 pw.println(mi.pss); 12286 } 12287 if (mi.subitems != null) { 12288 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12289 true, isCompact); 12290 } 12291 } 12292 } 12293 12294 // These are in KB. 12295 static final long[] DUMP_MEM_BUCKETS = new long[] { 12296 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12297 120*1024, 160*1024, 200*1024, 12298 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12299 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12300 }; 12301 12302 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12303 boolean stackLike) { 12304 int start = label.lastIndexOf('.'); 12305 if (start >= 0) start++; 12306 else start = 0; 12307 int end = label.length(); 12308 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12309 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12310 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12311 out.append(bucket); 12312 out.append(stackLike ? "MB." : "MB "); 12313 out.append(label, start, end); 12314 return; 12315 } 12316 } 12317 out.append(memKB/1024); 12318 out.append(stackLike ? "MB." : "MB "); 12319 out.append(label, start, end); 12320 } 12321 12322 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12323 ProcessList.NATIVE_ADJ, 12324 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12325 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12326 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12327 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12328 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12329 }; 12330 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12331 "Native", 12332 "System", "Persistent", "Foreground", 12333 "Visible", "Perceptible", 12334 "Heavy Weight", "Backup", 12335 "A Services", "Home", 12336 "Previous", "B Services", "Cached" 12337 }; 12338 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12339 "native", 12340 "sys", "pers", "fore", 12341 "vis", "percept", 12342 "heavy", "backup", 12343 "servicea", "home", 12344 "prev", "serviceb", "cached" 12345 }; 12346 12347 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12348 long realtime, boolean isCheckinRequest, boolean isCompact) { 12349 if (isCheckinRequest || isCompact) { 12350 // short checkin version 12351 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12352 } else { 12353 pw.println("Applications Memory Usage (kB):"); 12354 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12355 } 12356 } 12357 12358 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12359 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12360 boolean dumpDetails = false; 12361 boolean dumpFullDetails = false; 12362 boolean dumpDalvik = false; 12363 boolean oomOnly = false; 12364 boolean isCompact = false; 12365 boolean localOnly = false; 12366 12367 int opti = 0; 12368 while (opti < args.length) { 12369 String opt = args[opti]; 12370 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12371 break; 12372 } 12373 opti++; 12374 if ("-a".equals(opt)) { 12375 dumpDetails = true; 12376 dumpFullDetails = true; 12377 dumpDalvik = true; 12378 } else if ("-d".equals(opt)) { 12379 dumpDalvik = true; 12380 } else if ("-c".equals(opt)) { 12381 isCompact = true; 12382 } else if ("--oom".equals(opt)) { 12383 oomOnly = true; 12384 } else if ("--local".equals(opt)) { 12385 localOnly = true; 12386 } else if ("-h".equals(opt)) { 12387 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12388 pw.println(" -a: include all available information for each process."); 12389 pw.println(" -d: include dalvik details when dumping process details."); 12390 pw.println(" -c: dump in a compact machine-parseable representation."); 12391 pw.println(" --oom: only show processes organized by oom adj."); 12392 pw.println(" --local: only collect details locally, don't call process."); 12393 pw.println("If [process] is specified it can be the name or "); 12394 pw.println("pid of a specific process to dump."); 12395 return; 12396 } else { 12397 pw.println("Unknown argument: " + opt + "; use -h for help"); 12398 } 12399 } 12400 12401 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12402 long uptime = SystemClock.uptimeMillis(); 12403 long realtime = SystemClock.elapsedRealtime(); 12404 final long[] tmpLong = new long[1]; 12405 12406 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12407 if (procs == null) { 12408 // No Java processes. Maybe they want to print a native process. 12409 if (args != null && args.length > opti 12410 && args[opti].charAt(0) != '-') { 12411 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12412 = new ArrayList<ProcessCpuTracker.Stats>(); 12413 updateCpuStatsNow(); 12414 int findPid = -1; 12415 try { 12416 findPid = Integer.parseInt(args[opti]); 12417 } catch (NumberFormatException e) { 12418 } 12419 synchronized (mProcessCpuThread) { 12420 final int N = mProcessCpuTracker.countStats(); 12421 for (int i=0; i<N; i++) { 12422 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12423 if (st.pid == findPid || (st.baseName != null 12424 && st.baseName.equals(args[opti]))) { 12425 nativeProcs.add(st); 12426 } 12427 } 12428 } 12429 if (nativeProcs.size() > 0) { 12430 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12431 isCompact); 12432 Debug.MemoryInfo mi = null; 12433 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12434 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12435 final int pid = r.pid; 12436 if (!isCheckinRequest && dumpDetails) { 12437 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12438 } 12439 if (mi == null) { 12440 mi = new Debug.MemoryInfo(); 12441 } 12442 if (dumpDetails || (!brief && !oomOnly)) { 12443 Debug.getMemoryInfo(pid, mi); 12444 } else { 12445 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12446 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12447 } 12448 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12449 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12450 if (isCheckinRequest) { 12451 pw.println(); 12452 } 12453 } 12454 return; 12455 } 12456 } 12457 pw.println("No process found for: " + args[opti]); 12458 return; 12459 } 12460 12461 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12462 dumpDetails = true; 12463 } 12464 12465 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12466 12467 String[] innerArgs = new String[args.length-opti]; 12468 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12469 12470 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12471 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12472 long nativePss=0, dalvikPss=0, otherPss=0; 12473 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12474 12475 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12476 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12477 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12478 12479 long totalPss = 0; 12480 long cachedPss = 0; 12481 12482 Debug.MemoryInfo mi = null; 12483 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12484 final ProcessRecord r = procs.get(i); 12485 final IApplicationThread thread; 12486 final int pid; 12487 final int oomAdj; 12488 final boolean hasActivities; 12489 synchronized (this) { 12490 thread = r.thread; 12491 pid = r.pid; 12492 oomAdj = r.getSetAdjWithServices(); 12493 hasActivities = r.activities.size() > 0; 12494 } 12495 if (thread != null) { 12496 if (!isCheckinRequest && dumpDetails) { 12497 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12498 } 12499 if (mi == null) { 12500 mi = new Debug.MemoryInfo(); 12501 } 12502 if (dumpDetails || (!brief && !oomOnly)) { 12503 Debug.getMemoryInfo(pid, mi); 12504 } else { 12505 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12506 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12507 } 12508 if (dumpDetails) { 12509 if (localOnly) { 12510 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12511 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12512 if (isCheckinRequest) { 12513 pw.println(); 12514 } 12515 } else { 12516 try { 12517 pw.flush(); 12518 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12519 dumpDalvik, innerArgs); 12520 } catch (RemoteException e) { 12521 if (!isCheckinRequest) { 12522 pw.println("Got RemoteException!"); 12523 pw.flush(); 12524 } 12525 } 12526 } 12527 } 12528 12529 final long myTotalPss = mi.getTotalPss(); 12530 final long myTotalUss = mi.getTotalUss(); 12531 12532 synchronized (this) { 12533 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12534 // Record this for posterity if the process has been stable. 12535 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12536 } 12537 } 12538 12539 if (!isCheckinRequest && mi != null) { 12540 totalPss += myTotalPss; 12541 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12542 (hasActivities ? " / activities)" : ")"), 12543 r.processName, myTotalPss, pid, hasActivities); 12544 procMems.add(pssItem); 12545 procMemsMap.put(pid, pssItem); 12546 12547 nativePss += mi.nativePss; 12548 dalvikPss += mi.dalvikPss; 12549 otherPss += mi.otherPss; 12550 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12551 long mem = mi.getOtherPss(j); 12552 miscPss[j] += mem; 12553 otherPss -= mem; 12554 } 12555 12556 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12557 cachedPss += myTotalPss; 12558 } 12559 12560 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12561 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12562 || oomIndex == (oomPss.length-1)) { 12563 oomPss[oomIndex] += myTotalPss; 12564 if (oomProcs[oomIndex] == null) { 12565 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12566 } 12567 oomProcs[oomIndex].add(pssItem); 12568 break; 12569 } 12570 } 12571 } 12572 } 12573 } 12574 12575 if (!isCheckinRequest && procs.size() > 1) { 12576 // If we are showing aggregations, also look for native processes to 12577 // include so that our aggregations are more accurate. 12578 updateCpuStatsNow(); 12579 synchronized (mProcessCpuThread) { 12580 final int N = mProcessCpuTracker.countStats(); 12581 for (int i=0; i<N; i++) { 12582 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12583 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12584 if (mi == null) { 12585 mi = new Debug.MemoryInfo(); 12586 } 12587 if (!brief && !oomOnly) { 12588 Debug.getMemoryInfo(st.pid, mi); 12589 } else { 12590 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12591 mi.nativePrivateDirty = (int)tmpLong[0]; 12592 } 12593 12594 final long myTotalPss = mi.getTotalPss(); 12595 totalPss += myTotalPss; 12596 12597 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12598 st.name, myTotalPss, st.pid, false); 12599 procMems.add(pssItem); 12600 12601 nativePss += mi.nativePss; 12602 dalvikPss += mi.dalvikPss; 12603 otherPss += mi.otherPss; 12604 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12605 long mem = mi.getOtherPss(j); 12606 miscPss[j] += mem; 12607 otherPss -= mem; 12608 } 12609 oomPss[0] += myTotalPss; 12610 if (oomProcs[0] == null) { 12611 oomProcs[0] = new ArrayList<MemItem>(); 12612 } 12613 oomProcs[0].add(pssItem); 12614 } 12615 } 12616 } 12617 12618 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12619 12620 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12621 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12622 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12623 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12624 String label = Debug.MemoryInfo.getOtherLabel(j); 12625 catMems.add(new MemItem(label, label, miscPss[j], j)); 12626 } 12627 12628 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12629 for (int j=0; j<oomPss.length; j++) { 12630 if (oomPss[j] != 0) { 12631 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12632 : DUMP_MEM_OOM_LABEL[j]; 12633 MemItem item = new MemItem(label, label, oomPss[j], 12634 DUMP_MEM_OOM_ADJ[j]); 12635 item.subitems = oomProcs[j]; 12636 oomMems.add(item); 12637 } 12638 } 12639 12640 if (!brief && !oomOnly && !isCompact) { 12641 pw.println(); 12642 pw.println("Total PSS by process:"); 12643 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12644 pw.println(); 12645 } 12646 if (!isCompact) { 12647 pw.println("Total PSS by OOM adjustment:"); 12648 } 12649 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12650 if (!brief && !oomOnly) { 12651 PrintWriter out = categoryPw != null ? categoryPw : pw; 12652 if (!isCompact) { 12653 out.println(); 12654 out.println("Total PSS by category:"); 12655 } 12656 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12657 } 12658 if (!isCompact) { 12659 pw.println(); 12660 } 12661 MemInfoReader memInfo = new MemInfoReader(); 12662 memInfo.readMemInfo(); 12663 if (!brief) { 12664 if (!isCompact) { 12665 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12666 pw.print(" kB (status "); 12667 switch (mLastMemoryLevel) { 12668 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12669 pw.println("normal)"); 12670 break; 12671 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12672 pw.println("moderate)"); 12673 break; 12674 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12675 pw.println("low)"); 12676 break; 12677 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12678 pw.println("critical)"); 12679 break; 12680 default: 12681 pw.print(mLastMemoryLevel); 12682 pw.println(")"); 12683 break; 12684 } 12685 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12686 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12687 pw.print(cachedPss); pw.print(" cached pss + "); 12688 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12689 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12690 } else { 12691 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12692 pw.print(cachedPss + memInfo.getCachedSizeKb() 12693 + memInfo.getFreeSizeKb()); pw.print(","); 12694 pw.println(totalPss - cachedPss); 12695 } 12696 } 12697 if (!isCompact) { 12698 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12699 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12700 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12701 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12702 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12703 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12704 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12705 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12706 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12707 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12708 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12709 } 12710 if (!brief) { 12711 if (memInfo.getZramTotalSizeKb() != 0) { 12712 if (!isCompact) { 12713 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12714 pw.print(" kB physical used for "); 12715 pw.print(memInfo.getSwapTotalSizeKb() 12716 - memInfo.getSwapFreeSizeKb()); 12717 pw.print(" kB in swap ("); 12718 pw.print(memInfo.getSwapTotalSizeKb()); 12719 pw.println(" kB total swap)"); 12720 } else { 12721 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12722 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12723 pw.println(memInfo.getSwapFreeSizeKb()); 12724 } 12725 } 12726 final int[] SINGLE_LONG_FORMAT = new int[] { 12727 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12728 }; 12729 long[] longOut = new long[1]; 12730 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12731 SINGLE_LONG_FORMAT, null, longOut, null); 12732 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12733 longOut[0] = 0; 12734 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12735 SINGLE_LONG_FORMAT, null, longOut, null); 12736 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12737 longOut[0] = 0; 12738 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12739 SINGLE_LONG_FORMAT, null, longOut, null); 12740 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12741 longOut[0] = 0; 12742 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12743 SINGLE_LONG_FORMAT, null, longOut, null); 12744 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12745 if (!isCompact) { 12746 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12747 pw.print(" KSM: "); pw.print(sharing); 12748 pw.print(" kB saved from shared "); 12749 pw.print(shared); pw.println(" kB"); 12750 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12751 pw.print(voltile); pw.println(" kB volatile"); 12752 } 12753 pw.print(" Tuning: "); 12754 pw.print(ActivityManager.staticGetMemoryClass()); 12755 pw.print(" (large "); 12756 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12757 pw.print("), oom "); 12758 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12759 pw.print(" kB"); 12760 pw.print(", restore limit "); 12761 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12762 pw.print(" kB"); 12763 if (ActivityManager.isLowRamDeviceStatic()) { 12764 pw.print(" (low-ram)"); 12765 } 12766 if (ActivityManager.isHighEndGfx()) { 12767 pw.print(" (high-end-gfx)"); 12768 } 12769 pw.println(); 12770 } else { 12771 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12772 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12773 pw.println(voltile); 12774 pw.print("tuning,"); 12775 pw.print(ActivityManager.staticGetMemoryClass()); 12776 pw.print(','); 12777 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12778 pw.print(','); 12779 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12780 if (ActivityManager.isLowRamDeviceStatic()) { 12781 pw.print(",low-ram"); 12782 } 12783 if (ActivityManager.isHighEndGfx()) { 12784 pw.print(",high-end-gfx"); 12785 } 12786 pw.println(); 12787 } 12788 } 12789 } 12790 } 12791 12792 /** 12793 * Searches array of arguments for the specified string 12794 * @param args array of argument strings 12795 * @param value value to search for 12796 * @return true if the value is contained in the array 12797 */ 12798 private static boolean scanArgs(String[] args, String value) { 12799 if (args != null) { 12800 for (String arg : args) { 12801 if (value.equals(arg)) { 12802 return true; 12803 } 12804 } 12805 } 12806 return false; 12807 } 12808 12809 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12810 ContentProviderRecord cpr, boolean always) { 12811 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12812 12813 if (!inLaunching || always) { 12814 synchronized (cpr) { 12815 cpr.launchingApp = null; 12816 cpr.notifyAll(); 12817 } 12818 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12819 String names[] = cpr.info.authority.split(";"); 12820 for (int j = 0; j < names.length; j++) { 12821 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12822 } 12823 } 12824 12825 for (int i=0; i<cpr.connections.size(); i++) { 12826 ContentProviderConnection conn = cpr.connections.get(i); 12827 if (conn.waiting) { 12828 // If this connection is waiting for the provider, then we don't 12829 // need to mess with its process unless we are always removing 12830 // or for some reason the provider is not currently launching. 12831 if (inLaunching && !always) { 12832 continue; 12833 } 12834 } 12835 ProcessRecord capp = conn.client; 12836 conn.dead = true; 12837 if (conn.stableCount > 0) { 12838 if (!capp.persistent && capp.thread != null 12839 && capp.pid != 0 12840 && capp.pid != MY_PID) { 12841 killUnneededProcessLocked(capp, "depends on provider " 12842 + cpr.name.flattenToShortString() 12843 + " in dying proc " + (proc != null ? proc.processName : "??")); 12844 } 12845 } else if (capp.thread != null && conn.provider.provider != null) { 12846 try { 12847 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12848 } catch (RemoteException e) { 12849 } 12850 // In the protocol here, we don't expect the client to correctly 12851 // clean up this connection, we'll just remove it. 12852 cpr.connections.remove(i); 12853 conn.client.conProviders.remove(conn); 12854 } 12855 } 12856 12857 if (inLaunching && always) { 12858 mLaunchingProviders.remove(cpr); 12859 } 12860 return inLaunching; 12861 } 12862 12863 /** 12864 * Main code for cleaning up a process when it has gone away. This is 12865 * called both as a result of the process dying, or directly when stopping 12866 * a process when running in single process mode. 12867 */ 12868 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12869 boolean restarting, boolean allowRestart, int index) { 12870 if (index >= 0) { 12871 removeLruProcessLocked(app); 12872 ProcessList.remove(app.pid); 12873 } 12874 12875 mProcessesToGc.remove(app); 12876 mPendingPssProcesses.remove(app); 12877 12878 // Dismiss any open dialogs. 12879 if (app.crashDialog != null && !app.forceCrashReport) { 12880 app.crashDialog.dismiss(); 12881 app.crashDialog = null; 12882 } 12883 if (app.anrDialog != null) { 12884 app.anrDialog.dismiss(); 12885 app.anrDialog = null; 12886 } 12887 if (app.waitDialog != null) { 12888 app.waitDialog.dismiss(); 12889 app.waitDialog = null; 12890 } 12891 12892 app.crashing = false; 12893 app.notResponding = false; 12894 12895 app.resetPackageList(mProcessStats); 12896 app.unlinkDeathRecipient(); 12897 app.makeInactive(mProcessStats); 12898 app.forcingToForeground = null; 12899 updateProcessForegroundLocked(app, false, false); 12900 app.foregroundActivities = false; 12901 app.hasShownUi = false; 12902 app.treatLikeActivity = false; 12903 app.hasAboveClient = false; 12904 app.hasClientActivities = false; 12905 12906 mServices.killServicesLocked(app, allowRestart); 12907 12908 boolean restart = false; 12909 12910 // Remove published content providers. 12911 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12912 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12913 final boolean always = app.bad || !allowRestart; 12914 if (removeDyingProviderLocked(app, cpr, always) || always) { 12915 // We left the provider in the launching list, need to 12916 // restart it. 12917 restart = true; 12918 } 12919 12920 cpr.provider = null; 12921 cpr.proc = null; 12922 } 12923 app.pubProviders.clear(); 12924 12925 // Take care of any launching providers waiting for this process. 12926 if (checkAppInLaunchingProvidersLocked(app, false)) { 12927 restart = true; 12928 } 12929 12930 // Unregister from connected content providers. 12931 if (!app.conProviders.isEmpty()) { 12932 for (int i=0; i<app.conProviders.size(); i++) { 12933 ContentProviderConnection conn = app.conProviders.get(i); 12934 conn.provider.connections.remove(conn); 12935 } 12936 app.conProviders.clear(); 12937 } 12938 12939 // At this point there may be remaining entries in mLaunchingProviders 12940 // where we were the only one waiting, so they are no longer of use. 12941 // Look for these and clean up if found. 12942 // XXX Commented out for now. Trying to figure out a way to reproduce 12943 // the actual situation to identify what is actually going on. 12944 if (false) { 12945 for (int i=0; i<mLaunchingProviders.size(); i++) { 12946 ContentProviderRecord cpr = (ContentProviderRecord) 12947 mLaunchingProviders.get(i); 12948 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12949 synchronized (cpr) { 12950 cpr.launchingApp = null; 12951 cpr.notifyAll(); 12952 } 12953 } 12954 } 12955 } 12956 12957 skipCurrentReceiverLocked(app); 12958 12959 // Unregister any receivers. 12960 for (int i=app.receivers.size()-1; i>=0; i--) { 12961 removeReceiverLocked(app.receivers.valueAt(i)); 12962 } 12963 app.receivers.clear(); 12964 12965 // If the app is undergoing backup, tell the backup manager about it 12966 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12967 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12968 + mBackupTarget.appInfo + " died during backup"); 12969 try { 12970 IBackupManager bm = IBackupManager.Stub.asInterface( 12971 ServiceManager.getService(Context.BACKUP_SERVICE)); 12972 bm.agentDisconnected(app.info.packageName); 12973 } catch (RemoteException e) { 12974 // can't happen; backup manager is local 12975 } 12976 } 12977 12978 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12979 ProcessChangeItem item = mPendingProcessChanges.get(i); 12980 if (item.pid == app.pid) { 12981 mPendingProcessChanges.remove(i); 12982 mAvailProcessChanges.add(item); 12983 } 12984 } 12985 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12986 12987 // If the caller is restarting this app, then leave it in its 12988 // current lists and let the caller take care of it. 12989 if (restarting) { 12990 return; 12991 } 12992 12993 if (!app.persistent || app.isolated) { 12994 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12995 "Removing non-persistent process during cleanup: " + app); 12996 mProcessNames.remove(app.processName, app.uid); 12997 mIsolatedProcesses.remove(app.uid); 12998 if (mHeavyWeightProcess == app) { 12999 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13000 mHeavyWeightProcess.userId, 0)); 13001 mHeavyWeightProcess = null; 13002 } 13003 } else if (!app.removed) { 13004 // This app is persistent, so we need to keep its record around. 13005 // If it is not already on the pending app list, add it there 13006 // and start a new process for it. 13007 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13008 mPersistentStartingProcesses.add(app); 13009 restart = true; 13010 } 13011 } 13012 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13013 "Clean-up removing on hold: " + app); 13014 mProcessesOnHold.remove(app); 13015 13016 if (app == mHomeProcess) { 13017 mHomeProcess = null; 13018 } 13019 if (app == mPreviousProcess) { 13020 mPreviousProcess = null; 13021 } 13022 13023 if (restart && !app.isolated) { 13024 // We have components that still need to be running in the 13025 // process, so re-launch it. 13026 mProcessNames.put(app.processName, app.uid, app); 13027 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13028 } else if (app.pid > 0 && app.pid != MY_PID) { 13029 // Goodbye! 13030 boolean removed; 13031 synchronized (mPidsSelfLocked) { 13032 mPidsSelfLocked.remove(app.pid); 13033 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13034 } 13035 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13036 app.processName, app.info.uid); 13037 if (app.isolated) { 13038 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13039 } 13040 app.setPid(0); 13041 } 13042 } 13043 13044 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13045 // Look through the content providers we are waiting to have launched, 13046 // and if any run in this process then either schedule a restart of 13047 // the process or kill the client waiting for it if this process has 13048 // gone bad. 13049 int NL = mLaunchingProviders.size(); 13050 boolean restart = false; 13051 for (int i=0; i<NL; i++) { 13052 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13053 if (cpr.launchingApp == app) { 13054 if (!alwaysBad && !app.bad) { 13055 restart = true; 13056 } else { 13057 removeDyingProviderLocked(app, cpr, true); 13058 // cpr should have been removed from mLaunchingProviders 13059 NL = mLaunchingProviders.size(); 13060 i--; 13061 } 13062 } 13063 } 13064 return restart; 13065 } 13066 13067 // ========================================================= 13068 // SERVICES 13069 // ========================================================= 13070 13071 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13072 int flags) { 13073 enforceNotIsolatedCaller("getServices"); 13074 synchronized (this) { 13075 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13076 } 13077 } 13078 13079 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13080 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13081 synchronized (this) { 13082 return mServices.getRunningServiceControlPanelLocked(name); 13083 } 13084 } 13085 13086 public ComponentName startService(IApplicationThread caller, Intent service, 13087 String resolvedType, int userId) { 13088 enforceNotIsolatedCaller("startService"); 13089 // Refuse possible leaked file descriptors 13090 if (service != null && service.hasFileDescriptors() == true) { 13091 throw new IllegalArgumentException("File descriptors passed in Intent"); 13092 } 13093 13094 if (DEBUG_SERVICE) 13095 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13096 synchronized(this) { 13097 final int callingPid = Binder.getCallingPid(); 13098 final int callingUid = Binder.getCallingUid(); 13099 final long origId = Binder.clearCallingIdentity(); 13100 ComponentName res = mServices.startServiceLocked(caller, service, 13101 resolvedType, callingPid, callingUid, userId); 13102 Binder.restoreCallingIdentity(origId); 13103 return res; 13104 } 13105 } 13106 13107 ComponentName startServiceInPackage(int uid, 13108 Intent service, String resolvedType, int userId) { 13109 synchronized(this) { 13110 if (DEBUG_SERVICE) 13111 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13112 final long origId = Binder.clearCallingIdentity(); 13113 ComponentName res = mServices.startServiceLocked(null, service, 13114 resolvedType, -1, uid, userId); 13115 Binder.restoreCallingIdentity(origId); 13116 return res; 13117 } 13118 } 13119 13120 public int stopService(IApplicationThread caller, Intent service, 13121 String resolvedType, int userId) { 13122 enforceNotIsolatedCaller("stopService"); 13123 // Refuse possible leaked file descriptors 13124 if (service != null && service.hasFileDescriptors() == true) { 13125 throw new IllegalArgumentException("File descriptors passed in Intent"); 13126 } 13127 13128 synchronized(this) { 13129 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13130 } 13131 } 13132 13133 public IBinder peekService(Intent service, String resolvedType) { 13134 enforceNotIsolatedCaller("peekService"); 13135 // Refuse possible leaked file descriptors 13136 if (service != null && service.hasFileDescriptors() == true) { 13137 throw new IllegalArgumentException("File descriptors passed in Intent"); 13138 } 13139 synchronized(this) { 13140 return mServices.peekServiceLocked(service, resolvedType); 13141 } 13142 } 13143 13144 public boolean stopServiceToken(ComponentName className, IBinder token, 13145 int startId) { 13146 synchronized(this) { 13147 return mServices.stopServiceTokenLocked(className, token, startId); 13148 } 13149 } 13150 13151 public void setServiceForeground(ComponentName className, IBinder token, 13152 int id, Notification notification, boolean removeNotification) { 13153 synchronized(this) { 13154 mServices.setServiceForegroundLocked(className, token, id, notification, 13155 removeNotification); 13156 } 13157 } 13158 13159 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13160 boolean requireFull, String name, String callerPackage) { 13161 final int callingUserId = UserHandle.getUserId(callingUid); 13162 if (callingUserId != userId) { 13163 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13164 if ((requireFull || checkComponentPermission( 13165 android.Manifest.permission.INTERACT_ACROSS_USERS, 13166 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13167 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13168 callingPid, callingUid, -1, true) 13169 != PackageManager.PERMISSION_GRANTED) { 13170 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13171 // In this case, they would like to just execute as their 13172 // owner user instead of failing. 13173 userId = callingUserId; 13174 } else { 13175 StringBuilder builder = new StringBuilder(128); 13176 builder.append("Permission Denial: "); 13177 builder.append(name); 13178 if (callerPackage != null) { 13179 builder.append(" from "); 13180 builder.append(callerPackage); 13181 } 13182 builder.append(" asks to run as user "); 13183 builder.append(userId); 13184 builder.append(" but is calling from user "); 13185 builder.append(UserHandle.getUserId(callingUid)); 13186 builder.append("; this requires "); 13187 builder.append(INTERACT_ACROSS_USERS_FULL); 13188 if (!requireFull) { 13189 builder.append(" or "); 13190 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13191 } 13192 String msg = builder.toString(); 13193 Slog.w(TAG, msg); 13194 throw new SecurityException(msg); 13195 } 13196 } 13197 } 13198 if (userId == UserHandle.USER_CURRENT 13199 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13200 // Note that we may be accessing this outside of a lock... 13201 // shouldn't be a big deal, if this is being called outside 13202 // of a locked context there is intrinsically a race with 13203 // the value the caller will receive and someone else changing it. 13204 userId = mCurrentUserId; 13205 } 13206 if (!allowAll && userId < 0) { 13207 throw new IllegalArgumentException( 13208 "Call does not support special user #" + userId); 13209 } 13210 } 13211 return userId; 13212 } 13213 13214 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13215 String className, int flags) { 13216 boolean result = false; 13217 // For apps that don't have pre-defined UIDs, check for permission 13218 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13219 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13220 if (ActivityManager.checkUidPermission( 13221 android.Manifest.permission.INTERACT_ACROSS_USERS, 13222 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13223 ComponentName comp = new ComponentName(aInfo.packageName, className); 13224 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13225 + " requests FLAG_SINGLE_USER, but app does not hold " 13226 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13227 Slog.w(TAG, msg); 13228 throw new SecurityException(msg); 13229 } 13230 // Permission passed 13231 result = true; 13232 } 13233 } else if ("system".equals(componentProcessName)) { 13234 result = true; 13235 } else { 13236 // App with pre-defined UID, check if it's a persistent app 13237 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13238 } 13239 if (DEBUG_MU) { 13240 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13241 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13242 } 13243 return result; 13244 } 13245 13246 /** 13247 * Checks to see if the caller is in the same app as the singleton 13248 * component, or the component is in a special app. It allows special apps 13249 * to export singleton components but prevents exporting singleton 13250 * components for regular apps. 13251 */ 13252 boolean isValidSingletonCall(int callingUid, int componentUid) { 13253 int componentAppId = UserHandle.getAppId(componentUid); 13254 return UserHandle.isSameApp(callingUid, componentUid) 13255 || componentAppId == Process.SYSTEM_UID 13256 || componentAppId == Process.PHONE_UID 13257 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13258 == PackageManager.PERMISSION_GRANTED; 13259 } 13260 13261 public int bindService(IApplicationThread caller, IBinder token, 13262 Intent service, String resolvedType, 13263 IServiceConnection connection, int flags, int userId) { 13264 enforceNotIsolatedCaller("bindService"); 13265 // Refuse possible leaked file descriptors 13266 if (service != null && service.hasFileDescriptors() == true) { 13267 throw new IllegalArgumentException("File descriptors passed in Intent"); 13268 } 13269 13270 synchronized(this) { 13271 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13272 connection, flags, userId); 13273 } 13274 } 13275 13276 public boolean unbindService(IServiceConnection connection) { 13277 synchronized (this) { 13278 return mServices.unbindServiceLocked(connection); 13279 } 13280 } 13281 13282 public void publishService(IBinder token, Intent intent, IBinder service) { 13283 // Refuse possible leaked file descriptors 13284 if (intent != null && intent.hasFileDescriptors() == true) { 13285 throw new IllegalArgumentException("File descriptors passed in Intent"); 13286 } 13287 13288 synchronized(this) { 13289 if (!(token instanceof ServiceRecord)) { 13290 throw new IllegalArgumentException("Invalid service token"); 13291 } 13292 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13293 } 13294 } 13295 13296 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13297 // Refuse possible leaked file descriptors 13298 if (intent != null && intent.hasFileDescriptors() == true) { 13299 throw new IllegalArgumentException("File descriptors passed in Intent"); 13300 } 13301 13302 synchronized(this) { 13303 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13304 } 13305 } 13306 13307 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13308 synchronized(this) { 13309 if (!(token instanceof ServiceRecord)) { 13310 throw new IllegalArgumentException("Invalid service token"); 13311 } 13312 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13313 } 13314 } 13315 13316 // ========================================================= 13317 // BACKUP AND RESTORE 13318 // ========================================================= 13319 13320 // Cause the target app to be launched if necessary and its backup agent 13321 // instantiated. The backup agent will invoke backupAgentCreated() on the 13322 // activity manager to announce its creation. 13323 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13324 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13325 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13326 13327 synchronized(this) { 13328 // !!! TODO: currently no check here that we're already bound 13329 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13330 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13331 synchronized (stats) { 13332 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13333 } 13334 13335 // Backup agent is now in use, its package can't be stopped. 13336 try { 13337 AppGlobals.getPackageManager().setPackageStoppedState( 13338 app.packageName, false, UserHandle.getUserId(app.uid)); 13339 } catch (RemoteException e) { 13340 } catch (IllegalArgumentException e) { 13341 Slog.w(TAG, "Failed trying to unstop package " 13342 + app.packageName + ": " + e); 13343 } 13344 13345 BackupRecord r = new BackupRecord(ss, app, backupMode); 13346 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13347 ? new ComponentName(app.packageName, app.backupAgentName) 13348 : new ComponentName("android", "FullBackupAgent"); 13349 // startProcessLocked() returns existing proc's record if it's already running 13350 ProcessRecord proc = startProcessLocked(app.processName, app, 13351 false, 0, "backup", hostingName, false, false, false); 13352 if (proc == null) { 13353 Slog.e(TAG, "Unable to start backup agent process " + r); 13354 return false; 13355 } 13356 13357 r.app = proc; 13358 mBackupTarget = r; 13359 mBackupAppName = app.packageName; 13360 13361 // Try not to kill the process during backup 13362 updateOomAdjLocked(proc); 13363 13364 // If the process is already attached, schedule the creation of the backup agent now. 13365 // If it is not yet live, this will be done when it attaches to the framework. 13366 if (proc.thread != null) { 13367 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13368 try { 13369 proc.thread.scheduleCreateBackupAgent(app, 13370 compatibilityInfoForPackageLocked(app), backupMode); 13371 } catch (RemoteException e) { 13372 // Will time out on the backup manager side 13373 } 13374 } else { 13375 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13376 } 13377 // Invariants: at this point, the target app process exists and the application 13378 // is either already running or in the process of coming up. mBackupTarget and 13379 // mBackupAppName describe the app, so that when it binds back to the AM we 13380 // know that it's scheduled for a backup-agent operation. 13381 } 13382 13383 return true; 13384 } 13385 13386 @Override 13387 public void clearPendingBackup() { 13388 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13389 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13390 13391 synchronized (this) { 13392 mBackupTarget = null; 13393 mBackupAppName = null; 13394 } 13395 } 13396 13397 // A backup agent has just come up 13398 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13399 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13400 + " = " + agent); 13401 13402 synchronized(this) { 13403 if (!agentPackageName.equals(mBackupAppName)) { 13404 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13405 return; 13406 } 13407 } 13408 13409 long oldIdent = Binder.clearCallingIdentity(); 13410 try { 13411 IBackupManager bm = IBackupManager.Stub.asInterface( 13412 ServiceManager.getService(Context.BACKUP_SERVICE)); 13413 bm.agentConnected(agentPackageName, agent); 13414 } catch (RemoteException e) { 13415 // can't happen; the backup manager service is local 13416 } catch (Exception e) { 13417 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13418 e.printStackTrace(); 13419 } finally { 13420 Binder.restoreCallingIdentity(oldIdent); 13421 } 13422 } 13423 13424 // done with this agent 13425 public void unbindBackupAgent(ApplicationInfo appInfo) { 13426 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13427 if (appInfo == null) { 13428 Slog.w(TAG, "unbind backup agent for null app"); 13429 return; 13430 } 13431 13432 synchronized(this) { 13433 try { 13434 if (mBackupAppName == null) { 13435 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13436 return; 13437 } 13438 13439 if (!mBackupAppName.equals(appInfo.packageName)) { 13440 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13441 return; 13442 } 13443 13444 // Not backing this app up any more; reset its OOM adjustment 13445 final ProcessRecord proc = mBackupTarget.app; 13446 updateOomAdjLocked(proc); 13447 13448 // If the app crashed during backup, 'thread' will be null here 13449 if (proc.thread != null) { 13450 try { 13451 proc.thread.scheduleDestroyBackupAgent(appInfo, 13452 compatibilityInfoForPackageLocked(appInfo)); 13453 } catch (Exception e) { 13454 Slog.e(TAG, "Exception when unbinding backup agent:"); 13455 e.printStackTrace(); 13456 } 13457 } 13458 } finally { 13459 mBackupTarget = null; 13460 mBackupAppName = null; 13461 } 13462 } 13463 } 13464 // ========================================================= 13465 // BROADCASTS 13466 // ========================================================= 13467 13468 private final List getStickiesLocked(String action, IntentFilter filter, 13469 List cur, int userId) { 13470 final ContentResolver resolver = mContext.getContentResolver(); 13471 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13472 if (stickies == null) { 13473 return cur; 13474 } 13475 final ArrayList<Intent> list = stickies.get(action); 13476 if (list == null) { 13477 return cur; 13478 } 13479 int N = list.size(); 13480 for (int i=0; i<N; i++) { 13481 Intent intent = list.get(i); 13482 if (filter.match(resolver, intent, true, TAG) >= 0) { 13483 if (cur == null) { 13484 cur = new ArrayList<Intent>(); 13485 } 13486 cur.add(intent); 13487 } 13488 } 13489 return cur; 13490 } 13491 13492 boolean isPendingBroadcastProcessLocked(int pid) { 13493 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13494 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13495 } 13496 13497 void skipPendingBroadcastLocked(int pid) { 13498 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13499 for (BroadcastQueue queue : mBroadcastQueues) { 13500 queue.skipPendingBroadcastLocked(pid); 13501 } 13502 } 13503 13504 // The app just attached; send any pending broadcasts that it should receive 13505 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13506 boolean didSomething = false; 13507 for (BroadcastQueue queue : mBroadcastQueues) { 13508 didSomething |= queue.sendPendingBroadcastsLocked(app); 13509 } 13510 return didSomething; 13511 } 13512 13513 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13514 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13515 enforceNotIsolatedCaller("registerReceiver"); 13516 int callingUid; 13517 int callingPid; 13518 synchronized(this) { 13519 ProcessRecord callerApp = null; 13520 if (caller != null) { 13521 callerApp = getRecordForAppLocked(caller); 13522 if (callerApp == null) { 13523 throw new SecurityException( 13524 "Unable to find app for caller " + caller 13525 + " (pid=" + Binder.getCallingPid() 13526 + ") when registering receiver " + receiver); 13527 } 13528 if (callerApp.info.uid != Process.SYSTEM_UID && 13529 !callerApp.pkgList.containsKey(callerPackage) && 13530 !"android".equals(callerPackage)) { 13531 throw new SecurityException("Given caller package " + callerPackage 13532 + " is not running in process " + callerApp); 13533 } 13534 callingUid = callerApp.info.uid; 13535 callingPid = callerApp.pid; 13536 } else { 13537 callerPackage = null; 13538 callingUid = Binder.getCallingUid(); 13539 callingPid = Binder.getCallingPid(); 13540 } 13541 13542 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13543 true, true, "registerReceiver", callerPackage); 13544 13545 List allSticky = null; 13546 13547 // Look for any matching sticky broadcasts... 13548 Iterator actions = filter.actionsIterator(); 13549 if (actions != null) { 13550 while (actions.hasNext()) { 13551 String action = (String)actions.next(); 13552 allSticky = getStickiesLocked(action, filter, allSticky, 13553 UserHandle.USER_ALL); 13554 allSticky = getStickiesLocked(action, filter, allSticky, 13555 UserHandle.getUserId(callingUid)); 13556 } 13557 } else { 13558 allSticky = getStickiesLocked(null, filter, allSticky, 13559 UserHandle.USER_ALL); 13560 allSticky = getStickiesLocked(null, filter, allSticky, 13561 UserHandle.getUserId(callingUid)); 13562 } 13563 13564 // The first sticky in the list is returned directly back to 13565 // the client. 13566 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13567 13568 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13569 + ": " + sticky); 13570 13571 if (receiver == null) { 13572 return sticky; 13573 } 13574 13575 ReceiverList rl 13576 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13577 if (rl == null) { 13578 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13579 userId, receiver); 13580 if (rl.app != null) { 13581 rl.app.receivers.add(rl); 13582 } else { 13583 try { 13584 receiver.asBinder().linkToDeath(rl, 0); 13585 } catch (RemoteException e) { 13586 return sticky; 13587 } 13588 rl.linkedToDeath = true; 13589 } 13590 mRegisteredReceivers.put(receiver.asBinder(), rl); 13591 } else if (rl.uid != callingUid) { 13592 throw new IllegalArgumentException( 13593 "Receiver requested to register for uid " + callingUid 13594 + " was previously registered for uid " + rl.uid); 13595 } else if (rl.pid != callingPid) { 13596 throw new IllegalArgumentException( 13597 "Receiver requested to register for pid " + callingPid 13598 + " was previously registered for pid " + rl.pid); 13599 } else if (rl.userId != userId) { 13600 throw new IllegalArgumentException( 13601 "Receiver requested to register for user " + userId 13602 + " was previously registered for user " + rl.userId); 13603 } 13604 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13605 permission, callingUid, userId); 13606 rl.add(bf); 13607 if (!bf.debugCheck()) { 13608 Slog.w(TAG, "==> For Dynamic broadast"); 13609 } 13610 mReceiverResolver.addFilter(bf); 13611 13612 // Enqueue broadcasts for all existing stickies that match 13613 // this filter. 13614 if (allSticky != null) { 13615 ArrayList receivers = new ArrayList(); 13616 receivers.add(bf); 13617 13618 int N = allSticky.size(); 13619 for (int i=0; i<N; i++) { 13620 Intent intent = (Intent)allSticky.get(i); 13621 BroadcastQueue queue = broadcastQueueForIntent(intent); 13622 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13623 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13624 null, null, false, true, true, -1); 13625 queue.enqueueParallelBroadcastLocked(r); 13626 queue.scheduleBroadcastsLocked(); 13627 } 13628 } 13629 13630 return sticky; 13631 } 13632 } 13633 13634 public void unregisterReceiver(IIntentReceiver receiver) { 13635 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13636 13637 final long origId = Binder.clearCallingIdentity(); 13638 try { 13639 boolean doTrim = false; 13640 13641 synchronized(this) { 13642 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13643 if (rl != null) { 13644 if (rl.curBroadcast != null) { 13645 BroadcastRecord r = rl.curBroadcast; 13646 final boolean doNext = finishReceiverLocked( 13647 receiver.asBinder(), r.resultCode, r.resultData, 13648 r.resultExtras, r.resultAbort); 13649 if (doNext) { 13650 doTrim = true; 13651 r.queue.processNextBroadcast(false); 13652 } 13653 } 13654 13655 if (rl.app != null) { 13656 rl.app.receivers.remove(rl); 13657 } 13658 removeReceiverLocked(rl); 13659 if (rl.linkedToDeath) { 13660 rl.linkedToDeath = false; 13661 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13662 } 13663 } 13664 } 13665 13666 // If we actually concluded any broadcasts, we might now be able 13667 // to trim the recipients' apps from our working set 13668 if (doTrim) { 13669 trimApplications(); 13670 return; 13671 } 13672 13673 } finally { 13674 Binder.restoreCallingIdentity(origId); 13675 } 13676 } 13677 13678 void removeReceiverLocked(ReceiverList rl) { 13679 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13680 int N = rl.size(); 13681 for (int i=0; i<N; i++) { 13682 mReceiverResolver.removeFilter(rl.get(i)); 13683 } 13684 } 13685 13686 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13687 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13688 ProcessRecord r = mLruProcesses.get(i); 13689 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13690 try { 13691 r.thread.dispatchPackageBroadcast(cmd, packages); 13692 } catch (RemoteException ex) { 13693 } 13694 } 13695 } 13696 } 13697 13698 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13699 int[] users) { 13700 List<ResolveInfo> receivers = null; 13701 try { 13702 HashSet<ComponentName> singleUserReceivers = null; 13703 boolean scannedFirstReceivers = false; 13704 for (int user : users) { 13705 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13706 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13707 if (user != 0 && newReceivers != null) { 13708 // If this is not the primary user, we need to check for 13709 // any receivers that should be filtered out. 13710 for (int i=0; i<newReceivers.size(); i++) { 13711 ResolveInfo ri = newReceivers.get(i); 13712 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13713 newReceivers.remove(i); 13714 i--; 13715 } 13716 } 13717 } 13718 if (newReceivers != null && newReceivers.size() == 0) { 13719 newReceivers = null; 13720 } 13721 if (receivers == null) { 13722 receivers = newReceivers; 13723 } else if (newReceivers != null) { 13724 // We need to concatenate the additional receivers 13725 // found with what we have do far. This would be easy, 13726 // but we also need to de-dup any receivers that are 13727 // singleUser. 13728 if (!scannedFirstReceivers) { 13729 // Collect any single user receivers we had already retrieved. 13730 scannedFirstReceivers = true; 13731 for (int i=0; i<receivers.size(); i++) { 13732 ResolveInfo ri = receivers.get(i); 13733 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13734 ComponentName cn = new ComponentName( 13735 ri.activityInfo.packageName, ri.activityInfo.name); 13736 if (singleUserReceivers == null) { 13737 singleUserReceivers = new HashSet<ComponentName>(); 13738 } 13739 singleUserReceivers.add(cn); 13740 } 13741 } 13742 } 13743 // Add the new results to the existing results, tracking 13744 // and de-dupping single user receivers. 13745 for (int i=0; i<newReceivers.size(); i++) { 13746 ResolveInfo ri = newReceivers.get(i); 13747 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13748 ComponentName cn = new ComponentName( 13749 ri.activityInfo.packageName, ri.activityInfo.name); 13750 if (singleUserReceivers == null) { 13751 singleUserReceivers = new HashSet<ComponentName>(); 13752 } 13753 if (!singleUserReceivers.contains(cn)) { 13754 singleUserReceivers.add(cn); 13755 receivers.add(ri); 13756 } 13757 } else { 13758 receivers.add(ri); 13759 } 13760 } 13761 } 13762 } 13763 } catch (RemoteException ex) { 13764 // pm is in same process, this will never happen. 13765 } 13766 return receivers; 13767 } 13768 13769 private final int broadcastIntentLocked(ProcessRecord callerApp, 13770 String callerPackage, Intent intent, String resolvedType, 13771 IIntentReceiver resultTo, int resultCode, String resultData, 13772 Bundle map, String requiredPermission, int appOp, 13773 boolean ordered, boolean sticky, int callingPid, int callingUid, 13774 int userId) { 13775 intent = new Intent(intent); 13776 13777 // By default broadcasts do not go to stopped apps. 13778 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13779 13780 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13781 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13782 + " ordered=" + ordered + " userid=" + userId); 13783 if ((resultTo != null) && !ordered) { 13784 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13785 } 13786 13787 userId = handleIncomingUser(callingPid, callingUid, userId, 13788 true, false, "broadcast", callerPackage); 13789 13790 // Make sure that the user who is receiving this broadcast is started. 13791 // If not, we will just skip it. 13792 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13793 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13794 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13795 Slog.w(TAG, "Skipping broadcast of " + intent 13796 + ": user " + userId + " is stopped"); 13797 return ActivityManager.BROADCAST_SUCCESS; 13798 } 13799 } 13800 13801 /* 13802 * Prevent non-system code (defined here to be non-persistent 13803 * processes) from sending protected broadcasts. 13804 */ 13805 int callingAppId = UserHandle.getAppId(callingUid); 13806 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13807 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 13808 || callingUid == 0) { 13809 // Always okay. 13810 } else if (callerApp == null || !callerApp.persistent) { 13811 try { 13812 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13813 intent.getAction())) { 13814 String msg = "Permission Denial: not allowed to send broadcast " 13815 + intent.getAction() + " from pid=" 13816 + callingPid + ", uid=" + callingUid; 13817 Slog.w(TAG, msg); 13818 throw new SecurityException(msg); 13819 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13820 // Special case for compatibility: we don't want apps to send this, 13821 // but historically it has not been protected and apps may be using it 13822 // to poke their own app widget. So, instead of making it protected, 13823 // just limit it to the caller. 13824 if (callerApp == null) { 13825 String msg = "Permission Denial: not allowed to send broadcast " 13826 + intent.getAction() + " from unknown caller."; 13827 Slog.w(TAG, msg); 13828 throw new SecurityException(msg); 13829 } else if (intent.getComponent() != null) { 13830 // They are good enough to send to an explicit component... verify 13831 // it is being sent to the calling app. 13832 if (!intent.getComponent().getPackageName().equals( 13833 callerApp.info.packageName)) { 13834 String msg = "Permission Denial: not allowed to send broadcast " 13835 + intent.getAction() + " to " 13836 + intent.getComponent().getPackageName() + " from " 13837 + callerApp.info.packageName; 13838 Slog.w(TAG, msg); 13839 throw new SecurityException(msg); 13840 } 13841 } else { 13842 // Limit broadcast to their own package. 13843 intent.setPackage(callerApp.info.packageName); 13844 } 13845 } 13846 } catch (RemoteException e) { 13847 Slog.w(TAG, "Remote exception", e); 13848 return ActivityManager.BROADCAST_SUCCESS; 13849 } 13850 } 13851 13852 // Handle special intents: if this broadcast is from the package 13853 // manager about a package being removed, we need to remove all of 13854 // its activities from the history stack. 13855 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13856 intent.getAction()); 13857 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13858 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13859 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13860 || uidRemoved) { 13861 if (checkComponentPermission( 13862 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13863 callingPid, callingUid, -1, true) 13864 == PackageManager.PERMISSION_GRANTED) { 13865 if (uidRemoved) { 13866 final Bundle intentExtras = intent.getExtras(); 13867 final int uid = intentExtras != null 13868 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13869 if (uid >= 0) { 13870 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13871 synchronized (bs) { 13872 bs.removeUidStatsLocked(uid); 13873 } 13874 mAppOpsService.uidRemoved(uid); 13875 } 13876 } else { 13877 // If resources are unavailable just force stop all 13878 // those packages and flush the attribute cache as well. 13879 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13880 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13881 if (list != null && (list.length > 0)) { 13882 for (String pkg : list) { 13883 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13884 "storage unmount"); 13885 } 13886 sendPackageBroadcastLocked( 13887 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13888 } 13889 } else { 13890 Uri data = intent.getData(); 13891 String ssp; 13892 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13893 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13894 intent.getAction()); 13895 boolean fullUninstall = removed && 13896 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13897 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13898 forceStopPackageLocked(ssp, UserHandle.getAppId( 13899 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13900 false, fullUninstall, userId, 13901 removed ? "pkg removed" : "pkg changed"); 13902 } 13903 if (removed) { 13904 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13905 new String[] {ssp}, userId); 13906 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13907 mAppOpsService.packageRemoved( 13908 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13909 13910 // Remove all permissions granted from/to this package 13911 removeUriPermissionsForPackageLocked(ssp, userId, true); 13912 } 13913 } 13914 } 13915 } 13916 } 13917 } else { 13918 String msg = "Permission Denial: " + intent.getAction() 13919 + " broadcast from " + callerPackage + " (pid=" + callingPid 13920 + ", uid=" + callingUid + ")" 13921 + " requires " 13922 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13923 Slog.w(TAG, msg); 13924 throw new SecurityException(msg); 13925 } 13926 13927 // Special case for adding a package: by default turn on compatibility 13928 // mode. 13929 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13930 Uri data = intent.getData(); 13931 String ssp; 13932 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13933 mCompatModePackages.handlePackageAddedLocked(ssp, 13934 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13935 } 13936 } 13937 13938 /* 13939 * If this is the time zone changed action, queue up a message that will reset the timezone 13940 * of all currently running processes. This message will get queued up before the broadcast 13941 * happens. 13942 */ 13943 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13944 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13945 } 13946 13947 /* 13948 * If the user set the time, let all running processes know. 13949 */ 13950 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13951 final int is24Hour = intent.getBooleanExtra( 13952 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13953 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13954 } 13955 13956 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13957 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13958 } 13959 13960 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13961 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 13962 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13963 } 13964 13965 // Add to the sticky list if requested. 13966 if (sticky) { 13967 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13968 callingPid, callingUid) 13969 != PackageManager.PERMISSION_GRANTED) { 13970 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13971 + callingPid + ", uid=" + callingUid 13972 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13973 Slog.w(TAG, msg); 13974 throw new SecurityException(msg); 13975 } 13976 if (requiredPermission != null) { 13977 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13978 + " and enforce permission " + requiredPermission); 13979 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13980 } 13981 if (intent.getComponent() != null) { 13982 throw new SecurityException( 13983 "Sticky broadcasts can't target a specific component"); 13984 } 13985 // We use userId directly here, since the "all" target is maintained 13986 // as a separate set of sticky broadcasts. 13987 if (userId != UserHandle.USER_ALL) { 13988 // But first, if this is not a broadcast to all users, then 13989 // make sure it doesn't conflict with an existing broadcast to 13990 // all users. 13991 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13992 UserHandle.USER_ALL); 13993 if (stickies != null) { 13994 ArrayList<Intent> list = stickies.get(intent.getAction()); 13995 if (list != null) { 13996 int N = list.size(); 13997 int i; 13998 for (i=0; i<N; i++) { 13999 if (intent.filterEquals(list.get(i))) { 14000 throw new IllegalArgumentException( 14001 "Sticky broadcast " + intent + " for user " 14002 + userId + " conflicts with existing global broadcast"); 14003 } 14004 } 14005 } 14006 } 14007 } 14008 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14009 if (stickies == null) { 14010 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14011 mStickyBroadcasts.put(userId, stickies); 14012 } 14013 ArrayList<Intent> list = stickies.get(intent.getAction()); 14014 if (list == null) { 14015 list = new ArrayList<Intent>(); 14016 stickies.put(intent.getAction(), list); 14017 } 14018 int N = list.size(); 14019 int i; 14020 for (i=0; i<N; i++) { 14021 if (intent.filterEquals(list.get(i))) { 14022 // This sticky already exists, replace it. 14023 list.set(i, new Intent(intent)); 14024 break; 14025 } 14026 } 14027 if (i >= N) { 14028 list.add(new Intent(intent)); 14029 } 14030 } 14031 14032 int[] users; 14033 if (userId == UserHandle.USER_ALL) { 14034 // Caller wants broadcast to go to all started users. 14035 users = mStartedUserArray; 14036 } else { 14037 // Caller wants broadcast to go to one specific user. 14038 users = new int[] {userId}; 14039 } 14040 14041 // Figure out who all will receive this broadcast. 14042 List receivers = null; 14043 List<BroadcastFilter> registeredReceivers = null; 14044 // Need to resolve the intent to interested receivers... 14045 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14046 == 0) { 14047 receivers = collectReceiverComponents(intent, resolvedType, users); 14048 } 14049 if (intent.getComponent() == null) { 14050 registeredReceivers = mReceiverResolver.queryIntent(intent, 14051 resolvedType, false, userId); 14052 } 14053 14054 final boolean replacePending = 14055 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14056 14057 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14058 + " replacePending=" + replacePending); 14059 14060 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14061 if (!ordered && NR > 0) { 14062 // If we are not serializing this broadcast, then send the 14063 // registered receivers separately so they don't wait for the 14064 // components to be launched. 14065 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14066 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14067 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14068 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14069 ordered, sticky, false, userId); 14070 if (DEBUG_BROADCAST) Slog.v( 14071 TAG, "Enqueueing parallel broadcast " + r); 14072 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14073 if (!replaced) { 14074 queue.enqueueParallelBroadcastLocked(r); 14075 queue.scheduleBroadcastsLocked(); 14076 } 14077 registeredReceivers = null; 14078 NR = 0; 14079 } 14080 14081 // Merge into one list. 14082 int ir = 0; 14083 if (receivers != null) { 14084 // A special case for PACKAGE_ADDED: do not allow the package 14085 // being added to see this broadcast. This prevents them from 14086 // using this as a back door to get run as soon as they are 14087 // installed. Maybe in the future we want to have a special install 14088 // broadcast or such for apps, but we'd like to deliberately make 14089 // this decision. 14090 String skipPackages[] = null; 14091 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14092 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14093 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14094 Uri data = intent.getData(); 14095 if (data != null) { 14096 String pkgName = data.getSchemeSpecificPart(); 14097 if (pkgName != null) { 14098 skipPackages = new String[] { pkgName }; 14099 } 14100 } 14101 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14102 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14103 } 14104 if (skipPackages != null && (skipPackages.length > 0)) { 14105 for (String skipPackage : skipPackages) { 14106 if (skipPackage != null) { 14107 int NT = receivers.size(); 14108 for (int it=0; it<NT; it++) { 14109 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14110 if (curt.activityInfo.packageName.equals(skipPackage)) { 14111 receivers.remove(it); 14112 it--; 14113 NT--; 14114 } 14115 } 14116 } 14117 } 14118 } 14119 14120 int NT = receivers != null ? receivers.size() : 0; 14121 int it = 0; 14122 ResolveInfo curt = null; 14123 BroadcastFilter curr = null; 14124 while (it < NT && ir < NR) { 14125 if (curt == null) { 14126 curt = (ResolveInfo)receivers.get(it); 14127 } 14128 if (curr == null) { 14129 curr = registeredReceivers.get(ir); 14130 } 14131 if (curr.getPriority() >= curt.priority) { 14132 // Insert this broadcast record into the final list. 14133 receivers.add(it, curr); 14134 ir++; 14135 curr = null; 14136 it++; 14137 NT++; 14138 } else { 14139 // Skip to the next ResolveInfo in the final list. 14140 it++; 14141 curt = null; 14142 } 14143 } 14144 } 14145 while (ir < NR) { 14146 if (receivers == null) { 14147 receivers = new ArrayList(); 14148 } 14149 receivers.add(registeredReceivers.get(ir)); 14150 ir++; 14151 } 14152 14153 if ((receivers != null && receivers.size() > 0) 14154 || resultTo != null) { 14155 BroadcastQueue queue = broadcastQueueForIntent(intent); 14156 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14157 callerPackage, callingPid, callingUid, resolvedType, 14158 requiredPermission, appOp, receivers, resultTo, resultCode, 14159 resultData, map, ordered, sticky, false, userId); 14160 if (DEBUG_BROADCAST) Slog.v( 14161 TAG, "Enqueueing ordered broadcast " + r 14162 + ": prev had " + queue.mOrderedBroadcasts.size()); 14163 if (DEBUG_BROADCAST) { 14164 int seq = r.intent.getIntExtra("seq", -1); 14165 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14166 } 14167 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14168 if (!replaced) { 14169 queue.enqueueOrderedBroadcastLocked(r); 14170 queue.scheduleBroadcastsLocked(); 14171 } 14172 } 14173 14174 return ActivityManager.BROADCAST_SUCCESS; 14175 } 14176 14177 final Intent verifyBroadcastLocked(Intent intent) { 14178 // Refuse possible leaked file descriptors 14179 if (intent != null && intent.hasFileDescriptors() == true) { 14180 throw new IllegalArgumentException("File descriptors passed in Intent"); 14181 } 14182 14183 int flags = intent.getFlags(); 14184 14185 if (!mProcessesReady) { 14186 // if the caller really truly claims to know what they're doing, go 14187 // ahead and allow the broadcast without launching any receivers 14188 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14189 intent = new Intent(intent); 14190 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14191 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14192 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14193 + " before boot completion"); 14194 throw new IllegalStateException("Cannot broadcast before boot completed"); 14195 } 14196 } 14197 14198 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14199 throw new IllegalArgumentException( 14200 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14201 } 14202 14203 return intent; 14204 } 14205 14206 public final int broadcastIntent(IApplicationThread caller, 14207 Intent intent, String resolvedType, IIntentReceiver resultTo, 14208 int resultCode, String resultData, Bundle map, 14209 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14210 enforceNotIsolatedCaller("broadcastIntent"); 14211 synchronized(this) { 14212 intent = verifyBroadcastLocked(intent); 14213 14214 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14215 final int callingPid = Binder.getCallingPid(); 14216 final int callingUid = Binder.getCallingUid(); 14217 final long origId = Binder.clearCallingIdentity(); 14218 int res = broadcastIntentLocked(callerApp, 14219 callerApp != null ? callerApp.info.packageName : null, 14220 intent, resolvedType, resultTo, 14221 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14222 callingPid, callingUid, userId); 14223 Binder.restoreCallingIdentity(origId); 14224 return res; 14225 } 14226 } 14227 14228 int broadcastIntentInPackage(String packageName, int uid, 14229 Intent intent, String resolvedType, IIntentReceiver resultTo, 14230 int resultCode, String resultData, Bundle map, 14231 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14232 synchronized(this) { 14233 intent = verifyBroadcastLocked(intent); 14234 14235 final long origId = Binder.clearCallingIdentity(); 14236 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14237 resultTo, resultCode, resultData, map, requiredPermission, 14238 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14239 Binder.restoreCallingIdentity(origId); 14240 return res; 14241 } 14242 } 14243 14244 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14245 // Refuse possible leaked file descriptors 14246 if (intent != null && intent.hasFileDescriptors() == true) { 14247 throw new IllegalArgumentException("File descriptors passed in Intent"); 14248 } 14249 14250 userId = handleIncomingUser(Binder.getCallingPid(), 14251 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14252 14253 synchronized(this) { 14254 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14255 != PackageManager.PERMISSION_GRANTED) { 14256 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14257 + Binder.getCallingPid() 14258 + ", uid=" + Binder.getCallingUid() 14259 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14260 Slog.w(TAG, msg); 14261 throw new SecurityException(msg); 14262 } 14263 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14264 if (stickies != null) { 14265 ArrayList<Intent> list = stickies.get(intent.getAction()); 14266 if (list != null) { 14267 int N = list.size(); 14268 int i; 14269 for (i=0; i<N; i++) { 14270 if (intent.filterEquals(list.get(i))) { 14271 list.remove(i); 14272 break; 14273 } 14274 } 14275 if (list.size() <= 0) { 14276 stickies.remove(intent.getAction()); 14277 } 14278 } 14279 if (stickies.size() <= 0) { 14280 mStickyBroadcasts.remove(userId); 14281 } 14282 } 14283 } 14284 } 14285 14286 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14287 String resultData, Bundle resultExtras, boolean resultAbort) { 14288 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14289 if (r == null) { 14290 Slog.w(TAG, "finishReceiver called but not found on queue"); 14291 return false; 14292 } 14293 14294 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14295 } 14296 14297 void backgroundServicesFinishedLocked(int userId) { 14298 for (BroadcastQueue queue : mBroadcastQueues) { 14299 queue.backgroundServicesFinishedLocked(userId); 14300 } 14301 } 14302 14303 public void finishReceiver(IBinder who, int resultCode, String resultData, 14304 Bundle resultExtras, boolean resultAbort) { 14305 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14306 14307 // Refuse possible leaked file descriptors 14308 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14309 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14310 } 14311 14312 final long origId = Binder.clearCallingIdentity(); 14313 try { 14314 boolean doNext = false; 14315 BroadcastRecord r; 14316 14317 synchronized(this) { 14318 r = broadcastRecordForReceiverLocked(who); 14319 if (r != null) { 14320 doNext = r.queue.finishReceiverLocked(r, resultCode, 14321 resultData, resultExtras, resultAbort, true); 14322 } 14323 } 14324 14325 if (doNext) { 14326 r.queue.processNextBroadcast(false); 14327 } 14328 trimApplications(); 14329 } finally { 14330 Binder.restoreCallingIdentity(origId); 14331 } 14332 } 14333 14334 // ========================================================= 14335 // INSTRUMENTATION 14336 // ========================================================= 14337 14338 public boolean startInstrumentation(ComponentName className, 14339 String profileFile, int flags, Bundle arguments, 14340 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14341 int userId, String abiOverride) { 14342 enforceNotIsolatedCaller("startInstrumentation"); 14343 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14344 userId, false, true, "startInstrumentation", null); 14345 // Refuse possible leaked file descriptors 14346 if (arguments != null && arguments.hasFileDescriptors()) { 14347 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14348 } 14349 14350 synchronized(this) { 14351 InstrumentationInfo ii = null; 14352 ApplicationInfo ai = null; 14353 try { 14354 ii = mContext.getPackageManager().getInstrumentationInfo( 14355 className, STOCK_PM_FLAGS); 14356 ai = AppGlobals.getPackageManager().getApplicationInfo( 14357 ii.targetPackage, STOCK_PM_FLAGS, userId); 14358 } catch (PackageManager.NameNotFoundException e) { 14359 } catch (RemoteException e) { 14360 } 14361 if (ii == null) { 14362 reportStartInstrumentationFailure(watcher, className, 14363 "Unable to find instrumentation info for: " + className); 14364 return false; 14365 } 14366 if (ai == null) { 14367 reportStartInstrumentationFailure(watcher, className, 14368 "Unable to find instrumentation target package: " + ii.targetPackage); 14369 return false; 14370 } 14371 14372 int match = mContext.getPackageManager().checkSignatures( 14373 ii.targetPackage, ii.packageName); 14374 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14375 String msg = "Permission Denial: starting instrumentation " 14376 + className + " from pid=" 14377 + Binder.getCallingPid() 14378 + ", uid=" + Binder.getCallingPid() 14379 + " not allowed because package " + ii.packageName 14380 + " does not have a signature matching the target " 14381 + ii.targetPackage; 14382 reportStartInstrumentationFailure(watcher, className, msg); 14383 throw new SecurityException(msg); 14384 } 14385 14386 final long origId = Binder.clearCallingIdentity(); 14387 // Instrumentation can kill and relaunch even persistent processes 14388 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14389 "start instr"); 14390 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14391 app.instrumentationClass = className; 14392 app.instrumentationInfo = ai; 14393 app.instrumentationProfileFile = profileFile; 14394 app.instrumentationArguments = arguments; 14395 app.instrumentationWatcher = watcher; 14396 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14397 app.instrumentationResultClass = className; 14398 Binder.restoreCallingIdentity(origId); 14399 } 14400 14401 return true; 14402 } 14403 14404 /** 14405 * Report errors that occur while attempting to start Instrumentation. Always writes the 14406 * error to the logs, but if somebody is watching, send the report there too. This enables 14407 * the "am" command to report errors with more information. 14408 * 14409 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14410 * @param cn The component name of the instrumentation. 14411 * @param report The error report. 14412 */ 14413 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14414 ComponentName cn, String report) { 14415 Slog.w(TAG, report); 14416 try { 14417 if (watcher != null) { 14418 Bundle results = new Bundle(); 14419 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14420 results.putString("Error", report); 14421 watcher.instrumentationStatus(cn, -1, results); 14422 } 14423 } catch (RemoteException e) { 14424 Slog.w(TAG, e); 14425 } 14426 } 14427 14428 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14429 if (app.instrumentationWatcher != null) { 14430 try { 14431 // NOTE: IInstrumentationWatcher *must* be oneway here 14432 app.instrumentationWatcher.instrumentationFinished( 14433 app.instrumentationClass, 14434 resultCode, 14435 results); 14436 } catch (RemoteException e) { 14437 } 14438 } 14439 if (app.instrumentationUiAutomationConnection != null) { 14440 try { 14441 app.instrumentationUiAutomationConnection.shutdown(); 14442 } catch (RemoteException re) { 14443 /* ignore */ 14444 } 14445 // Only a UiAutomation can set this flag and now that 14446 // it is finished we make sure it is reset to its default. 14447 mUserIsMonkey = false; 14448 } 14449 app.instrumentationWatcher = null; 14450 app.instrumentationUiAutomationConnection = null; 14451 app.instrumentationClass = null; 14452 app.instrumentationInfo = null; 14453 app.instrumentationProfileFile = null; 14454 app.instrumentationArguments = null; 14455 14456 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14457 "finished inst"); 14458 } 14459 14460 public void finishInstrumentation(IApplicationThread target, 14461 int resultCode, Bundle results) { 14462 int userId = UserHandle.getCallingUserId(); 14463 // Refuse possible leaked file descriptors 14464 if (results != null && results.hasFileDescriptors()) { 14465 throw new IllegalArgumentException("File descriptors passed in Intent"); 14466 } 14467 14468 synchronized(this) { 14469 ProcessRecord app = getRecordForAppLocked(target); 14470 if (app == null) { 14471 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14472 return; 14473 } 14474 final long origId = Binder.clearCallingIdentity(); 14475 finishInstrumentationLocked(app, resultCode, results); 14476 Binder.restoreCallingIdentity(origId); 14477 } 14478 } 14479 14480 // ========================================================= 14481 // CONFIGURATION 14482 // ========================================================= 14483 14484 public ConfigurationInfo getDeviceConfigurationInfo() { 14485 ConfigurationInfo config = new ConfigurationInfo(); 14486 synchronized (this) { 14487 config.reqTouchScreen = mConfiguration.touchscreen; 14488 config.reqKeyboardType = mConfiguration.keyboard; 14489 config.reqNavigation = mConfiguration.navigation; 14490 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14491 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14492 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14493 } 14494 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14495 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14496 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14497 } 14498 config.reqGlEsVersion = GL_ES_VERSION; 14499 } 14500 return config; 14501 } 14502 14503 ActivityStack getFocusedStack() { 14504 return mStackSupervisor.getFocusedStack(); 14505 } 14506 14507 public Configuration getConfiguration() { 14508 Configuration ci; 14509 synchronized(this) { 14510 ci = new Configuration(mConfiguration); 14511 } 14512 return ci; 14513 } 14514 14515 public void updatePersistentConfiguration(Configuration values) { 14516 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14517 "updateConfiguration()"); 14518 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14519 "updateConfiguration()"); 14520 if (values == null) { 14521 throw new NullPointerException("Configuration must not be null"); 14522 } 14523 14524 synchronized(this) { 14525 final long origId = Binder.clearCallingIdentity(); 14526 updateConfigurationLocked(values, null, true, false); 14527 Binder.restoreCallingIdentity(origId); 14528 } 14529 } 14530 14531 public void updateConfiguration(Configuration values) { 14532 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14533 "updateConfiguration()"); 14534 14535 synchronized(this) { 14536 if (values == null && mWindowManager != null) { 14537 // sentinel: fetch the current configuration from the window manager 14538 values = mWindowManager.computeNewConfiguration(); 14539 } 14540 14541 if (mWindowManager != null) { 14542 mProcessList.applyDisplaySize(mWindowManager); 14543 } 14544 14545 final long origId = Binder.clearCallingIdentity(); 14546 if (values != null) { 14547 Settings.System.clearConfiguration(values); 14548 } 14549 updateConfigurationLocked(values, null, false, false); 14550 Binder.restoreCallingIdentity(origId); 14551 } 14552 } 14553 14554 /** 14555 * Do either or both things: (1) change the current configuration, and (2) 14556 * make sure the given activity is running with the (now) current 14557 * configuration. Returns true if the activity has been left running, or 14558 * false if <var>starting</var> is being destroyed to match the new 14559 * configuration. 14560 * @param persistent TODO 14561 */ 14562 boolean updateConfigurationLocked(Configuration values, 14563 ActivityRecord starting, boolean persistent, boolean initLocale) { 14564 int changes = 0; 14565 14566 if (values != null) { 14567 Configuration newConfig = new Configuration(mConfiguration); 14568 changes = newConfig.updateFrom(values); 14569 if (changes != 0) { 14570 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14571 Slog.i(TAG, "Updating configuration to: " + values); 14572 } 14573 14574 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14575 14576 if (values.locale != null && !initLocale) { 14577 saveLocaleLocked(values.locale, 14578 !values.locale.equals(mConfiguration.locale), 14579 values.userSetLocale); 14580 } 14581 14582 mConfigurationSeq++; 14583 if (mConfigurationSeq <= 0) { 14584 mConfigurationSeq = 1; 14585 } 14586 newConfig.seq = mConfigurationSeq; 14587 mConfiguration = newConfig; 14588 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14589 mUsageStatsService.noteStartConfig(newConfig); 14590 14591 final Configuration configCopy = new Configuration(mConfiguration); 14592 14593 // TODO: If our config changes, should we auto dismiss any currently 14594 // showing dialogs? 14595 mShowDialogs = shouldShowDialogs(newConfig); 14596 14597 AttributeCache ac = AttributeCache.instance(); 14598 if (ac != null) { 14599 ac.updateConfiguration(configCopy); 14600 } 14601 14602 // Make sure all resources in our process are updated 14603 // right now, so that anyone who is going to retrieve 14604 // resource values after we return will be sure to get 14605 // the new ones. This is especially important during 14606 // boot, where the first config change needs to guarantee 14607 // all resources have that config before following boot 14608 // code is executed. 14609 mSystemThread.applyConfigurationToResources(configCopy); 14610 14611 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14612 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14613 msg.obj = new Configuration(configCopy); 14614 mHandler.sendMessage(msg); 14615 } 14616 14617 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14618 ProcessRecord app = mLruProcesses.get(i); 14619 try { 14620 if (app.thread != null) { 14621 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14622 + app.processName + " new config " + mConfiguration); 14623 app.thread.scheduleConfigurationChanged(configCopy); 14624 } 14625 } catch (Exception e) { 14626 } 14627 } 14628 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14630 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14631 | Intent.FLAG_RECEIVER_FOREGROUND); 14632 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14633 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14634 Process.SYSTEM_UID, UserHandle.USER_ALL); 14635 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14636 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14637 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14638 broadcastIntentLocked(null, null, intent, 14639 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14640 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14641 } 14642 } 14643 } 14644 14645 boolean kept = true; 14646 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14647 // mainStack is null during startup. 14648 if (mainStack != null) { 14649 if (changes != 0 && starting == null) { 14650 // If the configuration changed, and the caller is not already 14651 // in the process of starting an activity, then find the top 14652 // activity to check if its configuration needs to change. 14653 starting = mainStack.topRunningActivityLocked(null); 14654 } 14655 14656 if (starting != null) { 14657 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14658 // And we need to make sure at this point that all other activities 14659 // are made visible with the correct configuration. 14660 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14661 } 14662 } 14663 14664 if (values != null && mWindowManager != null) { 14665 mWindowManager.setNewConfiguration(mConfiguration); 14666 } 14667 14668 return kept; 14669 } 14670 14671 /** 14672 * Decide based on the configuration whether we should shouw the ANR, 14673 * crash, etc dialogs. The idea is that if there is no affordnace to 14674 * press the on-screen buttons, we shouldn't show the dialog. 14675 * 14676 * A thought: SystemUI might also want to get told about this, the Power 14677 * dialog / global actions also might want different behaviors. 14678 */ 14679 private static final boolean shouldShowDialogs(Configuration config) { 14680 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14681 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14682 } 14683 14684 /** 14685 * Save the locale. You must be inside a synchronized (this) block. 14686 */ 14687 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14688 if(isDiff) { 14689 SystemProperties.set("user.language", l.getLanguage()); 14690 SystemProperties.set("user.region", l.getCountry()); 14691 } 14692 14693 if(isPersist) { 14694 SystemProperties.set("persist.sys.language", l.getLanguage()); 14695 SystemProperties.set("persist.sys.country", l.getCountry()); 14696 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14697 } 14698 } 14699 14700 @Override 14701 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14702 ActivityRecord srec = ActivityRecord.forToken(token); 14703 return srec != null && srec.task.affinity != null && 14704 srec.task.affinity.equals(destAffinity); 14705 } 14706 14707 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14708 Intent resultData) { 14709 14710 synchronized (this) { 14711 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14712 if (stack != null) { 14713 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14714 } 14715 return false; 14716 } 14717 } 14718 14719 public int getLaunchedFromUid(IBinder activityToken) { 14720 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14721 if (srec == null) { 14722 return -1; 14723 } 14724 return srec.launchedFromUid; 14725 } 14726 14727 public String getLaunchedFromPackage(IBinder activityToken) { 14728 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14729 if (srec == null) { 14730 return null; 14731 } 14732 return srec.launchedFromPackage; 14733 } 14734 14735 // ========================================================= 14736 // LIFETIME MANAGEMENT 14737 // ========================================================= 14738 14739 // Returns which broadcast queue the app is the current [or imminent] receiver 14740 // on, or 'null' if the app is not an active broadcast recipient. 14741 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14742 BroadcastRecord r = app.curReceiver; 14743 if (r != null) { 14744 return r.queue; 14745 } 14746 14747 // It's not the current receiver, but it might be starting up to become one 14748 synchronized (this) { 14749 for (BroadcastQueue queue : mBroadcastQueues) { 14750 r = queue.mPendingBroadcast; 14751 if (r != null && r.curApp == app) { 14752 // found it; report which queue it's in 14753 return queue; 14754 } 14755 } 14756 } 14757 14758 return null; 14759 } 14760 14761 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14762 boolean doingAll, long now) { 14763 if (mAdjSeq == app.adjSeq) { 14764 // This adjustment has already been computed. 14765 return app.curRawAdj; 14766 } 14767 14768 if (app.thread == null) { 14769 app.adjSeq = mAdjSeq; 14770 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14771 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14772 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14773 } 14774 14775 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14776 app.adjSource = null; 14777 app.adjTarget = null; 14778 app.empty = false; 14779 app.cached = false; 14780 14781 final int activitiesSize = app.activities.size(); 14782 14783 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14784 // The max adjustment doesn't allow this app to be anything 14785 // below foreground, so it is not worth doing work for it. 14786 app.adjType = "fixed"; 14787 app.adjSeq = mAdjSeq; 14788 app.curRawAdj = app.maxAdj; 14789 app.foregroundActivities = false; 14790 app.keeping = true; 14791 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14792 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14793 // System processes can do UI, and when they do we want to have 14794 // them trim their memory after the user leaves the UI. To 14795 // facilitate this, here we need to determine whether or not it 14796 // is currently showing UI. 14797 app.systemNoUi = true; 14798 if (app == TOP_APP) { 14799 app.systemNoUi = false; 14800 } else if (activitiesSize > 0) { 14801 for (int j = 0; j < activitiesSize; j++) { 14802 final ActivityRecord r = app.activities.get(j); 14803 if (r.visible) { 14804 app.systemNoUi = false; 14805 } 14806 } 14807 } 14808 if (!app.systemNoUi) { 14809 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14810 } 14811 return (app.curAdj=app.maxAdj); 14812 } 14813 14814 app.keeping = false; 14815 app.systemNoUi = false; 14816 14817 // Determine the importance of the process, starting with most 14818 // important to least, and assign an appropriate OOM adjustment. 14819 int adj; 14820 int schedGroup; 14821 int procState; 14822 boolean foregroundActivities = false; 14823 boolean interesting = false; 14824 BroadcastQueue queue; 14825 if (app == TOP_APP) { 14826 // The last app on the list is the foreground app. 14827 adj = ProcessList.FOREGROUND_APP_ADJ; 14828 schedGroup = Process.THREAD_GROUP_DEFAULT; 14829 app.adjType = "top-activity"; 14830 foregroundActivities = true; 14831 interesting = true; 14832 procState = ActivityManager.PROCESS_STATE_TOP; 14833 } else if (app.instrumentationClass != null) { 14834 // Don't want to kill running instrumentation. 14835 adj = ProcessList.FOREGROUND_APP_ADJ; 14836 schedGroup = Process.THREAD_GROUP_DEFAULT; 14837 app.adjType = "instrumentation"; 14838 interesting = true; 14839 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14840 } else if ((queue = isReceivingBroadcast(app)) != null) { 14841 // An app that is currently receiving a broadcast also 14842 // counts as being in the foreground for OOM killer purposes. 14843 // It's placed in a sched group based on the nature of the 14844 // broadcast as reflected by which queue it's active in. 14845 adj = ProcessList.FOREGROUND_APP_ADJ; 14846 schedGroup = (queue == mFgBroadcastQueue) 14847 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14848 app.adjType = "broadcast"; 14849 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14850 } else if (app.executingServices.size() > 0) { 14851 // An app that is currently executing a service callback also 14852 // counts as being in the foreground. 14853 adj = ProcessList.FOREGROUND_APP_ADJ; 14854 schedGroup = app.execServicesFg ? 14855 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14856 app.adjType = "exec-service"; 14857 procState = ActivityManager.PROCESS_STATE_SERVICE; 14858 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14859 } else { 14860 // As far as we know the process is empty. We may change our mind later. 14861 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14862 // At this point we don't actually know the adjustment. Use the cached adj 14863 // value that the caller wants us to. 14864 adj = cachedAdj; 14865 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14866 app.cached = true; 14867 app.empty = true; 14868 app.adjType = "cch-empty"; 14869 } 14870 14871 // Examine all activities if not already foreground. 14872 if (!foregroundActivities && activitiesSize > 0) { 14873 for (int j = 0; j < activitiesSize; j++) { 14874 final ActivityRecord r = app.activities.get(j); 14875 if (r.app != app) { 14876 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14877 + app + "?!?"); 14878 continue; 14879 } 14880 if (r.visible) { 14881 // App has a visible activity; only upgrade adjustment. 14882 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14883 adj = ProcessList.VISIBLE_APP_ADJ; 14884 app.adjType = "visible"; 14885 } 14886 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14887 procState = ActivityManager.PROCESS_STATE_TOP; 14888 } 14889 schedGroup = Process.THREAD_GROUP_DEFAULT; 14890 app.cached = false; 14891 app.empty = false; 14892 foregroundActivities = true; 14893 break; 14894 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14895 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14896 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14897 app.adjType = "pausing"; 14898 } 14899 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14900 procState = ActivityManager.PROCESS_STATE_TOP; 14901 } 14902 schedGroup = Process.THREAD_GROUP_DEFAULT; 14903 app.cached = false; 14904 app.empty = false; 14905 foregroundActivities = true; 14906 } else if (r.state == ActivityState.STOPPING) { 14907 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14908 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14909 app.adjType = "stopping"; 14910 } 14911 // For the process state, we will at this point consider the 14912 // process to be cached. It will be cached either as an activity 14913 // or empty depending on whether the activity is finishing. We do 14914 // this so that we can treat the process as cached for purposes of 14915 // memory trimming (determing current memory level, trim command to 14916 // send to process) since there can be an arbitrary number of stopping 14917 // processes and they should soon all go into the cached state. 14918 if (!r.finishing) { 14919 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14920 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14921 } 14922 } 14923 app.cached = false; 14924 app.empty = false; 14925 foregroundActivities = true; 14926 } else { 14927 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14928 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14929 app.adjType = "cch-act"; 14930 } 14931 } 14932 } 14933 } 14934 14935 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14936 if (app.foregroundServices) { 14937 // The user is aware of this app, so make it visible. 14938 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14939 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14940 app.cached = false; 14941 app.adjType = "fg-service"; 14942 schedGroup = Process.THREAD_GROUP_DEFAULT; 14943 } else if (app.forcingToForeground != null) { 14944 // The user is aware of this app, so make it visible. 14945 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14946 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14947 app.cached = false; 14948 app.adjType = "force-fg"; 14949 app.adjSource = app.forcingToForeground; 14950 schedGroup = Process.THREAD_GROUP_DEFAULT; 14951 } 14952 } 14953 14954 if (app.foregroundServices) { 14955 interesting = true; 14956 } 14957 14958 if (app == mHeavyWeightProcess) { 14959 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14960 // We don't want to kill the current heavy-weight process. 14961 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14962 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14963 app.cached = false; 14964 app.adjType = "heavy"; 14965 } 14966 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14967 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14968 } 14969 } 14970 14971 if (app == mHomeProcess) { 14972 if (adj > ProcessList.HOME_APP_ADJ) { 14973 // This process is hosting what we currently consider to be the 14974 // home app, so we don't want to let it go into the background. 14975 adj = ProcessList.HOME_APP_ADJ; 14976 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14977 app.cached = false; 14978 app.adjType = "home"; 14979 } 14980 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14981 procState = ActivityManager.PROCESS_STATE_HOME; 14982 } 14983 } 14984 14985 if (app == mPreviousProcess && app.activities.size() > 0) { 14986 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14987 // This was the previous process that showed UI to the user. 14988 // We want to try to keep it around more aggressively, to give 14989 // a good experience around switching between two apps. 14990 adj = ProcessList.PREVIOUS_APP_ADJ; 14991 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14992 app.cached = false; 14993 app.adjType = "previous"; 14994 } 14995 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14996 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14997 } 14998 } 14999 15000 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15001 + " reason=" + app.adjType); 15002 15003 // By default, we use the computed adjustment. It may be changed if 15004 // there are applications dependent on our services or providers, but 15005 // this gives us a baseline and makes sure we don't get into an 15006 // infinite recursion. 15007 app.adjSeq = mAdjSeq; 15008 app.curRawAdj = adj; 15009 app.hasStartedServices = false; 15010 15011 if (mBackupTarget != null && app == mBackupTarget.app) { 15012 // If possible we want to avoid killing apps while they're being backed up 15013 if (adj > ProcessList.BACKUP_APP_ADJ) { 15014 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15015 adj = ProcessList.BACKUP_APP_ADJ; 15016 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15017 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15018 } 15019 app.adjType = "backup"; 15020 app.cached = false; 15021 } 15022 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15023 procState = ActivityManager.PROCESS_STATE_BACKUP; 15024 } 15025 } 15026 15027 boolean mayBeTop = false; 15028 15029 for (int is = app.services.size()-1; 15030 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15031 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15032 || procState > ActivityManager.PROCESS_STATE_TOP); 15033 is--) { 15034 ServiceRecord s = app.services.valueAt(is); 15035 if (s.startRequested) { 15036 app.hasStartedServices = true; 15037 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15038 procState = ActivityManager.PROCESS_STATE_SERVICE; 15039 } 15040 if (app.hasShownUi && app != mHomeProcess) { 15041 // If this process has shown some UI, let it immediately 15042 // go to the LRU list because it may be pretty heavy with 15043 // UI stuff. We'll tag it with a label just to help 15044 // debug and understand what is going on. 15045 if (adj > ProcessList.SERVICE_ADJ) { 15046 app.adjType = "cch-started-ui-services"; 15047 } 15048 } else { 15049 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15050 // This service has seen some activity within 15051 // recent memory, so we will keep its process ahead 15052 // of the background processes. 15053 if (adj > ProcessList.SERVICE_ADJ) { 15054 adj = ProcessList.SERVICE_ADJ; 15055 app.adjType = "started-services"; 15056 app.cached = false; 15057 } 15058 } 15059 // If we have let the service slide into the background 15060 // state, still have some text describing what it is doing 15061 // even though the service no longer has an impact. 15062 if (adj > ProcessList.SERVICE_ADJ) { 15063 app.adjType = "cch-started-services"; 15064 } 15065 } 15066 // Don't kill this process because it is doing work; it 15067 // has said it is doing work. 15068 app.keeping = true; 15069 } 15070 for (int conni = s.connections.size()-1; 15071 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15072 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15073 || procState > ActivityManager.PROCESS_STATE_TOP); 15074 conni--) { 15075 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15076 for (int i = 0; 15077 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15078 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15079 || procState > ActivityManager.PROCESS_STATE_TOP); 15080 i++) { 15081 // XXX should compute this based on the max of 15082 // all connected clients. 15083 ConnectionRecord cr = clist.get(i); 15084 if (cr.binding.client == app) { 15085 // Binding to ourself is not interesting. 15086 continue; 15087 } 15088 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15089 ProcessRecord client = cr.binding.client; 15090 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15091 TOP_APP, doingAll, now); 15092 int clientProcState = client.curProcState; 15093 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15094 // If the other app is cached for any reason, for purposes here 15095 // we are going to consider it empty. The specific cached state 15096 // doesn't propagate except under certain conditions. 15097 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15098 } 15099 String adjType = null; 15100 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15101 // Not doing bind OOM management, so treat 15102 // this guy more like a started service. 15103 if (app.hasShownUi && app != mHomeProcess) { 15104 // If this process has shown some UI, let it immediately 15105 // go to the LRU list because it may be pretty heavy with 15106 // UI stuff. We'll tag it with a label just to help 15107 // debug and understand what is going on. 15108 if (adj > clientAdj) { 15109 adjType = "cch-bound-ui-services"; 15110 } 15111 app.cached = false; 15112 clientAdj = adj; 15113 clientProcState = procState; 15114 } else { 15115 if (now >= (s.lastActivity 15116 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15117 // This service has not seen activity within 15118 // recent memory, so allow it to drop to the 15119 // LRU list if there is no other reason to keep 15120 // it around. We'll also tag it with a label just 15121 // to help debug and undertand what is going on. 15122 if (adj > clientAdj) { 15123 adjType = "cch-bound-services"; 15124 } 15125 clientAdj = adj; 15126 } 15127 } 15128 } 15129 if (adj > clientAdj) { 15130 // If this process has recently shown UI, and 15131 // the process that is binding to it is less 15132 // important than being visible, then we don't 15133 // care about the binding as much as we care 15134 // about letting this process get into the LRU 15135 // list to be killed and restarted if needed for 15136 // memory. 15137 if (app.hasShownUi && app != mHomeProcess 15138 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15139 adjType = "cch-bound-ui-services"; 15140 } else { 15141 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15142 |Context.BIND_IMPORTANT)) != 0) { 15143 adj = clientAdj; 15144 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15145 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15146 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15147 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15148 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15149 adj = clientAdj; 15150 } else { 15151 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15152 adj = ProcessList.VISIBLE_APP_ADJ; 15153 } 15154 } 15155 if (!client.cached) { 15156 app.cached = false; 15157 } 15158 if (client.keeping) { 15159 app.keeping = true; 15160 } 15161 adjType = "service"; 15162 } 15163 } 15164 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15165 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15166 schedGroup = Process.THREAD_GROUP_DEFAULT; 15167 } 15168 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15169 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15170 // Special handling of clients who are in the top state. 15171 // We *may* want to consider this process to be in the 15172 // top state as well, but only if there is not another 15173 // reason for it to be running. Being on the top is a 15174 // special state, meaning you are specifically running 15175 // for the current top app. If the process is already 15176 // running in the background for some other reason, it 15177 // is more important to continue considering it to be 15178 // in the background state. 15179 mayBeTop = true; 15180 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15181 } else { 15182 // Special handling for above-top states (persistent 15183 // processes). These should not bring the current process 15184 // into the top state, since they are not on top. Instead 15185 // give them the best state after that. 15186 clientProcState = 15187 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15188 } 15189 } 15190 } else { 15191 if (clientProcState < 15192 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15193 clientProcState = 15194 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15195 } 15196 } 15197 if (procState > clientProcState) { 15198 procState = clientProcState; 15199 } 15200 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15201 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15202 app.pendingUiClean = true; 15203 } 15204 if (adjType != null) { 15205 app.adjType = adjType; 15206 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15207 .REASON_SERVICE_IN_USE; 15208 app.adjSource = cr.binding.client; 15209 app.adjSourceOom = clientAdj; 15210 app.adjTarget = s.name; 15211 } 15212 } 15213 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15214 app.treatLikeActivity = true; 15215 } 15216 final ActivityRecord a = cr.activity; 15217 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15218 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15219 (a.visible || a.state == ActivityState.RESUMED 15220 || a.state == ActivityState.PAUSING)) { 15221 adj = ProcessList.FOREGROUND_APP_ADJ; 15222 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15223 schedGroup = Process.THREAD_GROUP_DEFAULT; 15224 } 15225 app.cached = false; 15226 app.adjType = "service"; 15227 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15228 .REASON_SERVICE_IN_USE; 15229 app.adjSource = a; 15230 app.adjSourceOom = adj; 15231 app.adjTarget = s.name; 15232 } 15233 } 15234 } 15235 } 15236 } 15237 15238 for (int provi = app.pubProviders.size()-1; 15239 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15240 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15241 || procState > ActivityManager.PROCESS_STATE_TOP); 15242 provi--) { 15243 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15244 for (int i = cpr.connections.size()-1; 15245 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15246 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15247 || procState > ActivityManager.PROCESS_STATE_TOP); 15248 i--) { 15249 ContentProviderConnection conn = cpr.connections.get(i); 15250 ProcessRecord client = conn.client; 15251 if (client == app) { 15252 // Being our own client is not interesting. 15253 continue; 15254 } 15255 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15256 int clientProcState = client.curProcState; 15257 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15258 // If the other app is cached for any reason, for purposes here 15259 // we are going to consider it empty. 15260 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15261 } 15262 if (adj > clientAdj) { 15263 if (app.hasShownUi && app != mHomeProcess 15264 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15265 app.adjType = "cch-ui-provider"; 15266 } else { 15267 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15268 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15269 app.adjType = "provider"; 15270 } 15271 app.cached &= client.cached; 15272 app.keeping |= client.keeping; 15273 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15274 .REASON_PROVIDER_IN_USE; 15275 app.adjSource = client; 15276 app.adjSourceOom = clientAdj; 15277 app.adjTarget = cpr.name; 15278 } 15279 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15280 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15281 // Special handling of clients who are in the top state. 15282 // We *may* want to consider this process to be in the 15283 // top state as well, but only if there is not another 15284 // reason for it to be running. Being on the top is a 15285 // special state, meaning you are specifically running 15286 // for the current top app. If the process is already 15287 // running in the background for some other reason, it 15288 // is more important to continue considering it to be 15289 // in the background state. 15290 mayBeTop = true; 15291 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15292 } else { 15293 // Special handling for above-top states (persistent 15294 // processes). These should not bring the current process 15295 // into the top state, since they are not on top. Instead 15296 // give them the best state after that. 15297 clientProcState = 15298 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15299 } 15300 } 15301 if (procState > clientProcState) { 15302 procState = clientProcState; 15303 } 15304 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15305 schedGroup = Process.THREAD_GROUP_DEFAULT; 15306 } 15307 } 15308 // If the provider has external (non-framework) process 15309 // dependencies, ensure that its adjustment is at least 15310 // FOREGROUND_APP_ADJ. 15311 if (cpr.hasExternalProcessHandles()) { 15312 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15313 adj = ProcessList.FOREGROUND_APP_ADJ; 15314 schedGroup = Process.THREAD_GROUP_DEFAULT; 15315 app.cached = false; 15316 app.keeping = true; 15317 app.adjType = "provider"; 15318 app.adjTarget = cpr.name; 15319 } 15320 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15321 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15322 } 15323 } 15324 } 15325 15326 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15327 // A client of one of our services or providers is in the top state. We 15328 // *may* want to be in the top state, but not if we are already running in 15329 // the background for some other reason. For the decision here, we are going 15330 // to pick out a few specific states that we want to remain in when a client 15331 // is top (states that tend to be longer-term) and otherwise allow it to go 15332 // to the top state. 15333 switch (procState) { 15334 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15335 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15336 case ActivityManager.PROCESS_STATE_SERVICE: 15337 // These all are longer-term states, so pull them up to the top 15338 // of the background states, but not all the way to the top state. 15339 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15340 break; 15341 default: 15342 // Otherwise, top is a better choice, so take it. 15343 procState = ActivityManager.PROCESS_STATE_TOP; 15344 break; 15345 } 15346 } 15347 15348 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15349 if (app.hasClientActivities) { 15350 // This is a cached process, but with client activities. Mark it so. 15351 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15352 app.adjType = "cch-client-act"; 15353 } else if (app.treatLikeActivity) { 15354 // This is a cached process, but somebody wants us to treat it like it has 15355 // an activity, okay! 15356 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15357 app.adjType = "cch-as-act"; 15358 } 15359 } 15360 15361 if (adj == ProcessList.SERVICE_ADJ) { 15362 if (doingAll) { 15363 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15364 mNewNumServiceProcs++; 15365 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15366 if (!app.serviceb) { 15367 // This service isn't far enough down on the LRU list to 15368 // normally be a B service, but if we are low on RAM and it 15369 // is large we want to force it down since we would prefer to 15370 // keep launcher over it. 15371 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15372 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15373 app.serviceHighRam = true; 15374 app.serviceb = true; 15375 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15376 } else { 15377 mNewNumAServiceProcs++; 15378 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15379 } 15380 } else { 15381 app.serviceHighRam = false; 15382 } 15383 } 15384 if (app.serviceb) { 15385 adj = ProcessList.SERVICE_B_ADJ; 15386 } 15387 } 15388 15389 app.curRawAdj = adj; 15390 15391 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15392 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15393 if (adj > app.maxAdj) { 15394 adj = app.maxAdj; 15395 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15396 schedGroup = Process.THREAD_GROUP_DEFAULT; 15397 } 15398 } 15399 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15400 app.keeping = true; 15401 } 15402 15403 // Do final modification to adj. Everything we do between here and applying 15404 // the final setAdj must be done in this function, because we will also use 15405 // it when computing the final cached adj later. Note that we don't need to 15406 // worry about this for max adj above, since max adj will always be used to 15407 // keep it out of the cached vaues. 15408 app.curAdj = app.modifyRawOomAdj(adj); 15409 app.curSchedGroup = schedGroup; 15410 app.curProcState = procState; 15411 app.foregroundActivities = foregroundActivities; 15412 15413 return app.curRawAdj; 15414 } 15415 15416 /** 15417 * Schedule PSS collection of a process. 15418 */ 15419 void requestPssLocked(ProcessRecord proc, int procState) { 15420 if (mPendingPssProcesses.contains(proc)) { 15421 return; 15422 } 15423 if (mPendingPssProcesses.size() == 0) { 15424 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15425 } 15426 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15427 proc.pssProcState = procState; 15428 mPendingPssProcesses.add(proc); 15429 } 15430 15431 /** 15432 * Schedule PSS collection of all processes. 15433 */ 15434 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15435 if (!always) { 15436 if (now < (mLastFullPssTime + 15437 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15438 return; 15439 } 15440 } 15441 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15442 mLastFullPssTime = now; 15443 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15444 mPendingPssProcesses.clear(); 15445 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15446 ProcessRecord app = mLruProcesses.get(i); 15447 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15448 app.pssProcState = app.setProcState; 15449 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15450 isSleeping(), now); 15451 mPendingPssProcesses.add(app); 15452 } 15453 } 15454 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15455 } 15456 15457 /** 15458 * Ask a given process to GC right now. 15459 */ 15460 final void performAppGcLocked(ProcessRecord app) { 15461 try { 15462 app.lastRequestedGc = SystemClock.uptimeMillis(); 15463 if (app.thread != null) { 15464 if (app.reportLowMemory) { 15465 app.reportLowMemory = false; 15466 app.thread.scheduleLowMemory(); 15467 } else { 15468 app.thread.processInBackground(); 15469 } 15470 } 15471 } catch (Exception e) { 15472 // whatever. 15473 } 15474 } 15475 15476 /** 15477 * Returns true if things are idle enough to perform GCs. 15478 */ 15479 private final boolean canGcNowLocked() { 15480 boolean processingBroadcasts = false; 15481 for (BroadcastQueue q : mBroadcastQueues) { 15482 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15483 processingBroadcasts = true; 15484 } 15485 } 15486 return !processingBroadcasts 15487 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15488 } 15489 15490 /** 15491 * Perform GCs on all processes that are waiting for it, but only 15492 * if things are idle. 15493 */ 15494 final void performAppGcsLocked() { 15495 final int N = mProcessesToGc.size(); 15496 if (N <= 0) { 15497 return; 15498 } 15499 if (canGcNowLocked()) { 15500 while (mProcessesToGc.size() > 0) { 15501 ProcessRecord proc = mProcessesToGc.remove(0); 15502 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15503 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15504 <= SystemClock.uptimeMillis()) { 15505 // To avoid spamming the system, we will GC processes one 15506 // at a time, waiting a few seconds between each. 15507 performAppGcLocked(proc); 15508 scheduleAppGcsLocked(); 15509 return; 15510 } else { 15511 // It hasn't been long enough since we last GCed this 15512 // process... put it in the list to wait for its time. 15513 addProcessToGcListLocked(proc); 15514 break; 15515 } 15516 } 15517 } 15518 15519 scheduleAppGcsLocked(); 15520 } 15521 } 15522 15523 /** 15524 * If all looks good, perform GCs on all processes waiting for them. 15525 */ 15526 final void performAppGcsIfAppropriateLocked() { 15527 if (canGcNowLocked()) { 15528 performAppGcsLocked(); 15529 return; 15530 } 15531 // Still not idle, wait some more. 15532 scheduleAppGcsLocked(); 15533 } 15534 15535 /** 15536 * Schedule the execution of all pending app GCs. 15537 */ 15538 final void scheduleAppGcsLocked() { 15539 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15540 15541 if (mProcessesToGc.size() > 0) { 15542 // Schedule a GC for the time to the next process. 15543 ProcessRecord proc = mProcessesToGc.get(0); 15544 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15545 15546 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15547 long now = SystemClock.uptimeMillis(); 15548 if (when < (now+GC_TIMEOUT)) { 15549 when = now + GC_TIMEOUT; 15550 } 15551 mHandler.sendMessageAtTime(msg, when); 15552 } 15553 } 15554 15555 /** 15556 * Add a process to the array of processes waiting to be GCed. Keeps the 15557 * list in sorted order by the last GC time. The process can't already be 15558 * on the list. 15559 */ 15560 final void addProcessToGcListLocked(ProcessRecord proc) { 15561 boolean added = false; 15562 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15563 if (mProcessesToGc.get(i).lastRequestedGc < 15564 proc.lastRequestedGc) { 15565 added = true; 15566 mProcessesToGc.add(i+1, proc); 15567 break; 15568 } 15569 } 15570 if (!added) { 15571 mProcessesToGc.add(0, proc); 15572 } 15573 } 15574 15575 /** 15576 * Set up to ask a process to GC itself. This will either do it 15577 * immediately, or put it on the list of processes to gc the next 15578 * time things are idle. 15579 */ 15580 final void scheduleAppGcLocked(ProcessRecord app) { 15581 long now = SystemClock.uptimeMillis(); 15582 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15583 return; 15584 } 15585 if (!mProcessesToGc.contains(app)) { 15586 addProcessToGcListLocked(app); 15587 scheduleAppGcsLocked(); 15588 } 15589 } 15590 15591 final void checkExcessivePowerUsageLocked(boolean doKills) { 15592 updateCpuStatsNow(); 15593 15594 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15595 boolean doWakeKills = doKills; 15596 boolean doCpuKills = doKills; 15597 if (mLastPowerCheckRealtime == 0) { 15598 doWakeKills = false; 15599 } 15600 if (mLastPowerCheckUptime == 0) { 15601 doCpuKills = false; 15602 } 15603 if (stats.isScreenOn()) { 15604 doWakeKills = false; 15605 } 15606 final long curRealtime = SystemClock.elapsedRealtime(); 15607 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15608 final long curUptime = SystemClock.uptimeMillis(); 15609 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15610 mLastPowerCheckRealtime = curRealtime; 15611 mLastPowerCheckUptime = curUptime; 15612 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15613 doWakeKills = false; 15614 } 15615 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15616 doCpuKills = false; 15617 } 15618 int i = mLruProcesses.size(); 15619 while (i > 0) { 15620 i--; 15621 ProcessRecord app = mLruProcesses.get(i); 15622 if (!app.keeping) { 15623 long wtime; 15624 synchronized (stats) { 15625 wtime = stats.getProcessWakeTime(app.info.uid, 15626 app.pid, curRealtime); 15627 } 15628 long wtimeUsed = wtime - app.lastWakeTime; 15629 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15630 if (DEBUG_POWER) { 15631 StringBuilder sb = new StringBuilder(128); 15632 sb.append("Wake for "); 15633 app.toShortString(sb); 15634 sb.append(": over "); 15635 TimeUtils.formatDuration(realtimeSince, sb); 15636 sb.append(" used "); 15637 TimeUtils.formatDuration(wtimeUsed, sb); 15638 sb.append(" ("); 15639 sb.append((wtimeUsed*100)/realtimeSince); 15640 sb.append("%)"); 15641 Slog.i(TAG, sb.toString()); 15642 sb.setLength(0); 15643 sb.append("CPU for "); 15644 app.toShortString(sb); 15645 sb.append(": over "); 15646 TimeUtils.formatDuration(uptimeSince, sb); 15647 sb.append(" used "); 15648 TimeUtils.formatDuration(cputimeUsed, sb); 15649 sb.append(" ("); 15650 sb.append((cputimeUsed*100)/uptimeSince); 15651 sb.append("%)"); 15652 Slog.i(TAG, sb.toString()); 15653 } 15654 // If a process has held a wake lock for more 15655 // than 50% of the time during this period, 15656 // that sounds bad. Kill! 15657 if (doWakeKills && realtimeSince > 0 15658 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15659 synchronized (stats) { 15660 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15661 realtimeSince, wtimeUsed); 15662 } 15663 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15664 + " during " + realtimeSince); 15665 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15666 } else if (doCpuKills && uptimeSince > 0 15667 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15668 synchronized (stats) { 15669 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15670 uptimeSince, cputimeUsed); 15671 } 15672 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15673 + " during " + uptimeSince); 15674 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15675 } else { 15676 app.lastWakeTime = wtime; 15677 app.lastCpuTime = app.curCpuTime; 15678 } 15679 } 15680 } 15681 } 15682 15683 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15684 ProcessRecord TOP_APP, boolean doingAll, long now) { 15685 boolean success = true; 15686 15687 if (app.curRawAdj != app.setRawAdj) { 15688 if (wasKeeping && !app.keeping) { 15689 // This app is no longer something we want to keep. Note 15690 // its current wake lock time to later know to kill it if 15691 // it is not behaving well. 15692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15693 synchronized (stats) { 15694 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15695 app.pid, SystemClock.elapsedRealtime()); 15696 } 15697 app.lastCpuTime = app.curCpuTime; 15698 } 15699 15700 app.setRawAdj = app.curRawAdj; 15701 } 15702 15703 int changes = 0; 15704 15705 if (app.curAdj != app.setAdj) { 15706 ProcessList.setOomAdj(app.pid, app.curAdj); 15707 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15708 TAG, "Set " + app.pid + " " + app.processName + 15709 " adj " + app.curAdj + ": " + app.adjType); 15710 app.setAdj = app.curAdj; 15711 } 15712 15713 if (app.setSchedGroup != app.curSchedGroup) { 15714 app.setSchedGroup = app.curSchedGroup; 15715 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15716 "Setting process group of " + app.processName 15717 + " to " + app.curSchedGroup); 15718 if (app.waitingToKill != null && 15719 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15720 killUnneededProcessLocked(app, app.waitingToKill); 15721 success = false; 15722 } else { 15723 if (true) { 15724 long oldId = Binder.clearCallingIdentity(); 15725 try { 15726 Process.setProcessGroup(app.pid, app.curSchedGroup); 15727 } catch (Exception e) { 15728 Slog.w(TAG, "Failed setting process group of " + app.pid 15729 + " to " + app.curSchedGroup); 15730 e.printStackTrace(); 15731 } finally { 15732 Binder.restoreCallingIdentity(oldId); 15733 } 15734 } else { 15735 if (app.thread != null) { 15736 try { 15737 app.thread.setSchedulingGroup(app.curSchedGroup); 15738 } catch (RemoteException e) { 15739 } 15740 } 15741 } 15742 Process.setSwappiness(app.pid, 15743 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15744 } 15745 } 15746 if (app.repForegroundActivities != app.foregroundActivities) { 15747 app.repForegroundActivities = app.foregroundActivities; 15748 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15749 } 15750 if (app.repProcState != app.curProcState) { 15751 app.repProcState = app.curProcState; 15752 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15753 if (app.thread != null) { 15754 try { 15755 if (false) { 15756 //RuntimeException h = new RuntimeException("here"); 15757 Slog.i(TAG, "Sending new process state " + app.repProcState 15758 + " to " + app /*, h*/); 15759 } 15760 app.thread.setProcessState(app.repProcState); 15761 } catch (RemoteException e) { 15762 } 15763 } 15764 } 15765 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15766 app.setProcState)) { 15767 app.lastStateTime = now; 15768 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15769 isSleeping(), now); 15770 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15771 + ProcessList.makeProcStateString(app.setProcState) + " to " 15772 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15773 + (app.nextPssTime-now) + ": " + app); 15774 } else { 15775 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15776 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15777 requestPssLocked(app, app.setProcState); 15778 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15779 isSleeping(), now); 15780 } else if (false && DEBUG_PSS) { 15781 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15782 } 15783 } 15784 if (app.setProcState != app.curProcState) { 15785 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15786 "Proc state change of " + app.processName 15787 + " to " + app.curProcState); 15788 app.setProcState = app.curProcState; 15789 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15790 app.notCachedSinceIdle = false; 15791 } 15792 if (!doingAll) { 15793 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15794 } else { 15795 app.procStateChanged = true; 15796 } 15797 } 15798 15799 if (changes != 0) { 15800 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15801 int i = mPendingProcessChanges.size()-1; 15802 ProcessChangeItem item = null; 15803 while (i >= 0) { 15804 item = mPendingProcessChanges.get(i); 15805 if (item.pid == app.pid) { 15806 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15807 break; 15808 } 15809 i--; 15810 } 15811 if (i < 0) { 15812 // No existing item in pending changes; need a new one. 15813 final int NA = mAvailProcessChanges.size(); 15814 if (NA > 0) { 15815 item = mAvailProcessChanges.remove(NA-1); 15816 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15817 } else { 15818 item = new ProcessChangeItem(); 15819 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15820 } 15821 item.changes = 0; 15822 item.pid = app.pid; 15823 item.uid = app.info.uid; 15824 if (mPendingProcessChanges.size() == 0) { 15825 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15826 "*** Enqueueing dispatch processes changed!"); 15827 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15828 } 15829 mPendingProcessChanges.add(item); 15830 } 15831 item.changes |= changes; 15832 item.processState = app.repProcState; 15833 item.foregroundActivities = app.repForegroundActivities; 15834 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15835 + Integer.toHexString(System.identityHashCode(item)) 15836 + " " + app.toShortString() + ": changes=" + item.changes 15837 + " procState=" + item.processState 15838 + " foreground=" + item.foregroundActivities 15839 + " type=" + app.adjType + " source=" + app.adjSource 15840 + " target=" + app.adjTarget); 15841 } 15842 15843 return success; 15844 } 15845 15846 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15847 if (proc.thread != null && proc.baseProcessTracker != null) { 15848 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15849 } 15850 } 15851 15852 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15853 ProcessRecord TOP_APP, boolean doingAll, long now) { 15854 if (app.thread == null) { 15855 return false; 15856 } 15857 15858 final boolean wasKeeping = app.keeping; 15859 15860 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15861 15862 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15863 } 15864 15865 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15866 boolean oomAdj) { 15867 if (isForeground != proc.foregroundServices) { 15868 proc.foregroundServices = isForeground; 15869 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15870 proc.info.uid); 15871 if (isForeground) { 15872 if (curProcs == null) { 15873 curProcs = new ArrayList<ProcessRecord>(); 15874 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15875 } 15876 if (!curProcs.contains(proc)) { 15877 curProcs.add(proc); 15878 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15879 proc.info.packageName, proc.info.uid); 15880 } 15881 } else { 15882 if (curProcs != null) { 15883 if (curProcs.remove(proc)) { 15884 mBatteryStatsService.noteEvent( 15885 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15886 proc.info.packageName, proc.info.uid); 15887 if (curProcs.size() <= 0) { 15888 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15889 } 15890 } 15891 } 15892 } 15893 if (oomAdj) { 15894 updateOomAdjLocked(); 15895 } 15896 } 15897 } 15898 15899 private final ActivityRecord resumedAppLocked() { 15900 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15901 String pkg; 15902 int uid; 15903 if (act != null && !act.sleeping) { 15904 pkg = act.packageName; 15905 uid = act.info.applicationInfo.uid; 15906 } else { 15907 pkg = null; 15908 uid = -1; 15909 } 15910 // Has the UID or resumed package name changed? 15911 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15912 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15913 if (mCurResumedPackage != null) { 15914 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15915 mCurResumedPackage, mCurResumedUid); 15916 } 15917 mCurResumedPackage = pkg; 15918 mCurResumedUid = uid; 15919 if (mCurResumedPackage != null) { 15920 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15921 mCurResumedPackage, mCurResumedUid); 15922 } 15923 } 15924 return act; 15925 } 15926 15927 final boolean updateOomAdjLocked(ProcessRecord app) { 15928 final ActivityRecord TOP_ACT = resumedAppLocked(); 15929 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15930 final boolean wasCached = app.cached; 15931 15932 mAdjSeq++; 15933 15934 // This is the desired cached adjusment we want to tell it to use. 15935 // If our app is currently cached, we know it, and that is it. Otherwise, 15936 // we don't know it yet, and it needs to now be cached we will then 15937 // need to do a complete oom adj. 15938 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15939 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15940 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15941 SystemClock.uptimeMillis()); 15942 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15943 // Changed to/from cached state, so apps after it in the LRU 15944 // list may also be changed. 15945 updateOomAdjLocked(); 15946 } 15947 return success; 15948 } 15949 15950 final void updateOomAdjLocked() { 15951 final ActivityRecord TOP_ACT = resumedAppLocked(); 15952 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15953 final long now = SystemClock.uptimeMillis(); 15954 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15955 final int N = mLruProcesses.size(); 15956 15957 if (false) { 15958 RuntimeException e = new RuntimeException(); 15959 e.fillInStackTrace(); 15960 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15961 } 15962 15963 mAdjSeq++; 15964 mNewNumServiceProcs = 0; 15965 mNewNumAServiceProcs = 0; 15966 15967 final int emptyProcessLimit; 15968 final int cachedProcessLimit; 15969 if (mProcessLimit <= 0) { 15970 emptyProcessLimit = cachedProcessLimit = 0; 15971 } else if (mProcessLimit == 1) { 15972 emptyProcessLimit = 1; 15973 cachedProcessLimit = 0; 15974 } else { 15975 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15976 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15977 } 15978 15979 // Let's determine how many processes we have running vs. 15980 // how many slots we have for background processes; we may want 15981 // to put multiple processes in a slot of there are enough of 15982 // them. 15983 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15984 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15985 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15986 if (numEmptyProcs > cachedProcessLimit) { 15987 // If there are more empty processes than our limit on cached 15988 // processes, then use the cached process limit for the factor. 15989 // This ensures that the really old empty processes get pushed 15990 // down to the bottom, so if we are running low on memory we will 15991 // have a better chance at keeping around more cached processes 15992 // instead of a gazillion empty processes. 15993 numEmptyProcs = cachedProcessLimit; 15994 } 15995 int emptyFactor = numEmptyProcs/numSlots; 15996 if (emptyFactor < 1) emptyFactor = 1; 15997 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15998 if (cachedFactor < 1) cachedFactor = 1; 15999 int stepCached = 0; 16000 int stepEmpty = 0; 16001 int numCached = 0; 16002 int numEmpty = 0; 16003 int numTrimming = 0; 16004 16005 mNumNonCachedProcs = 0; 16006 mNumCachedHiddenProcs = 0; 16007 16008 // First update the OOM adjustment for each of the 16009 // application processes based on their current state. 16010 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16011 int nextCachedAdj = curCachedAdj+1; 16012 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16013 int nextEmptyAdj = curEmptyAdj+2; 16014 for (int i=N-1; i>=0; i--) { 16015 ProcessRecord app = mLruProcesses.get(i); 16016 if (!app.killedByAm && app.thread != null) { 16017 app.procStateChanged = false; 16018 final boolean wasKeeping = app.keeping; 16019 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16020 16021 // If we haven't yet assigned the final cached adj 16022 // to the process, do that now. 16023 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16024 switch (app.curProcState) { 16025 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16026 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16027 // This process is a cached process holding activities... 16028 // assign it the next cached value for that type, and then 16029 // step that cached level. 16030 app.curRawAdj = curCachedAdj; 16031 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16032 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16033 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16034 + ")"); 16035 if (curCachedAdj != nextCachedAdj) { 16036 stepCached++; 16037 if (stepCached >= cachedFactor) { 16038 stepCached = 0; 16039 curCachedAdj = nextCachedAdj; 16040 nextCachedAdj += 2; 16041 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16042 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16043 } 16044 } 16045 } 16046 break; 16047 default: 16048 // For everything else, assign next empty cached process 16049 // level and bump that up. Note that this means that 16050 // long-running services that have dropped down to the 16051 // cached level will be treated as empty (since their process 16052 // state is still as a service), which is what we want. 16053 app.curRawAdj = curEmptyAdj; 16054 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16055 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16056 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16057 + ")"); 16058 if (curEmptyAdj != nextEmptyAdj) { 16059 stepEmpty++; 16060 if (stepEmpty >= emptyFactor) { 16061 stepEmpty = 0; 16062 curEmptyAdj = nextEmptyAdj; 16063 nextEmptyAdj += 2; 16064 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16065 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16066 } 16067 } 16068 } 16069 break; 16070 } 16071 } 16072 16073 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16074 16075 // Count the number of process types. 16076 switch (app.curProcState) { 16077 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16078 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16079 mNumCachedHiddenProcs++; 16080 numCached++; 16081 if (numCached > cachedProcessLimit) { 16082 killUnneededProcessLocked(app, "cached #" + numCached); 16083 } 16084 break; 16085 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16086 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16087 && app.lastActivityTime < oldTime) { 16088 killUnneededProcessLocked(app, "empty for " 16089 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16090 / 1000) + "s"); 16091 } else { 16092 numEmpty++; 16093 if (numEmpty > emptyProcessLimit) { 16094 killUnneededProcessLocked(app, "empty #" + numEmpty); 16095 } 16096 } 16097 break; 16098 default: 16099 mNumNonCachedProcs++; 16100 break; 16101 } 16102 16103 if (app.isolated && app.services.size() <= 0) { 16104 // If this is an isolated process, and there are no 16105 // services running in it, then the process is no longer 16106 // needed. We agressively kill these because we can by 16107 // definition not re-use the same process again, and it is 16108 // good to avoid having whatever code was running in them 16109 // left sitting around after no longer needed. 16110 killUnneededProcessLocked(app, "isolated not needed"); 16111 } 16112 16113 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16114 && !app.killedByAm) { 16115 numTrimming++; 16116 } 16117 } 16118 } 16119 16120 mNumServiceProcs = mNewNumServiceProcs; 16121 16122 // Now determine the memory trimming level of background processes. 16123 // Unfortunately we need to start at the back of the list to do this 16124 // properly. We only do this if the number of background apps we 16125 // are managing to keep around is less than half the maximum we desire; 16126 // if we are keeping a good number around, we'll let them use whatever 16127 // memory they want. 16128 final int numCachedAndEmpty = numCached + numEmpty; 16129 int memFactor; 16130 if (numCached <= ProcessList.TRIM_CACHED_APPS 16131 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16132 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16133 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16134 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16135 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16136 } else { 16137 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16138 } 16139 } else { 16140 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16141 } 16142 // We always allow the memory level to go up (better). We only allow it to go 16143 // down if we are in a state where that is allowed, *and* the total number of processes 16144 // has gone down since last time. 16145 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16146 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16147 + " last=" + mLastNumProcesses); 16148 if (memFactor > mLastMemoryLevel) { 16149 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16150 memFactor = mLastMemoryLevel; 16151 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16152 } 16153 } 16154 mLastMemoryLevel = memFactor; 16155 mLastNumProcesses = mLruProcesses.size(); 16156 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16157 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16158 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16159 if (mLowRamStartTime == 0) { 16160 mLowRamStartTime = now; 16161 } 16162 int step = 0; 16163 int fgTrimLevel; 16164 switch (memFactor) { 16165 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16166 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16167 break; 16168 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16169 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16170 break; 16171 default: 16172 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16173 break; 16174 } 16175 int factor = numTrimming/3; 16176 int minFactor = 2; 16177 if (mHomeProcess != null) minFactor++; 16178 if (mPreviousProcess != null) minFactor++; 16179 if (factor < minFactor) factor = minFactor; 16180 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16181 for (int i=N-1; i>=0; i--) { 16182 ProcessRecord app = mLruProcesses.get(i); 16183 if (allChanged || app.procStateChanged) { 16184 setProcessTrackerState(app, trackerMemFactor, now); 16185 app.procStateChanged = false; 16186 } 16187 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16188 && !app.killedByAm) { 16189 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16190 try { 16191 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16192 "Trimming memory of " + app.processName 16193 + " to " + curLevel); 16194 app.thread.scheduleTrimMemory(curLevel); 16195 } catch (RemoteException e) { 16196 } 16197 if (false) { 16198 // For now we won't do this; our memory trimming seems 16199 // to be good enough at this point that destroying 16200 // activities causes more harm than good. 16201 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16202 && app != mHomeProcess && app != mPreviousProcess) { 16203 // Need to do this on its own message because the stack may not 16204 // be in a consistent state at this point. 16205 // For these apps we will also finish their activities 16206 // to help them free memory. 16207 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16208 } 16209 } 16210 } 16211 app.trimMemoryLevel = curLevel; 16212 step++; 16213 if (step >= factor) { 16214 step = 0; 16215 switch (curLevel) { 16216 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16217 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16218 break; 16219 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16220 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16221 break; 16222 } 16223 } 16224 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16225 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16226 && app.thread != null) { 16227 try { 16228 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16229 "Trimming memory of heavy-weight " + app.processName 16230 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16231 app.thread.scheduleTrimMemory( 16232 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16233 } catch (RemoteException e) { 16234 } 16235 } 16236 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16237 } else { 16238 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16239 || app.systemNoUi) && app.pendingUiClean) { 16240 // If this application is now in the background and it 16241 // had done UI, then give it the special trim level to 16242 // have it free UI resources. 16243 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16244 if (app.trimMemoryLevel < level && app.thread != null) { 16245 try { 16246 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16247 "Trimming memory of bg-ui " + app.processName 16248 + " to " + level); 16249 app.thread.scheduleTrimMemory(level); 16250 } catch (RemoteException e) { 16251 } 16252 } 16253 app.pendingUiClean = false; 16254 } 16255 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16256 try { 16257 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16258 "Trimming memory of fg " + app.processName 16259 + " to " + fgTrimLevel); 16260 app.thread.scheduleTrimMemory(fgTrimLevel); 16261 } catch (RemoteException e) { 16262 } 16263 } 16264 app.trimMemoryLevel = fgTrimLevel; 16265 } 16266 } 16267 } else { 16268 if (mLowRamStartTime != 0) { 16269 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16270 mLowRamStartTime = 0; 16271 } 16272 for (int i=N-1; i>=0; i--) { 16273 ProcessRecord app = mLruProcesses.get(i); 16274 if (allChanged || app.procStateChanged) { 16275 setProcessTrackerState(app, trackerMemFactor, now); 16276 app.procStateChanged = false; 16277 } 16278 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16279 || app.systemNoUi) && app.pendingUiClean) { 16280 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16281 && app.thread != null) { 16282 try { 16283 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16284 "Trimming memory of ui hidden " + app.processName 16285 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16286 app.thread.scheduleTrimMemory( 16287 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16288 } catch (RemoteException e) { 16289 } 16290 } 16291 app.pendingUiClean = false; 16292 } 16293 app.trimMemoryLevel = 0; 16294 } 16295 } 16296 16297 if (mAlwaysFinishActivities) { 16298 // Need to do this on its own message because the stack may not 16299 // be in a consistent state at this point. 16300 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16301 } 16302 16303 if (allChanged) { 16304 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16305 } 16306 16307 if (mProcessStats.shouldWriteNowLocked(now)) { 16308 mHandler.post(new Runnable() { 16309 @Override public void run() { 16310 synchronized (ActivityManagerService.this) { 16311 mProcessStats.writeStateAsyncLocked(); 16312 } 16313 } 16314 }); 16315 } 16316 16317 if (DEBUG_OOM_ADJ) { 16318 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16319 } 16320 } 16321 16322 final void trimApplications() { 16323 synchronized (this) { 16324 int i; 16325 16326 // First remove any unused application processes whose package 16327 // has been removed. 16328 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16329 final ProcessRecord app = mRemovedProcesses.get(i); 16330 if (app.activities.size() == 0 16331 && app.curReceiver == null && app.services.size() == 0) { 16332 Slog.i( 16333 TAG, "Exiting empty application process " 16334 + app.processName + " (" 16335 + (app.thread != null ? app.thread.asBinder() : null) 16336 + ")\n"); 16337 if (app.pid > 0 && app.pid != MY_PID) { 16338 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16339 app.processName, app.setAdj, "empty"); 16340 app.killedByAm = true; 16341 Process.killProcessQuiet(app.pid); 16342 } else { 16343 try { 16344 app.thread.scheduleExit(); 16345 } catch (Exception e) { 16346 // Ignore exceptions. 16347 } 16348 } 16349 cleanUpApplicationRecordLocked(app, false, true, -1); 16350 mRemovedProcesses.remove(i); 16351 16352 if (app.persistent) { 16353 if (app.persistent) { 16354 addAppLocked(app.info, false, null /* ABI override */); 16355 } 16356 } 16357 } 16358 } 16359 16360 // Now update the oom adj for all processes. 16361 updateOomAdjLocked(); 16362 } 16363 } 16364 16365 /** This method sends the specified signal to each of the persistent apps */ 16366 public void signalPersistentProcesses(int sig) throws RemoteException { 16367 if (sig != Process.SIGNAL_USR1) { 16368 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16369 } 16370 16371 synchronized (this) { 16372 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16373 != PackageManager.PERMISSION_GRANTED) { 16374 throw new SecurityException("Requires permission " 16375 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16376 } 16377 16378 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16379 ProcessRecord r = mLruProcesses.get(i); 16380 if (r.thread != null && r.persistent) { 16381 Process.sendSignal(r.pid, sig); 16382 } 16383 } 16384 } 16385 } 16386 16387 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16388 if (proc == null || proc == mProfileProc) { 16389 proc = mProfileProc; 16390 path = mProfileFile; 16391 profileType = mProfileType; 16392 clearProfilerLocked(); 16393 } 16394 if (proc == null) { 16395 return; 16396 } 16397 try { 16398 proc.thread.profilerControl(false, path, null, profileType); 16399 } catch (RemoteException e) { 16400 throw new IllegalStateException("Process disappeared"); 16401 } 16402 } 16403 16404 private void clearProfilerLocked() { 16405 if (mProfileFd != null) { 16406 try { 16407 mProfileFd.close(); 16408 } catch (IOException e) { 16409 } 16410 } 16411 mProfileApp = null; 16412 mProfileProc = null; 16413 mProfileFile = null; 16414 mProfileType = 0; 16415 mAutoStopProfiler = false; 16416 } 16417 16418 public boolean profileControl(String process, int userId, boolean start, 16419 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16420 16421 try { 16422 synchronized (this) { 16423 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16424 // its own permission. 16425 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16426 != PackageManager.PERMISSION_GRANTED) { 16427 throw new SecurityException("Requires permission " 16428 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16429 } 16430 16431 if (start && fd == null) { 16432 throw new IllegalArgumentException("null fd"); 16433 } 16434 16435 ProcessRecord proc = null; 16436 if (process != null) { 16437 proc = findProcessLocked(process, userId, "profileControl"); 16438 } 16439 16440 if (start && (proc == null || proc.thread == null)) { 16441 throw new IllegalArgumentException("Unknown process: " + process); 16442 } 16443 16444 if (start) { 16445 stopProfilerLocked(null, null, 0); 16446 setProfileApp(proc.info, proc.processName, path, fd, false); 16447 mProfileProc = proc; 16448 mProfileType = profileType; 16449 try { 16450 fd = fd.dup(); 16451 } catch (IOException e) { 16452 fd = null; 16453 } 16454 proc.thread.profilerControl(start, path, fd, profileType); 16455 fd = null; 16456 mProfileFd = null; 16457 } else { 16458 stopProfilerLocked(proc, path, profileType); 16459 if (fd != null) { 16460 try { 16461 fd.close(); 16462 } catch (IOException e) { 16463 } 16464 } 16465 } 16466 16467 return true; 16468 } 16469 } catch (RemoteException e) { 16470 throw new IllegalStateException("Process disappeared"); 16471 } finally { 16472 if (fd != null) { 16473 try { 16474 fd.close(); 16475 } catch (IOException e) { 16476 } 16477 } 16478 } 16479 } 16480 16481 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16482 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16483 userId, true, true, callName, null); 16484 ProcessRecord proc = null; 16485 try { 16486 int pid = Integer.parseInt(process); 16487 synchronized (mPidsSelfLocked) { 16488 proc = mPidsSelfLocked.get(pid); 16489 } 16490 } catch (NumberFormatException e) { 16491 } 16492 16493 if (proc == null) { 16494 ArrayMap<String, SparseArray<ProcessRecord>> all 16495 = mProcessNames.getMap(); 16496 SparseArray<ProcessRecord> procs = all.get(process); 16497 if (procs != null && procs.size() > 0) { 16498 proc = procs.valueAt(0); 16499 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16500 for (int i=1; i<procs.size(); i++) { 16501 ProcessRecord thisProc = procs.valueAt(i); 16502 if (thisProc.userId == userId) { 16503 proc = thisProc; 16504 break; 16505 } 16506 } 16507 } 16508 } 16509 } 16510 16511 return proc; 16512 } 16513 16514 public boolean dumpHeap(String process, int userId, boolean managed, 16515 String path, ParcelFileDescriptor fd) throws RemoteException { 16516 16517 try { 16518 synchronized (this) { 16519 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16520 // its own permission (same as profileControl). 16521 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16522 != PackageManager.PERMISSION_GRANTED) { 16523 throw new SecurityException("Requires permission " 16524 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16525 } 16526 16527 if (fd == null) { 16528 throw new IllegalArgumentException("null fd"); 16529 } 16530 16531 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16532 if (proc == null || proc.thread == null) { 16533 throw new IllegalArgumentException("Unknown process: " + process); 16534 } 16535 16536 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16537 if (!isDebuggable) { 16538 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16539 throw new SecurityException("Process not debuggable: " + proc); 16540 } 16541 } 16542 16543 proc.thread.dumpHeap(managed, path, fd); 16544 fd = null; 16545 return true; 16546 } 16547 } catch (RemoteException e) { 16548 throw new IllegalStateException("Process disappeared"); 16549 } finally { 16550 if (fd != null) { 16551 try { 16552 fd.close(); 16553 } catch (IOException e) { 16554 } 16555 } 16556 } 16557 } 16558 16559 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16560 public void monitor() { 16561 synchronized (this) { } 16562 } 16563 16564 void onCoreSettingsChange(Bundle settings) { 16565 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16566 ProcessRecord processRecord = mLruProcesses.get(i); 16567 try { 16568 if (processRecord.thread != null) { 16569 processRecord.thread.setCoreSettings(settings); 16570 } 16571 } catch (RemoteException re) { 16572 /* ignore */ 16573 } 16574 } 16575 } 16576 16577 // Multi-user methods 16578 16579 /** 16580 * Start user, if its not already running, but don't bring it to foreground. 16581 */ 16582 @Override 16583 public boolean startUserInBackground(final int userId) { 16584 return startUser(userId, /* foreground */ false); 16585 } 16586 16587 /** 16588 * Refreshes the list of users related to the current user when either a 16589 * user switch happens or when a new related user is started in the 16590 * background. 16591 */ 16592 private void updateCurrentProfileIdsLocked() { 16593 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16594 mCurrentUserId, false /* enabledOnly */); 16595 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16596 for (int i = 0; i < currentProfileIds.length; i++) { 16597 currentProfileIds[i] = profiles.get(i).id; 16598 } 16599 mCurrentProfileIds = currentProfileIds; 16600 } 16601 16602 private Set getProfileIdsLocked(int userId) { 16603 Set userIds = new HashSet<Integer>(); 16604 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16605 userId, false /* enabledOnly */); 16606 for (UserInfo user : profiles) { 16607 userIds.add(Integer.valueOf(user.id)); 16608 } 16609 return userIds; 16610 } 16611 16612 @Override 16613 public boolean switchUser(final int userId) { 16614 return startUser(userId, /* foregound */ true); 16615 } 16616 16617 private boolean startUser(final int userId, boolean foreground) { 16618 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16619 != PackageManager.PERMISSION_GRANTED) { 16620 String msg = "Permission Denial: switchUser() from pid=" 16621 + Binder.getCallingPid() 16622 + ", uid=" + Binder.getCallingUid() 16623 + " requires " + INTERACT_ACROSS_USERS_FULL; 16624 Slog.w(TAG, msg); 16625 throw new SecurityException(msg); 16626 } 16627 16628 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16629 16630 final long ident = Binder.clearCallingIdentity(); 16631 try { 16632 synchronized (this) { 16633 final int oldUserId = mCurrentUserId; 16634 if (oldUserId == userId) { 16635 return true; 16636 } 16637 16638 mStackSupervisor.setLockTaskModeLocked(null); 16639 16640 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16641 if (userInfo == null) { 16642 Slog.w(TAG, "No user info for user #" + userId); 16643 return false; 16644 } 16645 16646 if (foreground) { 16647 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16648 R.anim.screen_user_enter); 16649 } 16650 16651 boolean needStart = false; 16652 16653 // If the user we are switching to is not currently started, then 16654 // we need to start it now. 16655 if (mStartedUsers.get(userId) == null) { 16656 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16657 updateStartedUserArrayLocked(); 16658 needStart = true; 16659 } 16660 16661 final Integer userIdInt = Integer.valueOf(userId); 16662 mUserLru.remove(userIdInt); 16663 mUserLru.add(userIdInt); 16664 16665 if (foreground) { 16666 mCurrentUserId = userId; 16667 updateCurrentProfileIdsLocked(); 16668 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16669 // Once the internal notion of the active user has switched, we lock the device 16670 // with the option to show the user switcher on the keyguard. 16671 mWindowManager.lockNow(null); 16672 } else { 16673 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16674 updateCurrentProfileIdsLocked(); 16675 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16676 mUserLru.remove(currentUserIdInt); 16677 mUserLru.add(currentUserIdInt); 16678 } 16679 16680 final UserStartedState uss = mStartedUsers.get(userId); 16681 16682 // Make sure user is in the started state. If it is currently 16683 // stopping, we need to knock that off. 16684 if (uss.mState == UserStartedState.STATE_STOPPING) { 16685 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16686 // so we can just fairly silently bring the user back from 16687 // the almost-dead. 16688 uss.mState = UserStartedState.STATE_RUNNING; 16689 updateStartedUserArrayLocked(); 16690 needStart = true; 16691 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16692 // This means ACTION_SHUTDOWN has been sent, so we will 16693 // need to treat this as a new boot of the user. 16694 uss.mState = UserStartedState.STATE_BOOTING; 16695 updateStartedUserArrayLocked(); 16696 needStart = true; 16697 } 16698 16699 if (uss.mState == UserStartedState.STATE_BOOTING) { 16700 // Booting up a new user, need to tell system services about it. 16701 // Note that this is on the same handler as scheduling of broadcasts, 16702 // which is important because it needs to go first. 16703 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16704 } 16705 16706 if (foreground) { 16707 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16708 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16709 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16710 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16711 oldUserId, userId, uss)); 16712 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16713 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16714 } 16715 16716 if (needStart) { 16717 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16718 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16719 | Intent.FLAG_RECEIVER_FOREGROUND); 16720 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16721 broadcastIntentLocked(null, null, intent, 16722 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16723 false, false, MY_PID, Process.SYSTEM_UID, userId); 16724 } 16725 16726 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16727 if (userId != UserHandle.USER_OWNER) { 16728 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16729 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16730 broadcastIntentLocked(null, null, intent, null, 16731 new IIntentReceiver.Stub() { 16732 public void performReceive(Intent intent, int resultCode, 16733 String data, Bundle extras, boolean ordered, 16734 boolean sticky, int sendingUser) { 16735 userInitialized(uss, userId); 16736 } 16737 }, 0, null, null, null, AppOpsManager.OP_NONE, 16738 true, false, MY_PID, Process.SYSTEM_UID, 16739 userId); 16740 uss.initializing = true; 16741 } else { 16742 getUserManagerLocked().makeInitialized(userInfo.id); 16743 } 16744 } 16745 16746 if (foreground) { 16747 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16748 if (homeInFront) { 16749 startHomeActivityLocked(userId); 16750 } else { 16751 mStackSupervisor.resumeTopActivitiesLocked(); 16752 } 16753 EventLogTags.writeAmSwitchUser(userId); 16754 getUserManagerLocked().userForeground(userId); 16755 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16756 } else { 16757 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16758 } 16759 16760 if (needStart) { 16761 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16762 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16763 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16764 broadcastIntentLocked(null, null, intent, 16765 null, new IIntentReceiver.Stub() { 16766 @Override 16767 public void performReceive(Intent intent, int resultCode, String data, 16768 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16769 throws RemoteException { 16770 } 16771 }, 0, null, null, 16772 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16773 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16774 } 16775 } 16776 } finally { 16777 Binder.restoreCallingIdentity(ident); 16778 } 16779 16780 return true; 16781 } 16782 16783 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16784 long ident = Binder.clearCallingIdentity(); 16785 try { 16786 Intent intent; 16787 if (oldUserId >= 0) { 16788 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16789 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16790 | Intent.FLAG_RECEIVER_FOREGROUND); 16791 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16792 broadcastIntentLocked(null, null, intent, 16793 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16794 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16795 } 16796 if (newUserId >= 0) { 16797 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16798 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16799 | Intent.FLAG_RECEIVER_FOREGROUND); 16800 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16801 broadcastIntentLocked(null, null, intent, 16802 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16803 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16804 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16805 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16806 | Intent.FLAG_RECEIVER_FOREGROUND); 16807 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16808 broadcastIntentLocked(null, null, intent, 16809 null, null, 0, null, null, 16810 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16811 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16812 } 16813 } finally { 16814 Binder.restoreCallingIdentity(ident); 16815 } 16816 } 16817 16818 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16819 final int newUserId) { 16820 final int N = mUserSwitchObservers.beginBroadcast(); 16821 if (N > 0) { 16822 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16823 int mCount = 0; 16824 @Override 16825 public void sendResult(Bundle data) throws RemoteException { 16826 synchronized (ActivityManagerService.this) { 16827 if (mCurUserSwitchCallback == this) { 16828 mCount++; 16829 if (mCount == N) { 16830 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16831 } 16832 } 16833 } 16834 } 16835 }; 16836 synchronized (this) { 16837 uss.switching = true; 16838 mCurUserSwitchCallback = callback; 16839 } 16840 for (int i=0; i<N; i++) { 16841 try { 16842 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16843 newUserId, callback); 16844 } catch (RemoteException e) { 16845 } 16846 } 16847 } else { 16848 synchronized (this) { 16849 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16850 } 16851 } 16852 mUserSwitchObservers.finishBroadcast(); 16853 } 16854 16855 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16856 synchronized (this) { 16857 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16858 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16859 } 16860 } 16861 16862 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16863 mCurUserSwitchCallback = null; 16864 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16865 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16866 oldUserId, newUserId, uss)); 16867 } 16868 16869 void userInitialized(UserStartedState uss, int newUserId) { 16870 completeSwitchAndInitalize(uss, newUserId, true, false); 16871 } 16872 16873 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16874 completeSwitchAndInitalize(uss, newUserId, false, true); 16875 } 16876 16877 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16878 boolean clearInitializing, boolean clearSwitching) { 16879 boolean unfrozen = false; 16880 synchronized (this) { 16881 if (clearInitializing) { 16882 uss.initializing = false; 16883 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16884 } 16885 if (clearSwitching) { 16886 uss.switching = false; 16887 } 16888 if (!uss.switching && !uss.initializing) { 16889 mWindowManager.stopFreezingScreen(); 16890 unfrozen = true; 16891 } 16892 } 16893 if (unfrozen) { 16894 final int N = mUserSwitchObservers.beginBroadcast(); 16895 for (int i=0; i<N; i++) { 16896 try { 16897 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16898 } catch (RemoteException e) { 16899 } 16900 } 16901 mUserSwitchObservers.finishBroadcast(); 16902 } 16903 } 16904 16905 void scheduleStartProfilesLocked() { 16906 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16907 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16908 DateUtils.SECOND_IN_MILLIS); 16909 } 16910 } 16911 16912 void startProfilesLocked() { 16913 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16914 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16915 mCurrentUserId, false /* enabledOnly */); 16916 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16917 for (UserInfo user : profiles) { 16918 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16919 && user.id != mCurrentUserId) { 16920 toStart.add(user); 16921 } 16922 } 16923 final int n = toStart.size(); 16924 int i = 0; 16925 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16926 startUserInBackground(toStart.get(i).id); 16927 } 16928 if (i < n) { 16929 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16930 } 16931 } 16932 16933 void finishUserBoot(UserStartedState uss) { 16934 synchronized (this) { 16935 if (uss.mState == UserStartedState.STATE_BOOTING 16936 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16937 uss.mState = UserStartedState.STATE_RUNNING; 16938 final int userId = uss.mHandle.getIdentifier(); 16939 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16940 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16941 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16942 broadcastIntentLocked(null, null, intent, 16943 null, null, 0, null, null, 16944 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16945 true, false, MY_PID, Process.SYSTEM_UID, userId); 16946 } 16947 } 16948 } 16949 16950 void finishUserSwitch(UserStartedState uss) { 16951 synchronized (this) { 16952 finishUserBoot(uss); 16953 16954 startProfilesLocked(); 16955 16956 int num = mUserLru.size(); 16957 int i = 0; 16958 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16959 Integer oldUserId = mUserLru.get(i); 16960 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16961 if (oldUss == null) { 16962 // Shouldn't happen, but be sane if it does. 16963 mUserLru.remove(i); 16964 num--; 16965 continue; 16966 } 16967 if (oldUss.mState == UserStartedState.STATE_STOPPING 16968 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16969 // This user is already stopping, doesn't count. 16970 num--; 16971 i++; 16972 continue; 16973 } 16974 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16975 // Owner and current can't be stopped, but count as running. 16976 i++; 16977 continue; 16978 } 16979 // This is a user to be stopped. 16980 stopUserLocked(oldUserId, null); 16981 num--; 16982 i++; 16983 } 16984 } 16985 } 16986 16987 @Override 16988 public int stopUser(final int userId, final IStopUserCallback callback) { 16989 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16990 != PackageManager.PERMISSION_GRANTED) { 16991 String msg = "Permission Denial: switchUser() from pid=" 16992 + Binder.getCallingPid() 16993 + ", uid=" + Binder.getCallingUid() 16994 + " requires " + INTERACT_ACROSS_USERS_FULL; 16995 Slog.w(TAG, msg); 16996 throw new SecurityException(msg); 16997 } 16998 if (userId <= 0) { 16999 throw new IllegalArgumentException("Can't stop primary user " + userId); 17000 } 17001 synchronized (this) { 17002 return stopUserLocked(userId, callback); 17003 } 17004 } 17005 17006 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17007 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17008 if (mCurrentUserId == userId) { 17009 return ActivityManager.USER_OP_IS_CURRENT; 17010 } 17011 17012 final UserStartedState uss = mStartedUsers.get(userId); 17013 if (uss == null) { 17014 // User is not started, nothing to do... but we do need to 17015 // callback if requested. 17016 if (callback != null) { 17017 mHandler.post(new Runnable() { 17018 @Override 17019 public void run() { 17020 try { 17021 callback.userStopped(userId); 17022 } catch (RemoteException e) { 17023 } 17024 } 17025 }); 17026 } 17027 return ActivityManager.USER_OP_SUCCESS; 17028 } 17029 17030 if (callback != null) { 17031 uss.mStopCallbacks.add(callback); 17032 } 17033 17034 if (uss.mState != UserStartedState.STATE_STOPPING 17035 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17036 uss.mState = UserStartedState.STATE_STOPPING; 17037 updateStartedUserArrayLocked(); 17038 17039 long ident = Binder.clearCallingIdentity(); 17040 try { 17041 // We are going to broadcast ACTION_USER_STOPPING and then 17042 // once that is done send a final ACTION_SHUTDOWN and then 17043 // stop the user. 17044 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17045 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17046 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17047 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17048 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17049 // This is the result receiver for the final shutdown broadcast. 17050 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17051 @Override 17052 public void performReceive(Intent intent, int resultCode, String data, 17053 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17054 finishUserStop(uss); 17055 } 17056 }; 17057 // This is the result receiver for the initial stopping broadcast. 17058 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17059 @Override 17060 public void performReceive(Intent intent, int resultCode, String data, 17061 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17062 // On to the next. 17063 synchronized (ActivityManagerService.this) { 17064 if (uss.mState != UserStartedState.STATE_STOPPING) { 17065 // Whoops, we are being started back up. Abort, abort! 17066 return; 17067 } 17068 uss.mState = UserStartedState.STATE_SHUTDOWN; 17069 } 17070 mSystemServiceManager.stopUser(userId); 17071 broadcastIntentLocked(null, null, shutdownIntent, 17072 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17073 true, false, MY_PID, Process.SYSTEM_UID, userId); 17074 } 17075 }; 17076 // Kick things off. 17077 broadcastIntentLocked(null, null, stoppingIntent, 17078 null, stoppingReceiver, 0, null, null, 17079 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17080 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17081 } finally { 17082 Binder.restoreCallingIdentity(ident); 17083 } 17084 } 17085 17086 return ActivityManager.USER_OP_SUCCESS; 17087 } 17088 17089 void finishUserStop(UserStartedState uss) { 17090 final int userId = uss.mHandle.getIdentifier(); 17091 boolean stopped; 17092 ArrayList<IStopUserCallback> callbacks; 17093 synchronized (this) { 17094 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17095 if (mStartedUsers.get(userId) != uss) { 17096 stopped = false; 17097 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17098 stopped = false; 17099 } else { 17100 stopped = true; 17101 // User can no longer run. 17102 mStartedUsers.remove(userId); 17103 mUserLru.remove(Integer.valueOf(userId)); 17104 updateStartedUserArrayLocked(); 17105 17106 // Clean up all state and processes associated with the user. 17107 // Kill all the processes for the user. 17108 forceStopUserLocked(userId, "finish user"); 17109 } 17110 } 17111 17112 for (int i=0; i<callbacks.size(); i++) { 17113 try { 17114 if (stopped) callbacks.get(i).userStopped(userId); 17115 else callbacks.get(i).userStopAborted(userId); 17116 } catch (RemoteException e) { 17117 } 17118 } 17119 17120 if (stopped) { 17121 mSystemServiceManager.cleanupUser(userId); 17122 synchronized (this) { 17123 mStackSupervisor.removeUserLocked(userId); 17124 } 17125 } 17126 } 17127 17128 @Override 17129 public UserInfo getCurrentUser() { 17130 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17131 != PackageManager.PERMISSION_GRANTED) && ( 17132 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17133 != PackageManager.PERMISSION_GRANTED)) { 17134 String msg = "Permission Denial: getCurrentUser() from pid=" 17135 + Binder.getCallingPid() 17136 + ", uid=" + Binder.getCallingUid() 17137 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17138 Slog.w(TAG, msg); 17139 throw new SecurityException(msg); 17140 } 17141 synchronized (this) { 17142 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17143 } 17144 } 17145 17146 int getCurrentUserIdLocked() { 17147 return mCurrentUserId; 17148 } 17149 17150 @Override 17151 public boolean isUserRunning(int userId, boolean orStopped) { 17152 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17153 != PackageManager.PERMISSION_GRANTED) { 17154 String msg = "Permission Denial: isUserRunning() from pid=" 17155 + Binder.getCallingPid() 17156 + ", uid=" + Binder.getCallingUid() 17157 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17158 Slog.w(TAG, msg); 17159 throw new SecurityException(msg); 17160 } 17161 synchronized (this) { 17162 return isUserRunningLocked(userId, orStopped); 17163 } 17164 } 17165 17166 boolean isUserRunningLocked(int userId, boolean orStopped) { 17167 UserStartedState state = mStartedUsers.get(userId); 17168 if (state == null) { 17169 return false; 17170 } 17171 if (orStopped) { 17172 return true; 17173 } 17174 return state.mState != UserStartedState.STATE_STOPPING 17175 && state.mState != UserStartedState.STATE_SHUTDOWN; 17176 } 17177 17178 @Override 17179 public int[] getRunningUserIds() { 17180 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17181 != PackageManager.PERMISSION_GRANTED) { 17182 String msg = "Permission Denial: isUserRunning() from pid=" 17183 + Binder.getCallingPid() 17184 + ", uid=" + Binder.getCallingUid() 17185 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17186 Slog.w(TAG, msg); 17187 throw new SecurityException(msg); 17188 } 17189 synchronized (this) { 17190 return mStartedUserArray; 17191 } 17192 } 17193 17194 private void updateStartedUserArrayLocked() { 17195 int num = 0; 17196 for (int i=0; i<mStartedUsers.size(); i++) { 17197 UserStartedState uss = mStartedUsers.valueAt(i); 17198 // This list does not include stopping users. 17199 if (uss.mState != UserStartedState.STATE_STOPPING 17200 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17201 num++; 17202 } 17203 } 17204 mStartedUserArray = new int[num]; 17205 num = 0; 17206 for (int i=0; i<mStartedUsers.size(); i++) { 17207 UserStartedState uss = mStartedUsers.valueAt(i); 17208 if (uss.mState != UserStartedState.STATE_STOPPING 17209 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17210 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17211 num++; 17212 } 17213 } 17214 } 17215 17216 @Override 17217 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17218 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17219 != PackageManager.PERMISSION_GRANTED) { 17220 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17221 + Binder.getCallingPid() 17222 + ", uid=" + Binder.getCallingUid() 17223 + " requires " + INTERACT_ACROSS_USERS_FULL; 17224 Slog.w(TAG, msg); 17225 throw new SecurityException(msg); 17226 } 17227 17228 mUserSwitchObservers.register(observer); 17229 } 17230 17231 @Override 17232 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17233 mUserSwitchObservers.unregister(observer); 17234 } 17235 17236 private boolean userExists(int userId) { 17237 if (userId == 0) { 17238 return true; 17239 } 17240 UserManagerService ums = getUserManagerLocked(); 17241 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17242 } 17243 17244 int[] getUsersLocked() { 17245 UserManagerService ums = getUserManagerLocked(); 17246 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17247 } 17248 17249 UserManagerService getUserManagerLocked() { 17250 if (mUserManager == null) { 17251 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17252 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17253 } 17254 return mUserManager; 17255 } 17256 17257 private int applyUserId(int uid, int userId) { 17258 return UserHandle.getUid(userId, uid); 17259 } 17260 17261 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17262 if (info == null) return null; 17263 ApplicationInfo newInfo = new ApplicationInfo(info); 17264 newInfo.uid = applyUserId(info.uid, userId); 17265 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17266 + info.packageName; 17267 return newInfo; 17268 } 17269 17270 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17271 if (aInfo == null 17272 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17273 return aInfo; 17274 } 17275 17276 ActivityInfo info = new ActivityInfo(aInfo); 17277 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17278 return info; 17279 } 17280 17281 private final class LocalService extends ActivityManagerInternal { 17282 @Override 17283 public void goingToSleep() { 17284 ActivityManagerService.this.goingToSleep(); 17285 } 17286 17287 @Override 17288 public void wakingUp() { 17289 ActivityManagerService.this.wakingUp(); 17290 } 17291 } 17292 17293 /** 17294 * An implementation of IAppTask, that allows an app to manage its own tasks via 17295 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17296 * only the process that calls getAppTasks() can call the AppTask methods. 17297 */ 17298 class AppTaskImpl extends IAppTask.Stub { 17299 private int mTaskId; 17300 private int mCallingUid; 17301 17302 public AppTaskImpl(int taskId, int callingUid) { 17303 mTaskId = taskId; 17304 mCallingUid = callingUid; 17305 } 17306 17307 @Override 17308 public void finishAndRemoveTask() { 17309 // Ensure that we are called from the same process that created this AppTask 17310 if (mCallingUid != Binder.getCallingUid()) { 17311 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17312 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17313 return; 17314 } 17315 17316 synchronized (ActivityManagerService.this) { 17317 long origId = Binder.clearCallingIdentity(); 17318 try { 17319 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17320 if (tr != null) { 17321 // Only kill the process if we are not a new document 17322 int flags = tr.getBaseIntent().getFlags(); 17323 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17324 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17325 removeTaskByIdLocked(mTaskId, 17326 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17327 } 17328 } finally { 17329 Binder.restoreCallingIdentity(origId); 17330 } 17331 } 17332 } 17333 17334 @Override 17335 public ActivityManager.RecentTaskInfo getTaskInfo() { 17336 // Ensure that we are called from the same process that created this AppTask 17337 if (mCallingUid != Binder.getCallingUid()) { 17338 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17339 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17340 return null; 17341 } 17342 17343 synchronized (ActivityManagerService.this) { 17344 long origId = Binder.clearCallingIdentity(); 17345 try { 17346 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17347 if (tr != null) { 17348 return createRecentTaskInfoFromTaskRecord(tr); 17349 } 17350 } finally { 17351 Binder.restoreCallingIdentity(origId); 17352 } 17353 return null; 17354 } 17355 } 17356 } 17357} 17358