ActivityManagerService.java revision d85fc72fb810858f7502e7e7f1bad53e1bf03edd
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.service.voice.IVoiceInteractionSession; 39import android.util.ArrayMap; 40 41import com.android.internal.R; 42import com.android.internal.annotations.GuardedBy; 43import com.android.internal.app.IAppOpsService; 44import com.android.internal.app.IVoiceInteractor; 45import com.android.internal.app.ProcessMap; 46import com.android.internal.app.ProcessStats; 47import com.android.internal.content.PackageMonitor; 48import com.android.internal.os.BackgroundThread; 49import com.android.internal.os.BatteryStatsImpl; 50import com.android.internal.os.ProcessCpuTracker; 51import com.android.internal.os.TransferPipe; 52import com.android.internal.os.Zygote; 53import com.android.internal.util.FastPrintWriter; 54import com.android.internal.util.FastXmlSerializer; 55import com.android.internal.util.MemInfoReader; 56import com.android.internal.util.Preconditions; 57import com.android.server.AppOpsService; 58import com.android.server.AttributeCache; 59import com.android.server.IntentResolver; 60import com.android.server.LocalServices; 61import com.android.server.ServiceThread; 62import com.android.server.SystemService; 63import com.android.server.SystemServiceManager; 64import com.android.server.Watchdog; 65import com.android.server.am.ActivityStack.ActivityState; 66import com.android.server.firewall.IntentFirewall; 67import com.android.server.pm.UserManagerService; 68import com.android.server.wm.AppTransition; 69import com.android.server.wm.WindowManagerService; 70import com.google.android.collect.Lists; 71import com.google.android.collect.Maps; 72 73import libcore.io.IoUtils; 74 75import org.xmlpull.v1.XmlPullParser; 76import org.xmlpull.v1.XmlPullParserException; 77import org.xmlpull.v1.XmlSerializer; 78 79import android.app.Activity; 80import android.app.ActivityManager; 81import android.app.ActivityManager.RunningTaskInfo; 82import android.app.ActivityManager.StackInfo; 83import android.app.ActivityManagerInternal; 84import android.app.ActivityManagerNative; 85import android.app.ActivityOptions; 86import android.app.ActivityThread; 87import android.app.AlertDialog; 88import android.app.AppGlobals; 89import android.app.ApplicationErrorReport; 90import android.app.Dialog; 91import android.app.IActivityController; 92import android.app.IApplicationThread; 93import android.app.IInstrumentationWatcher; 94import android.app.INotificationManager; 95import android.app.IProcessObserver; 96import android.app.IServiceConnection; 97import android.app.IStopUserCallback; 98import android.app.IUiAutomationConnection; 99import android.app.IUserSwitchObserver; 100import android.app.Instrumentation; 101import android.app.Notification; 102import android.app.NotificationManager; 103import android.app.PendingIntent; 104import android.app.backup.IBackupManager; 105import android.content.ActivityNotFoundException; 106import android.content.BroadcastReceiver; 107import android.content.ClipData; 108import android.content.ComponentCallbacks2; 109import android.content.ComponentName; 110import android.content.ContentProvider; 111import android.content.ContentResolver; 112import android.content.Context; 113import android.content.DialogInterface; 114import android.content.IContentProvider; 115import android.content.IIntentReceiver; 116import android.content.IIntentSender; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.ConfigurationInfo; 123import android.content.pm.IPackageDataObserver; 124import android.content.pm.IPackageManager; 125import android.content.pm.InstrumentationInfo; 126import android.content.pm.PackageInfo; 127import android.content.pm.PackageManager; 128import android.content.pm.ParceledListSlice; 129import android.content.pm.UserInfo; 130import android.content.pm.PackageManager.NameNotFoundException; 131import android.content.pm.PathPermission; 132import android.content.pm.ProviderInfo; 133import android.content.pm.ResolveInfo; 134import android.content.pm.ServiceInfo; 135import android.content.res.CompatibilityInfo; 136import android.content.res.Configuration; 137import android.graphics.Bitmap; 138import android.net.Proxy; 139import android.net.ProxyInfo; 140import android.net.Uri; 141import android.os.Binder; 142import android.os.Build; 143import android.os.Bundle; 144import android.os.Debug; 145import android.os.DropBoxManager; 146import android.os.Environment; 147import android.os.FactoryTest; 148import android.os.FileObserver; 149import android.os.FileUtils; 150import android.os.Handler; 151import android.os.IBinder; 152import android.os.IPermissionController; 153import android.os.IRemoteCallback; 154import android.os.IUserManager; 155import android.os.Looper; 156import android.os.Message; 157import android.os.Parcel; 158import android.os.ParcelFileDescriptor; 159import android.os.Process; 160import android.os.RemoteCallbackList; 161import android.os.RemoteException; 162import android.os.SELinux; 163import android.os.ServiceManager; 164import android.os.StrictMode; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.UpdateLock; 168import android.os.UserHandle; 169import android.provider.Settings; 170import android.text.format.DateUtils; 171import android.text.format.Time; 172import android.util.AtomicFile; 173import android.util.EventLog; 174import android.util.Log; 175import android.util.Pair; 176import android.util.PrintWriterPrinter; 177import android.util.Slog; 178import android.util.SparseArray; 179import android.util.TimeUtils; 180import android.util.Xml; 181import android.view.Gravity; 182import android.view.LayoutInflater; 183import android.view.View; 184import android.view.WindowManager; 185 186import java.io.BufferedInputStream; 187import java.io.BufferedOutputStream; 188import java.io.DataInputStream; 189import java.io.DataOutputStream; 190import java.io.File; 191import java.io.FileDescriptor; 192import java.io.FileInputStream; 193import java.io.FileNotFoundException; 194import java.io.FileOutputStream; 195import java.io.IOException; 196import java.io.InputStreamReader; 197import java.io.PrintWriter; 198import java.io.StringWriter; 199import java.lang.ref.WeakReference; 200import java.util.ArrayList; 201import java.util.Arrays; 202import java.util.Collections; 203import java.util.Comparator; 204import java.util.HashMap; 205import java.util.HashSet; 206import java.util.Iterator; 207import java.util.List; 208import java.util.Locale; 209import java.util.Map; 210import java.util.Set; 211import java.util.concurrent.atomic.AtomicBoolean; 212import java.util.concurrent.atomic.AtomicLong; 213 214public final class ActivityManagerService extends ActivityManagerNative 215 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 216 private static final String USER_DATA_DIR = "/data/user/"; 217 static final String TAG = "ActivityManager"; 218 static final String TAG_MU = "ActivityManagerServiceMU"; 219 static final boolean DEBUG = false; 220 static final boolean localLOGV = DEBUG; 221 static final boolean DEBUG_BACKUP = localLOGV || false; 222 static final boolean DEBUG_BROADCAST = localLOGV || false; 223 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 224 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_CLEANUP = localLOGV || false; 226 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 227 static final boolean DEBUG_FOCUS = false; 228 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 229 static final boolean DEBUG_MU = localLOGV || false; 230 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 231 static final boolean DEBUG_LRU = localLOGV || false; 232 static final boolean DEBUG_PAUSE = localLOGV || false; 233 static final boolean DEBUG_POWER = localLOGV || false; 234 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 235 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 236 static final boolean DEBUG_PROCESSES = localLOGV || false; 237 static final boolean DEBUG_PROVIDER = localLOGV || false; 238 static final boolean DEBUG_RESULTS = localLOGV || false; 239 static final boolean DEBUG_SERVICE = localLOGV || false; 240 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 241 static final boolean DEBUG_STACK = localLOGV || false; 242 static final boolean DEBUG_SWITCH = localLOGV || false; 243 static final boolean DEBUG_TASKS = localLOGV || false; 244 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 245 static final boolean DEBUG_TRANSITION = localLOGV || false; 246 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 247 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 248 static final boolean DEBUG_VISBILITY = localLOGV || false; 249 static final boolean DEBUG_PSS = localLOGV || false; 250 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 251 static final boolean VALIDATE_TOKENS = false; 252 static final boolean SHOW_ACTIVITY_START_TIME = true; 253 254 // Control over CPU and battery monitoring. 255 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 256 static final boolean MONITOR_CPU_USAGE = true; 257 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 258 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 259 static final boolean MONITOR_THREAD_CPU_USAGE = false; 260 261 // The flags that are set for all calls we make to the package manager. 262 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 263 264 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 265 266 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 267 268 // Maximum number of recent tasks that we can remember. 269 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 270 271 // Amount of time after a call to stopAppSwitches() during which we will 272 // prevent further untrusted switches from happening. 273 static final long APP_SWITCH_DELAY_TIME = 5*1000; 274 275 // How long we wait for a launched process to attach to the activity manager 276 // before we decide it's never going to come up for real. 277 static final int PROC_START_TIMEOUT = 10*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real, when the process was 281 // started with a wrapper for instrumentation (such as Valgrind) because it 282 // could take much longer than usual. 283 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 284 285 // How long to wait after going idle before forcing apps to GC. 286 static final int GC_TIMEOUT = 5*1000; 287 288 // The minimum amount of time between successive GC requests for a process. 289 static final int GC_MIN_INTERVAL = 60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process. 292 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process 295 // when the request is due to the memory state being lowered. 296 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 297 298 // The rate at which we check for apps using excessive power -- 15 mins. 299 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on wake locks to start killing things. 303 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on CPU usage to start killing things. 307 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // How long we allow a receiver to run before giving up on it. 310 static final int BROADCAST_FG_TIMEOUT = 10*1000; 311 static final int BROADCAST_BG_TIMEOUT = 60*1000; 312 313 // How long we wait until we timeout on key dispatching. 314 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 315 316 // How long we wait until we timeout on key dispatching during instrumentation. 317 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 318 319 // Amount of time we wait for observers to handle a user switch before 320 // giving up on them and unfreezing the screen. 321 static final int USER_SWITCH_TIMEOUT = 2*1000; 322 323 // Maximum number of users we allow to be running at a time. 324 static final int MAX_RUNNING_USERS = 3; 325 326 // How long to wait in getAssistContextExtras for the activity and foreground services 327 // to respond with the result. 328 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 329 330 // Maximum number of persisted Uri grants a package is allowed 331 static final int MAX_PERSISTED_URI_GRANTS = 128; 332 333 static final int MY_PID = Process.myPid(); 334 335 static final String[] EMPTY_STRING_ARRAY = new String[0]; 336 337 // How many bytes to write into the dropbox log before truncating 338 static final int DROPBOX_MAX_SIZE = 256 * 1024; 339 340 /** All system services */ 341 SystemServiceManager mSystemServiceManager; 342 343 /** Run all ActivityStacks through this */ 344 ActivityStackSupervisor mStackSupervisor; 345 346 public IntentFirewall mIntentFirewall; 347 348 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 349 // default actuion automatically. Important for devices without direct input 350 // devices. 351 private boolean mShowDialogs = true; 352 353 /** 354 * Description of a request to start a new activity, which has been held 355 * due to app switches being disabled. 356 */ 357 static class PendingActivityLaunch { 358 final ActivityRecord r; 359 final ActivityRecord sourceRecord; 360 final int startFlags; 361 final ActivityStack stack; 362 363 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 364 int _startFlags, ActivityStack _stack) { 365 r = _r; 366 sourceRecord = _sourceRecord; 367 startFlags = _startFlags; 368 stack = _stack; 369 } 370 } 371 372 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 373 = new ArrayList<PendingActivityLaunch>(); 374 375 BroadcastQueue mFgBroadcastQueue; 376 BroadcastQueue mBgBroadcastQueue; 377 // Convenient for easy iteration over the queues. Foreground is first 378 // so that dispatch of foreground broadcasts gets precedence. 379 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 380 381 BroadcastQueue broadcastQueueForIntent(Intent intent) { 382 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 383 if (DEBUG_BACKGROUND_BROADCAST) { 384 Slog.i(TAG, "Broadcast intent " + intent + " on " 385 + (isFg ? "foreground" : "background") 386 + " queue"); 387 } 388 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 389 } 390 391 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 392 for (BroadcastQueue queue : mBroadcastQueues) { 393 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 394 if (r != null) { 395 return r; 396 } 397 } 398 return null; 399 } 400 401 /** 402 * Activity we have told the window manager to have key focus. 403 */ 404 ActivityRecord mFocusedActivity = null; 405 406 /** 407 * List of intents that were used to start the most recent tasks. 408 */ 409 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 410 411 public class PendingAssistExtras extends Binder implements Runnable { 412 public final ActivityRecord activity; 413 public boolean haveResult = false; 414 public Bundle result = null; 415 public PendingAssistExtras(ActivityRecord _activity) { 416 activity = _activity; 417 } 418 @Override 419 public void run() { 420 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 421 synchronized (this) { 422 haveResult = true; 423 notifyAll(); 424 } 425 } 426 } 427 428 final ArrayList<PendingAssistExtras> mPendingAssistExtras 429 = new ArrayList<PendingAssistExtras>(); 430 431 /** 432 * Process management. 433 */ 434 final ProcessList mProcessList = new ProcessList(); 435 436 /** 437 * All of the applications we currently have running organized by name. 438 * The keys are strings of the application package name (as 439 * returned by the package manager), and the keys are ApplicationRecord 440 * objects. 441 */ 442 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 443 444 /** 445 * Tracking long-term execution of processes to look for abuse and other 446 * bad app behavior. 447 */ 448 final ProcessStatsService mProcessStats; 449 450 /** 451 * The currently running isolated processes. 452 */ 453 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 454 455 /** 456 * Counter for assigning isolated process uids, to avoid frequently reusing the 457 * same ones. 458 */ 459 int mNextIsolatedProcessUid = 0; 460 461 /** 462 * The currently running heavy-weight process, if any. 463 */ 464 ProcessRecord mHeavyWeightProcess = null; 465 466 /** 467 * The last time that various processes have crashed. 468 */ 469 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 470 471 /** 472 * Information about a process that is currently marked as bad. 473 */ 474 static final class BadProcessInfo { 475 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 476 this.time = time; 477 this.shortMsg = shortMsg; 478 this.longMsg = longMsg; 479 this.stack = stack; 480 } 481 482 final long time; 483 final String shortMsg; 484 final String longMsg; 485 final String stack; 486 } 487 488 /** 489 * Set of applications that we consider to be bad, and will reject 490 * incoming broadcasts from (which the user has no control over). 491 * Processes are added to this set when they have crashed twice within 492 * a minimum amount of time; they are removed from it when they are 493 * later restarted (hopefully due to some user action). The value is the 494 * time it was added to the list. 495 */ 496 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 497 498 /** 499 * All of the processes we currently have running organized by pid. 500 * The keys are the pid running the application. 501 * 502 * <p>NOTE: This object is protected by its own lock, NOT the global 503 * activity manager lock! 504 */ 505 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 506 507 /** 508 * All of the processes that have been forced to be foreground. The key 509 * is the pid of the caller who requested it (we hold a death 510 * link on it). 511 */ 512 abstract class ForegroundToken implements IBinder.DeathRecipient { 513 int pid; 514 IBinder token; 515 } 516 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 517 518 /** 519 * List of records for processes that someone had tried to start before the 520 * system was ready. We don't start them at that point, but ensure they 521 * are started by the time booting is complete. 522 */ 523 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of persistent applications that are in the process 527 * of being started. 528 */ 529 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Processes that are being forcibly torn down. 533 */ 534 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * List of running applications, sorted by recent usage. 538 * The first entry in the list is the least recently used. 539 */ 540 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * Where in mLruProcesses that the processes hosting activities start. 544 */ 545 int mLruProcessActivityStart = 0; 546 547 /** 548 * Where in mLruProcesses that the processes hosting services start. 549 * This is after (lower index) than mLruProcessesActivityStart. 550 */ 551 int mLruProcessServiceStart = 0; 552 553 /** 554 * List of processes that should gc as soon as things are idle. 555 */ 556 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes we want to collect PSS data from. 560 */ 561 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Last time we requested PSS data of all processes. 565 */ 566 long mLastFullPssTime = SystemClock.uptimeMillis(); 567 568 /** 569 * This is the process holding what we currently consider to be 570 * the "home" activity. 571 */ 572 ProcessRecord mHomeProcess; 573 574 /** 575 * This is the process holding the activity the user last visited that 576 * is in a different process from the one they are currently in. 577 */ 578 ProcessRecord mPreviousProcess; 579 580 /** 581 * The time at which the previous process was last visible. 582 */ 583 long mPreviousProcessVisibleTime; 584 585 /** 586 * Which uses have been started, so are allowed to run code. 587 */ 588 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 589 590 /** 591 * LRU list of history of current users. Most recently current is at the end. 592 */ 593 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 594 595 /** 596 * Constant array of the users that are currently started. 597 */ 598 int[] mStartedUserArray = new int[] { 0 }; 599 600 /** 601 * Registered observers of the user switching mechanics. 602 */ 603 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 604 = new RemoteCallbackList<IUserSwitchObserver>(); 605 606 /** 607 * Currently active user switch. 608 */ 609 Object mCurUserSwitchCallback; 610 611 /** 612 * Packages that the user has asked to have run in screen size 613 * compatibility mode instead of filling the screen. 614 */ 615 final CompatModePackages mCompatModePackages; 616 617 /** 618 * Set of IntentSenderRecord objects that are currently active. 619 */ 620 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 621 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 622 623 /** 624 * Fingerprints (hashCode()) of stack traces that we've 625 * already logged DropBox entries for. Guarded by itself. If 626 * something (rogue user app) forces this over 627 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 628 */ 629 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 630 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 631 632 /** 633 * Strict Mode background batched logging state. 634 * 635 * The string buffer is guarded by itself, and its lock is also 636 * used to determine if another batched write is already 637 * in-flight. 638 */ 639 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 640 641 /** 642 * Keeps track of all IIntentReceivers that have been registered for 643 * broadcasts. Hash keys are the receiver IBinder, hash value is 644 * a ReceiverList. 645 */ 646 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 647 new HashMap<IBinder, ReceiverList>(); 648 649 /** 650 * Resolver for broadcast intents to registered receivers. 651 * Holds BroadcastFilter (subclass of IntentFilter). 652 */ 653 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 654 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 655 @Override 656 protected boolean allowFilterResult( 657 BroadcastFilter filter, List<BroadcastFilter> dest) { 658 IBinder target = filter.receiverList.receiver.asBinder(); 659 for (int i=dest.size()-1; i>=0; i--) { 660 if (dest.get(i).receiverList.receiver.asBinder() == target) { 661 return false; 662 } 663 } 664 return true; 665 } 666 667 @Override 668 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 669 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 670 || userId == filter.owningUserId) { 671 return super.newResult(filter, match, userId); 672 } 673 return null; 674 } 675 676 @Override 677 protected BroadcastFilter[] newArray(int size) { 678 return new BroadcastFilter[size]; 679 } 680 681 @Override 682 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 683 return packageName.equals(filter.packageName); 684 } 685 }; 686 687 /** 688 * State of all active sticky broadcasts per user. Keys are the action of the 689 * sticky Intent, values are an ArrayList of all broadcasted intents with 690 * that action (which should usually be one). The SparseArray is keyed 691 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 692 * for stickies that are sent to all users. 693 */ 694 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 695 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 696 697 final ActiveServices mServices; 698 699 /** 700 * Backup/restore process management 701 */ 702 String mBackupAppName = null; 703 BackupRecord mBackupTarget = null; 704 705 final ProviderMap mProviderMap; 706 707 /** 708 * List of content providers who have clients waiting for them. The 709 * application is currently being launched and the provider will be 710 * removed from this list once it is published. 711 */ 712 final ArrayList<ContentProviderRecord> mLaunchingProviders 713 = new ArrayList<ContentProviderRecord>(); 714 715 /** 716 * File storing persisted {@link #mGrantedUriPermissions}. 717 */ 718 private final AtomicFile mGrantFile; 719 720 /** XML constants used in {@link #mGrantFile} */ 721 private static final String TAG_URI_GRANTS = "uri-grants"; 722 private static final String TAG_URI_GRANT = "uri-grant"; 723 private static final String ATTR_USER_HANDLE = "userHandle"; 724 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 725 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 726 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 727 private static final String ATTR_TARGET_PKG = "targetPkg"; 728 private static final String ATTR_URI = "uri"; 729 private static final String ATTR_MODE_FLAGS = "modeFlags"; 730 private static final String ATTR_CREATED_TIME = "createdTime"; 731 private static final String ATTR_PREFIX = "prefix"; 732 733 /** 734 * Global set of specific {@link Uri} permissions that have been granted. 735 * This optimized lookup structure maps from {@link UriPermission#targetUid} 736 * to {@link UriPermission#uri} to {@link UriPermission}. 737 */ 738 @GuardedBy("this") 739 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 740 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 741 742 public static class GrantUri { 743 public final int sourceUserId; 744 public final Uri uri; 745 public boolean prefix; 746 747 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 748 this.sourceUserId = sourceUserId; 749 this.uri = uri; 750 this.prefix = prefix; 751 } 752 753 @Override 754 public int hashCode() { 755 return toString().hashCode(); 756 } 757 758 @Override 759 public boolean equals(Object o) { 760 if (o instanceof GrantUri) { 761 GrantUri other = (GrantUri) o; 762 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 763 && prefix == other.prefix; 764 } 765 return false; 766 } 767 768 @Override 769 public String toString() { 770 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 771 if (prefix) result += " [prefix]"; 772 return result; 773 } 774 775 public String toSafeString() { 776 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 777 if (prefix) result += " [prefix]"; 778 return result; 779 } 780 781 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 782 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 783 ContentProvider.getUriWithoutUserId(uri), false); 784 } 785 } 786 787 CoreSettingsObserver mCoreSettingsObserver; 788 789 /** 790 * Thread-local storage used to carry caller permissions over through 791 * indirect content-provider access. 792 */ 793 private class Identity { 794 public int pid; 795 public int uid; 796 797 Identity(int _pid, int _uid) { 798 pid = _pid; 799 uid = _uid; 800 } 801 } 802 803 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 804 805 /** 806 * All information we have collected about the runtime performance of 807 * any user id that can impact battery performance. 808 */ 809 final BatteryStatsService mBatteryStatsService; 810 811 /** 812 * Information about component usage 813 */ 814 final UsageStatsService mUsageStatsService; 815 816 /** 817 * Information about and control over application operations 818 */ 819 final AppOpsService mAppOpsService; 820 821 /** 822 * Current configuration information. HistoryRecord objects are given 823 * a reference to this object to indicate which configuration they are 824 * currently running in, so this object must be kept immutable. 825 */ 826 Configuration mConfiguration = new Configuration(); 827 828 /** 829 * Current sequencing integer of the configuration, for skipping old 830 * configurations. 831 */ 832 int mConfigurationSeq = 0; 833 834 /** 835 * Hardware-reported OpenGLES version. 836 */ 837 final int GL_ES_VERSION; 838 839 /** 840 * List of initialization arguments to pass to all processes when binding applications to them. 841 * For example, references to the commonly used services. 842 */ 843 HashMap<String, IBinder> mAppBindArgs; 844 845 /** 846 * Temporary to avoid allocations. Protected by main lock. 847 */ 848 final StringBuilder mStringBuilder = new StringBuilder(256); 849 850 /** 851 * Used to control how we initialize the service. 852 */ 853 ComponentName mTopComponent; 854 String mTopAction = Intent.ACTION_MAIN; 855 String mTopData; 856 boolean mProcessesReady = false; 857 boolean mSystemReady = false; 858 boolean mBooting = false; 859 boolean mWaitingUpdate = false; 860 boolean mDidUpdate = false; 861 boolean mOnBattery = false; 862 boolean mLaunchWarningShown = false; 863 864 Context mContext; 865 866 int mFactoryTest; 867 868 boolean mCheckedForSetup; 869 870 /** 871 * The time at which we will allow normal application switches again, 872 * after a call to {@link #stopAppSwitches()}. 873 */ 874 long mAppSwitchesAllowedTime; 875 876 /** 877 * This is set to true after the first switch after mAppSwitchesAllowedTime 878 * is set; any switches after that will clear the time. 879 */ 880 boolean mDidAppSwitch; 881 882 /** 883 * Last time (in realtime) at which we checked for power usage. 884 */ 885 long mLastPowerCheckRealtime; 886 887 /** 888 * Last time (in uptime) at which we checked for power usage. 889 */ 890 long mLastPowerCheckUptime; 891 892 /** 893 * Set while we are wanting to sleep, to prevent any 894 * activities from being started/resumed. 895 */ 896 private boolean mSleeping = false; 897 898 /** 899 * Set while we are running a voice interaction. This overrides 900 * sleeping while it is active. 901 */ 902 private boolean mRunningVoice = false; 903 904 /** 905 * State of external calls telling us if the device is asleep. 906 */ 907 private boolean mWentToSleep = false; 908 909 /** 910 * State of external call telling us if the lock screen is shown. 911 */ 912 private boolean mLockScreenShown = false; 913 914 /** 915 * Set if we are shutting down the system, similar to sleeping. 916 */ 917 boolean mShuttingDown = false; 918 919 /** 920 * Current sequence id for oom_adj computation traversal. 921 */ 922 int mAdjSeq = 0; 923 924 /** 925 * Current sequence id for process LRU updating. 926 */ 927 int mLruSeq = 0; 928 929 /** 930 * Keep track of the non-cached/empty process we last found, to help 931 * determine how to distribute cached/empty processes next time. 932 */ 933 int mNumNonCachedProcs = 0; 934 935 /** 936 * Keep track of the number of cached hidden procs, to balance oom adj 937 * distribution between those and empty procs. 938 */ 939 int mNumCachedHiddenProcs = 0; 940 941 /** 942 * Keep track of the number of service processes we last found, to 943 * determine on the next iteration which should be B services. 944 */ 945 int mNumServiceProcs = 0; 946 int mNewNumAServiceProcs = 0; 947 int mNewNumServiceProcs = 0; 948 949 /** 950 * Allow the current computed overall memory level of the system to go down? 951 * This is set to false when we are killing processes for reasons other than 952 * memory management, so that the now smaller process list will not be taken as 953 * an indication that memory is tighter. 954 */ 955 boolean mAllowLowerMemLevel = false; 956 957 /** 958 * The last computed memory level, for holding when we are in a state that 959 * processes are going away for other reasons. 960 */ 961 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 962 963 /** 964 * The last total number of process we have, to determine if changes actually look 965 * like a shrinking number of process due to lower RAM. 966 */ 967 int mLastNumProcesses; 968 969 /** 970 * The uptime of the last time we performed idle maintenance. 971 */ 972 long mLastIdleTime = SystemClock.uptimeMillis(); 973 974 /** 975 * Total time spent with RAM that has been added in the past since the last idle time. 976 */ 977 long mLowRamTimeSinceLastIdle = 0; 978 979 /** 980 * If RAM is currently low, when that horrible situation started. 981 */ 982 long mLowRamStartTime = 0; 983 984 /** 985 * For reporting to battery stats the current top application. 986 */ 987 private String mCurResumedPackage = null; 988 private int mCurResumedUid = -1; 989 990 /** 991 * For reporting to battery stats the apps currently running foreground 992 * service. The ProcessMap is package/uid tuples; each of these contain 993 * an array of the currently foreground processes. 994 */ 995 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 996 = new ProcessMap<ArrayList<ProcessRecord>>(); 997 998 /** 999 * This is set if we had to do a delayed dexopt of an app before launching 1000 * it, to increase the ANR timeouts in that case. 1001 */ 1002 boolean mDidDexOpt; 1003 1004 /** 1005 * Set if the systemServer made a call to enterSafeMode. 1006 */ 1007 boolean mSafeMode; 1008 1009 String mDebugApp = null; 1010 boolean mWaitForDebugger = false; 1011 boolean mDebugTransient = false; 1012 String mOrigDebugApp = null; 1013 boolean mOrigWaitForDebugger = false; 1014 boolean mAlwaysFinishActivities = false; 1015 IActivityController mController = null; 1016 String mProfileApp = null; 1017 ProcessRecord mProfileProc = null; 1018 String mProfileFile; 1019 ParcelFileDescriptor mProfileFd; 1020 int mProfileType = 0; 1021 boolean mAutoStopProfiler = false; 1022 String mOpenGlTraceApp = null; 1023 1024 static class ProcessChangeItem { 1025 static final int CHANGE_ACTIVITIES = 1<<0; 1026 static final int CHANGE_PROCESS_STATE = 1<<1; 1027 int changes; 1028 int uid; 1029 int pid; 1030 int processState; 1031 boolean foregroundActivities; 1032 } 1033 1034 final RemoteCallbackList<IProcessObserver> mProcessObservers 1035 = new RemoteCallbackList<IProcessObserver>(); 1036 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1037 1038 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1039 = new ArrayList<ProcessChangeItem>(); 1040 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1041 = new ArrayList<ProcessChangeItem>(); 1042 1043 /** 1044 * Runtime CPU use collection thread. This object's lock is used to 1045 * protect all related state. 1046 */ 1047 final Thread mProcessCpuThread; 1048 1049 /** 1050 * Used to collect process stats when showing not responding dialog. 1051 * Protected by mProcessCpuThread. 1052 */ 1053 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1054 MONITOR_THREAD_CPU_USAGE); 1055 final AtomicLong mLastCpuTime = new AtomicLong(0); 1056 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1057 1058 long mLastWriteTime = 0; 1059 1060 /** 1061 * Used to retain an update lock when the foreground activity is in 1062 * immersive mode. 1063 */ 1064 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1065 1066 /** 1067 * Set to true after the system has finished booting. 1068 */ 1069 boolean mBooted = false; 1070 1071 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1072 int mProcessLimitOverride = -1; 1073 1074 WindowManagerService mWindowManager; 1075 1076 final ActivityThread mSystemThread; 1077 1078 int mCurrentUserId = 0; 1079 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1080 private UserManagerService mUserManager; 1081 1082 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1083 final ProcessRecord mApp; 1084 final int mPid; 1085 final IApplicationThread mAppThread; 1086 1087 AppDeathRecipient(ProcessRecord app, int pid, 1088 IApplicationThread thread) { 1089 if (localLOGV) Slog.v( 1090 TAG, "New death recipient " + this 1091 + " for thread " + thread.asBinder()); 1092 mApp = app; 1093 mPid = pid; 1094 mAppThread = thread; 1095 } 1096 1097 @Override 1098 public void binderDied() { 1099 if (localLOGV) Slog.v( 1100 TAG, "Death received in " + this 1101 + " for thread " + mAppThread.asBinder()); 1102 synchronized(ActivityManagerService.this) { 1103 appDiedLocked(mApp, mPid, mAppThread); 1104 } 1105 } 1106 } 1107 1108 static final int SHOW_ERROR_MSG = 1; 1109 static final int SHOW_NOT_RESPONDING_MSG = 2; 1110 static final int SHOW_FACTORY_ERROR_MSG = 3; 1111 static final int UPDATE_CONFIGURATION_MSG = 4; 1112 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1113 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1114 static final int SERVICE_TIMEOUT_MSG = 12; 1115 static final int UPDATE_TIME_ZONE = 13; 1116 static final int SHOW_UID_ERROR_MSG = 14; 1117 static final int IM_FEELING_LUCKY_MSG = 15; 1118 static final int PROC_START_TIMEOUT_MSG = 20; 1119 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1120 static final int KILL_APPLICATION_MSG = 22; 1121 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1122 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1123 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1124 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1125 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1126 static final int CLEAR_DNS_CACHE_MSG = 28; 1127 static final int UPDATE_HTTP_PROXY_MSG = 29; 1128 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1129 static final int DISPATCH_PROCESSES_CHANGED = 31; 1130 static final int DISPATCH_PROCESS_DIED = 32; 1131 static final int REPORT_MEM_USAGE_MSG = 33; 1132 static final int REPORT_USER_SWITCH_MSG = 34; 1133 static final int CONTINUE_USER_SWITCH_MSG = 35; 1134 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1135 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1136 static final int PERSIST_URI_GRANTS_MSG = 38; 1137 static final int REQUEST_ALL_PSS_MSG = 39; 1138 static final int START_PROFILES_MSG = 40; 1139 static final int UPDATE_TIME = 41; 1140 static final int SYSTEM_USER_START_MSG = 42; 1141 static final int SYSTEM_USER_CURRENT_MSG = 43; 1142 1143 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1144 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1145 static final int FIRST_COMPAT_MODE_MSG = 300; 1146 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1147 1148 AlertDialog mUidAlert; 1149 CompatModeDialog mCompatModeDialog; 1150 long mLastMemUsageReportTime = 0; 1151 1152 /** 1153 * Flag whether the current user is a "monkey", i.e. whether 1154 * the UI is driven by a UI automation tool. 1155 */ 1156 private boolean mUserIsMonkey; 1157 1158 final ServiceThread mHandlerThread; 1159 final MainHandler mHandler; 1160 1161 final class MainHandler extends Handler { 1162 public MainHandler(Looper looper) { 1163 super(looper, null, true); 1164 } 1165 1166 @Override 1167 public void handleMessage(Message msg) { 1168 switch (msg.what) { 1169 case SHOW_ERROR_MSG: { 1170 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1171 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1172 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1173 synchronized (ActivityManagerService.this) { 1174 ProcessRecord proc = (ProcessRecord)data.get("app"); 1175 AppErrorResult res = (AppErrorResult) data.get("result"); 1176 if (proc != null && proc.crashDialog != null) { 1177 Slog.e(TAG, "App already has crash dialog: " + proc); 1178 if (res != null) { 1179 res.set(0); 1180 } 1181 return; 1182 } 1183 if (!showBackground && UserHandle.getAppId(proc.uid) 1184 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1185 && proc.pid != MY_PID) { 1186 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1187 if (res != null) { 1188 res.set(0); 1189 } 1190 return; 1191 } 1192 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1193 Dialog d = new AppErrorDialog(mContext, 1194 ActivityManagerService.this, res, proc); 1195 d.show(); 1196 proc.crashDialog = d; 1197 } else { 1198 // The device is asleep, so just pretend that the user 1199 // saw a crash dialog and hit "force quit". 1200 if (res != null) { 1201 res.set(0); 1202 } 1203 } 1204 } 1205 1206 ensureBootCompleted(); 1207 } break; 1208 case SHOW_NOT_RESPONDING_MSG: { 1209 synchronized (ActivityManagerService.this) { 1210 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1211 ProcessRecord proc = (ProcessRecord)data.get("app"); 1212 if (proc != null && proc.anrDialog != null) { 1213 Slog.e(TAG, "App already has anr dialog: " + proc); 1214 return; 1215 } 1216 1217 Intent intent = new Intent("android.intent.action.ANR"); 1218 if (!mProcessesReady) { 1219 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1220 | Intent.FLAG_RECEIVER_FOREGROUND); 1221 } 1222 broadcastIntentLocked(null, null, intent, 1223 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1224 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1225 1226 if (mShowDialogs) { 1227 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1228 mContext, proc, (ActivityRecord)data.get("activity"), 1229 msg.arg1 != 0); 1230 d.show(); 1231 proc.anrDialog = d; 1232 } else { 1233 // Just kill the app if there is no dialog to be shown. 1234 killAppAtUsersRequest(proc, null); 1235 } 1236 } 1237 1238 ensureBootCompleted(); 1239 } break; 1240 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1241 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1242 synchronized (ActivityManagerService.this) { 1243 ProcessRecord proc = (ProcessRecord) data.get("app"); 1244 if (proc == null) { 1245 Slog.e(TAG, "App not found when showing strict mode dialog."); 1246 break; 1247 } 1248 if (proc.crashDialog != null) { 1249 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1250 return; 1251 } 1252 AppErrorResult res = (AppErrorResult) data.get("result"); 1253 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1254 Dialog d = new StrictModeViolationDialog(mContext, 1255 ActivityManagerService.this, res, proc); 1256 d.show(); 1257 proc.crashDialog = d; 1258 } else { 1259 // The device is asleep, so just pretend that the user 1260 // saw a crash dialog and hit "force quit". 1261 res.set(0); 1262 } 1263 } 1264 ensureBootCompleted(); 1265 } break; 1266 case SHOW_FACTORY_ERROR_MSG: { 1267 Dialog d = new FactoryErrorDialog( 1268 mContext, msg.getData().getCharSequence("msg")); 1269 d.show(); 1270 ensureBootCompleted(); 1271 } break; 1272 case UPDATE_CONFIGURATION_MSG: { 1273 final ContentResolver resolver = mContext.getContentResolver(); 1274 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1275 } break; 1276 case GC_BACKGROUND_PROCESSES_MSG: { 1277 synchronized (ActivityManagerService.this) { 1278 performAppGcsIfAppropriateLocked(); 1279 } 1280 } break; 1281 case WAIT_FOR_DEBUGGER_MSG: { 1282 synchronized (ActivityManagerService.this) { 1283 ProcessRecord app = (ProcessRecord)msg.obj; 1284 if (msg.arg1 != 0) { 1285 if (!app.waitedForDebugger) { 1286 Dialog d = new AppWaitingForDebuggerDialog( 1287 ActivityManagerService.this, 1288 mContext, app); 1289 app.waitDialog = d; 1290 app.waitedForDebugger = true; 1291 d.show(); 1292 } 1293 } else { 1294 if (app.waitDialog != null) { 1295 app.waitDialog.dismiss(); 1296 app.waitDialog = null; 1297 } 1298 } 1299 } 1300 } break; 1301 case SERVICE_TIMEOUT_MSG: { 1302 if (mDidDexOpt) { 1303 mDidDexOpt = false; 1304 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1305 nmsg.obj = msg.obj; 1306 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1307 return; 1308 } 1309 mServices.serviceTimeout((ProcessRecord)msg.obj); 1310 } break; 1311 case UPDATE_TIME_ZONE: { 1312 synchronized (ActivityManagerService.this) { 1313 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1314 ProcessRecord r = mLruProcesses.get(i); 1315 if (r.thread != null) { 1316 try { 1317 r.thread.updateTimeZone(); 1318 } catch (RemoteException ex) { 1319 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1320 } 1321 } 1322 } 1323 } 1324 } break; 1325 case CLEAR_DNS_CACHE_MSG: { 1326 synchronized (ActivityManagerService.this) { 1327 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1328 ProcessRecord r = mLruProcesses.get(i); 1329 if (r.thread != null) { 1330 try { 1331 r.thread.clearDnsCache(); 1332 } catch (RemoteException ex) { 1333 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1334 } 1335 } 1336 } 1337 } 1338 } break; 1339 case UPDATE_HTTP_PROXY_MSG: { 1340 ProxyInfo proxy = (ProxyInfo)msg.obj; 1341 String host = ""; 1342 String port = ""; 1343 String exclList = ""; 1344 String pacFileUrl = null; 1345 if (proxy != null) { 1346 host = proxy.getHost(); 1347 port = Integer.toString(proxy.getPort()); 1348 exclList = proxy.getExclusionListAsString(); 1349 pacFileUrl = proxy.getPacFileUrl().toString(); 1350 } 1351 synchronized (ActivityManagerService.this) { 1352 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1353 ProcessRecord r = mLruProcesses.get(i); 1354 if (r.thread != null) { 1355 try { 1356 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1357 } catch (RemoteException ex) { 1358 Slog.w(TAG, "Failed to update http proxy for: " + 1359 r.info.processName); 1360 } 1361 } 1362 } 1363 } 1364 } break; 1365 case SHOW_UID_ERROR_MSG: { 1366 String title = "System UIDs Inconsistent"; 1367 String text = "UIDs on the system are inconsistent, you need to wipe your" 1368 + " data partition or your device will be unstable."; 1369 Log.e(TAG, title + ": " + text); 1370 if (mShowDialogs) { 1371 // XXX This is a temporary dialog, no need to localize. 1372 AlertDialog d = new BaseErrorDialog(mContext); 1373 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1374 d.setCancelable(false); 1375 d.setTitle(title); 1376 d.setMessage(text); 1377 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1378 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1379 mUidAlert = d; 1380 d.show(); 1381 } 1382 } break; 1383 case IM_FEELING_LUCKY_MSG: { 1384 if (mUidAlert != null) { 1385 mUidAlert.dismiss(); 1386 mUidAlert = null; 1387 } 1388 } break; 1389 case PROC_START_TIMEOUT_MSG: { 1390 if (mDidDexOpt) { 1391 mDidDexOpt = false; 1392 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1393 nmsg.obj = msg.obj; 1394 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1395 return; 1396 } 1397 ProcessRecord app = (ProcessRecord)msg.obj; 1398 synchronized (ActivityManagerService.this) { 1399 processStartTimedOutLocked(app); 1400 } 1401 } break; 1402 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1403 synchronized (ActivityManagerService.this) { 1404 doPendingActivityLaunchesLocked(true); 1405 } 1406 } break; 1407 case KILL_APPLICATION_MSG: { 1408 synchronized (ActivityManagerService.this) { 1409 int appid = msg.arg1; 1410 boolean restart = (msg.arg2 == 1); 1411 Bundle bundle = (Bundle)msg.obj; 1412 String pkg = bundle.getString("pkg"); 1413 String reason = bundle.getString("reason"); 1414 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1415 false, UserHandle.USER_ALL, reason); 1416 } 1417 } break; 1418 case FINALIZE_PENDING_INTENT_MSG: { 1419 ((PendingIntentRecord)msg.obj).completeFinalize(); 1420 } break; 1421 case POST_HEAVY_NOTIFICATION_MSG: { 1422 INotificationManager inm = NotificationManager.getService(); 1423 if (inm == null) { 1424 return; 1425 } 1426 1427 ActivityRecord root = (ActivityRecord)msg.obj; 1428 ProcessRecord process = root.app; 1429 if (process == null) { 1430 return; 1431 } 1432 1433 try { 1434 Context context = mContext.createPackageContext(process.info.packageName, 0); 1435 String text = mContext.getString(R.string.heavy_weight_notification, 1436 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1437 Notification notification = new Notification(); 1438 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1439 notification.when = 0; 1440 notification.flags = Notification.FLAG_ONGOING_EVENT; 1441 notification.tickerText = text; 1442 notification.defaults = 0; // please be quiet 1443 notification.sound = null; 1444 notification.vibrate = null; 1445 notification.setLatestEventInfo(context, text, 1446 mContext.getText(R.string.heavy_weight_notification_detail), 1447 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1448 PendingIntent.FLAG_CANCEL_CURRENT, null, 1449 new UserHandle(root.userId))); 1450 1451 try { 1452 int[] outId = new int[1]; 1453 inm.enqueueNotificationWithTag("android", "android", null, 1454 R.string.heavy_weight_notification, 1455 notification, outId, root.userId); 1456 } catch (RuntimeException e) { 1457 Slog.w(ActivityManagerService.TAG, 1458 "Error showing notification for heavy-weight app", e); 1459 } catch (RemoteException e) { 1460 } 1461 } catch (NameNotFoundException e) { 1462 Slog.w(TAG, "Unable to create context for heavy notification", e); 1463 } 1464 } break; 1465 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1466 INotificationManager inm = NotificationManager.getService(); 1467 if (inm == null) { 1468 return; 1469 } 1470 try { 1471 inm.cancelNotificationWithTag("android", null, 1472 R.string.heavy_weight_notification, msg.arg1); 1473 } catch (RuntimeException e) { 1474 Slog.w(ActivityManagerService.TAG, 1475 "Error canceling notification for service", e); 1476 } catch (RemoteException e) { 1477 } 1478 } break; 1479 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1480 synchronized (ActivityManagerService.this) { 1481 checkExcessivePowerUsageLocked(true); 1482 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1483 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1484 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1485 } 1486 } break; 1487 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1488 synchronized (ActivityManagerService.this) { 1489 ActivityRecord ar = (ActivityRecord)msg.obj; 1490 if (mCompatModeDialog != null) { 1491 if (mCompatModeDialog.mAppInfo.packageName.equals( 1492 ar.info.applicationInfo.packageName)) { 1493 return; 1494 } 1495 mCompatModeDialog.dismiss(); 1496 mCompatModeDialog = null; 1497 } 1498 if (ar != null && false) { 1499 if (mCompatModePackages.getPackageAskCompatModeLocked( 1500 ar.packageName)) { 1501 int mode = mCompatModePackages.computeCompatModeLocked( 1502 ar.info.applicationInfo); 1503 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1504 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1505 mCompatModeDialog = new CompatModeDialog( 1506 ActivityManagerService.this, mContext, 1507 ar.info.applicationInfo); 1508 mCompatModeDialog.show(); 1509 } 1510 } 1511 } 1512 } 1513 break; 1514 } 1515 case DISPATCH_PROCESSES_CHANGED: { 1516 dispatchProcessesChanged(); 1517 break; 1518 } 1519 case DISPATCH_PROCESS_DIED: { 1520 final int pid = msg.arg1; 1521 final int uid = msg.arg2; 1522 dispatchProcessDied(pid, uid); 1523 break; 1524 } 1525 case REPORT_MEM_USAGE_MSG: { 1526 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1527 Thread thread = new Thread() { 1528 @Override public void run() { 1529 final SparseArray<ProcessMemInfo> infoMap 1530 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1531 for (int i=0, N=memInfos.size(); i<N; i++) { 1532 ProcessMemInfo mi = memInfos.get(i); 1533 infoMap.put(mi.pid, mi); 1534 } 1535 updateCpuStatsNow(); 1536 synchronized (mProcessCpuThread) { 1537 final int N = mProcessCpuTracker.countStats(); 1538 for (int i=0; i<N; i++) { 1539 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1540 if (st.vsize > 0) { 1541 long pss = Debug.getPss(st.pid, null); 1542 if (pss > 0) { 1543 if (infoMap.indexOfKey(st.pid) < 0) { 1544 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1545 ProcessList.NATIVE_ADJ, -1, "native", null); 1546 mi.pss = pss; 1547 memInfos.add(mi); 1548 } 1549 } 1550 } 1551 } 1552 } 1553 1554 long totalPss = 0; 1555 for (int i=0, N=memInfos.size(); i<N; i++) { 1556 ProcessMemInfo mi = memInfos.get(i); 1557 if (mi.pss == 0) { 1558 mi.pss = Debug.getPss(mi.pid, null); 1559 } 1560 totalPss += mi.pss; 1561 } 1562 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1563 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1564 if (lhs.oomAdj != rhs.oomAdj) { 1565 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1566 } 1567 if (lhs.pss != rhs.pss) { 1568 return lhs.pss < rhs.pss ? 1 : -1; 1569 } 1570 return 0; 1571 } 1572 }); 1573 1574 StringBuilder tag = new StringBuilder(128); 1575 StringBuilder stack = new StringBuilder(128); 1576 tag.append("Low on memory -- "); 1577 appendMemBucket(tag, totalPss, "total", false); 1578 appendMemBucket(stack, totalPss, "total", true); 1579 1580 StringBuilder logBuilder = new StringBuilder(1024); 1581 logBuilder.append("Low on memory:\n"); 1582 1583 boolean firstLine = true; 1584 int lastOomAdj = Integer.MIN_VALUE; 1585 for (int i=0, N=memInfos.size(); i<N; i++) { 1586 ProcessMemInfo mi = memInfos.get(i); 1587 1588 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1589 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1590 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1591 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1592 if (lastOomAdj != mi.oomAdj) { 1593 lastOomAdj = mi.oomAdj; 1594 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1595 tag.append(" / "); 1596 } 1597 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1598 if (firstLine) { 1599 stack.append(":"); 1600 firstLine = false; 1601 } 1602 stack.append("\n\t at "); 1603 } else { 1604 stack.append("$"); 1605 } 1606 } else { 1607 tag.append(" "); 1608 stack.append("$"); 1609 } 1610 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1611 appendMemBucket(tag, mi.pss, mi.name, false); 1612 } 1613 appendMemBucket(stack, mi.pss, mi.name, true); 1614 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1615 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1616 stack.append("("); 1617 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1618 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1619 stack.append(DUMP_MEM_OOM_LABEL[k]); 1620 stack.append(":"); 1621 stack.append(DUMP_MEM_OOM_ADJ[k]); 1622 } 1623 } 1624 stack.append(")"); 1625 } 1626 } 1627 1628 logBuilder.append(" "); 1629 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1630 logBuilder.append(' '); 1631 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1632 logBuilder.append(' '); 1633 ProcessList.appendRamKb(logBuilder, mi.pss); 1634 logBuilder.append(" kB: "); 1635 logBuilder.append(mi.name); 1636 logBuilder.append(" ("); 1637 logBuilder.append(mi.pid); 1638 logBuilder.append(") "); 1639 logBuilder.append(mi.adjType); 1640 logBuilder.append('\n'); 1641 if (mi.adjReason != null) { 1642 logBuilder.append(" "); 1643 logBuilder.append(mi.adjReason); 1644 logBuilder.append('\n'); 1645 } 1646 } 1647 1648 logBuilder.append(" "); 1649 ProcessList.appendRamKb(logBuilder, totalPss); 1650 logBuilder.append(" kB: TOTAL\n"); 1651 1652 long[] infos = new long[Debug.MEMINFO_COUNT]; 1653 Debug.getMemInfo(infos); 1654 logBuilder.append(" MemInfo: "); 1655 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1656 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1657 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1658 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1659 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1660 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1661 logBuilder.append(" ZRAM: "); 1662 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1663 logBuilder.append(" kB RAM, "); 1664 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1665 logBuilder.append(" kB swap total, "); 1666 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1667 logBuilder.append(" kB swap free\n"); 1668 } 1669 Slog.i(TAG, logBuilder.toString()); 1670 1671 StringBuilder dropBuilder = new StringBuilder(1024); 1672 /* 1673 StringWriter oomSw = new StringWriter(); 1674 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1675 StringWriter catSw = new StringWriter(); 1676 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1677 String[] emptyArgs = new String[] { }; 1678 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1679 oomPw.flush(); 1680 String oomString = oomSw.toString(); 1681 */ 1682 dropBuilder.append(stack); 1683 dropBuilder.append('\n'); 1684 dropBuilder.append('\n'); 1685 dropBuilder.append(logBuilder); 1686 dropBuilder.append('\n'); 1687 /* 1688 dropBuilder.append(oomString); 1689 dropBuilder.append('\n'); 1690 */ 1691 StringWriter catSw = new StringWriter(); 1692 synchronized (ActivityManagerService.this) { 1693 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1694 String[] emptyArgs = new String[] { }; 1695 catPw.println(); 1696 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1697 catPw.println(); 1698 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1699 false, false, null); 1700 catPw.println(); 1701 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1702 catPw.flush(); 1703 } 1704 dropBuilder.append(catSw.toString()); 1705 addErrorToDropBox("lowmem", null, "system_server", null, 1706 null, tag.toString(), dropBuilder.toString(), null, null); 1707 //Slog.i(TAG, "Sent to dropbox:"); 1708 //Slog.i(TAG, dropBuilder.toString()); 1709 synchronized (ActivityManagerService.this) { 1710 long now = SystemClock.uptimeMillis(); 1711 if (mLastMemUsageReportTime < now) { 1712 mLastMemUsageReportTime = now; 1713 } 1714 } 1715 } 1716 }; 1717 thread.start(); 1718 break; 1719 } 1720 case REPORT_USER_SWITCH_MSG: { 1721 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1722 break; 1723 } 1724 case CONTINUE_USER_SWITCH_MSG: { 1725 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1726 break; 1727 } 1728 case USER_SWITCH_TIMEOUT_MSG: { 1729 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1730 break; 1731 } 1732 case IMMERSIVE_MODE_LOCK_MSG: { 1733 final boolean nextState = (msg.arg1 != 0); 1734 if (mUpdateLock.isHeld() != nextState) { 1735 if (DEBUG_IMMERSIVE) { 1736 final ActivityRecord r = (ActivityRecord) msg.obj; 1737 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1738 } 1739 if (nextState) { 1740 mUpdateLock.acquire(); 1741 } else { 1742 mUpdateLock.release(); 1743 } 1744 } 1745 break; 1746 } 1747 case PERSIST_URI_GRANTS_MSG: { 1748 writeGrantedUriPermissions(); 1749 break; 1750 } 1751 case REQUEST_ALL_PSS_MSG: { 1752 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1753 break; 1754 } 1755 case START_PROFILES_MSG: { 1756 synchronized (ActivityManagerService.this) { 1757 startProfilesLocked(); 1758 } 1759 break; 1760 } 1761 case UPDATE_TIME: { 1762 synchronized (ActivityManagerService.this) { 1763 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1764 ProcessRecord r = mLruProcesses.get(i); 1765 if (r.thread != null) { 1766 try { 1767 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1768 } catch (RemoteException ex) { 1769 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1770 } 1771 } 1772 } 1773 } 1774 break; 1775 } 1776 case SYSTEM_USER_START_MSG: { 1777 mSystemServiceManager.startUser(msg.arg1); 1778 break; 1779 } 1780 case SYSTEM_USER_CURRENT_MSG: { 1781 mSystemServiceManager.switchUser(msg.arg1); 1782 break; 1783 } 1784 } 1785 } 1786 }; 1787 1788 static final int COLLECT_PSS_BG_MSG = 1; 1789 1790 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1791 @Override 1792 public void handleMessage(Message msg) { 1793 switch (msg.what) { 1794 case COLLECT_PSS_BG_MSG: { 1795 int i=0, num=0; 1796 long start = SystemClock.uptimeMillis(); 1797 long[] tmp = new long[1]; 1798 do { 1799 ProcessRecord proc; 1800 int procState; 1801 int pid; 1802 synchronized (ActivityManagerService.this) { 1803 if (i >= mPendingPssProcesses.size()) { 1804 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1805 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1806 mPendingPssProcesses.clear(); 1807 return; 1808 } 1809 proc = mPendingPssProcesses.get(i); 1810 procState = proc.pssProcState; 1811 if (proc.thread != null && procState == proc.setProcState) { 1812 pid = proc.pid; 1813 } else { 1814 proc = null; 1815 pid = 0; 1816 } 1817 i++; 1818 } 1819 if (proc != null) { 1820 long pss = Debug.getPss(pid, tmp); 1821 synchronized (ActivityManagerService.this) { 1822 if (proc.thread != null && proc.setProcState == procState 1823 && proc.pid == pid) { 1824 num++; 1825 proc.lastPssTime = SystemClock.uptimeMillis(); 1826 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1827 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1828 + ": " + pss + " lastPss=" + proc.lastPss 1829 + " state=" + ProcessList.makeProcStateString(procState)); 1830 if (proc.initialIdlePss == 0) { 1831 proc.initialIdlePss = pss; 1832 } 1833 proc.lastPss = pss; 1834 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1835 proc.lastCachedPss = pss; 1836 } 1837 } 1838 } 1839 } 1840 } while (true); 1841 } 1842 } 1843 } 1844 }; 1845 1846 /** 1847 * Monitor for package changes and update our internal state. 1848 */ 1849 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1850 @Override 1851 public void onPackageRemoved(String packageName, int uid) { 1852 // Remove all tasks with activities in the specified package from the list of recent tasks 1853 synchronized (ActivityManagerService.this) { 1854 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1855 TaskRecord tr = mRecentTasks.get(i); 1856 ComponentName cn = tr.intent.getComponent(); 1857 if (cn != null && cn.getPackageName().equals(packageName)) { 1858 // If the package name matches, remove the task and kill the process 1859 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1860 } 1861 } 1862 } 1863 } 1864 1865 @Override 1866 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1867 onPackageModified(packageName); 1868 return true; 1869 } 1870 1871 @Override 1872 public void onPackageModified(String packageName) { 1873 final PackageManager pm = mContext.getPackageManager(); 1874 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1875 new ArrayList<Pair<Intent, Integer>>(); 1876 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1877 // Copy the list of recent tasks so that we don't hold onto the lock on 1878 // ActivityManagerService for long periods while checking if components exist. 1879 synchronized (ActivityManagerService.this) { 1880 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1881 TaskRecord tr = mRecentTasks.get(i); 1882 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1883 } 1884 } 1885 // Check the recent tasks and filter out all tasks with components that no longer exist. 1886 Intent tmpI = new Intent(); 1887 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1888 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1889 ComponentName cn = p.first.getComponent(); 1890 if (cn != null && cn.getPackageName().equals(packageName)) { 1891 try { 1892 // Add the task to the list to remove if the component no longer exists 1893 tmpI.setComponent(cn); 1894 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1895 tasksToRemove.add(p.second); 1896 } 1897 } catch (Exception e) {} 1898 } 1899 } 1900 // Prune all the tasks with removed components from the list of recent tasks 1901 synchronized (ActivityManagerService.this) { 1902 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1903 // Remove the task but don't kill the process (since other components in that 1904 // package may still be running and in the background) 1905 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1906 } 1907 } 1908 } 1909 1910 @Override 1911 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1912 // Force stop the specified packages 1913 if (packages != null) { 1914 for (String pkg : packages) { 1915 synchronized (ActivityManagerService.this) { 1916 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1917 "finished booting")) { 1918 return true; 1919 } 1920 } 1921 } 1922 } 1923 return false; 1924 } 1925 }; 1926 1927 public void setSystemProcess() { 1928 try { 1929 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1930 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1931 ServiceManager.addService("meminfo", new MemBinder(this)); 1932 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1933 ServiceManager.addService("dbinfo", new DbBinder(this)); 1934 if (MONITOR_CPU_USAGE) { 1935 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1936 } 1937 ServiceManager.addService("permission", new PermissionController(this)); 1938 1939 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1940 "android", STOCK_PM_FLAGS); 1941 mSystemThread.installSystemApplicationInfo(info); 1942 1943 synchronized (this) { 1944 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1945 app.persistent = true; 1946 app.pid = MY_PID; 1947 app.maxAdj = ProcessList.SYSTEM_ADJ; 1948 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1949 mProcessNames.put(app.processName, app.uid, app); 1950 synchronized (mPidsSelfLocked) { 1951 mPidsSelfLocked.put(app.pid, app); 1952 } 1953 updateLruProcessLocked(app, false, null); 1954 updateOomAdjLocked(); 1955 } 1956 } catch (PackageManager.NameNotFoundException e) { 1957 throw new RuntimeException( 1958 "Unable to find android system package", e); 1959 } 1960 } 1961 1962 public void setWindowManager(WindowManagerService wm) { 1963 mWindowManager = wm; 1964 mStackSupervisor.setWindowManager(wm); 1965 } 1966 1967 public void startObservingNativeCrashes() { 1968 final NativeCrashListener ncl = new NativeCrashListener(this); 1969 ncl.start(); 1970 } 1971 1972 public IAppOpsService getAppOpsService() { 1973 return mAppOpsService; 1974 } 1975 1976 static class MemBinder extends Binder { 1977 ActivityManagerService mActivityManagerService; 1978 MemBinder(ActivityManagerService activityManagerService) { 1979 mActivityManagerService = activityManagerService; 1980 } 1981 1982 @Override 1983 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1984 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1985 != PackageManager.PERMISSION_GRANTED) { 1986 pw.println("Permission Denial: can't dump meminfo from from pid=" 1987 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1988 + " without permission " + android.Manifest.permission.DUMP); 1989 return; 1990 } 1991 1992 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1993 } 1994 } 1995 1996 static class GraphicsBinder extends Binder { 1997 ActivityManagerService mActivityManagerService; 1998 GraphicsBinder(ActivityManagerService activityManagerService) { 1999 mActivityManagerService = activityManagerService; 2000 } 2001 2002 @Override 2003 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2004 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2005 != PackageManager.PERMISSION_GRANTED) { 2006 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2007 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2008 + " without permission " + android.Manifest.permission.DUMP); 2009 return; 2010 } 2011 2012 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2013 } 2014 } 2015 2016 static class DbBinder extends Binder { 2017 ActivityManagerService mActivityManagerService; 2018 DbBinder(ActivityManagerService activityManagerService) { 2019 mActivityManagerService = activityManagerService; 2020 } 2021 2022 @Override 2023 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2024 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2025 != PackageManager.PERMISSION_GRANTED) { 2026 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2027 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2028 + " without permission " + android.Manifest.permission.DUMP); 2029 return; 2030 } 2031 2032 mActivityManagerService.dumpDbInfo(fd, pw, args); 2033 } 2034 } 2035 2036 static class CpuBinder extends Binder { 2037 ActivityManagerService mActivityManagerService; 2038 CpuBinder(ActivityManagerService activityManagerService) { 2039 mActivityManagerService = activityManagerService; 2040 } 2041 2042 @Override 2043 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2044 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2045 != PackageManager.PERMISSION_GRANTED) { 2046 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2047 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2048 + " without permission " + android.Manifest.permission.DUMP); 2049 return; 2050 } 2051 2052 synchronized (mActivityManagerService.mProcessCpuThread) { 2053 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2054 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2055 SystemClock.uptimeMillis())); 2056 } 2057 } 2058 } 2059 2060 public static final class Lifecycle extends SystemService { 2061 private final ActivityManagerService mService; 2062 2063 public Lifecycle(Context context) { 2064 super(context); 2065 mService = new ActivityManagerService(context); 2066 } 2067 2068 @Override 2069 public void onStart() { 2070 mService.start(); 2071 } 2072 2073 public ActivityManagerService getService() { 2074 return mService; 2075 } 2076 } 2077 2078 // Note: This method is invoked on the main thread but may need to attach various 2079 // handlers to other threads. So take care to be explicit about the looper. 2080 public ActivityManagerService(Context systemContext) { 2081 mContext = systemContext; 2082 mFactoryTest = FactoryTest.getMode(); 2083 mSystemThread = ActivityThread.currentActivityThread(); 2084 2085 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2086 2087 mHandlerThread = new ServiceThread(TAG, 2088 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2089 mHandlerThread.start(); 2090 mHandler = new MainHandler(mHandlerThread.getLooper()); 2091 2092 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2093 "foreground", BROADCAST_FG_TIMEOUT, false); 2094 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2095 "background", BROADCAST_BG_TIMEOUT, true); 2096 mBroadcastQueues[0] = mFgBroadcastQueue; 2097 mBroadcastQueues[1] = mBgBroadcastQueue; 2098 2099 mServices = new ActiveServices(this); 2100 mProviderMap = new ProviderMap(this); 2101 2102 // TODO: Move creation of battery stats service outside of activity manager service. 2103 File dataDir = Environment.getDataDirectory(); 2104 File systemDir = new File(dataDir, "system"); 2105 systemDir.mkdirs(); 2106 mBatteryStatsService = new BatteryStatsService(new File( 2107 systemDir, "batterystats.bin").toString(), mHandler); 2108 mBatteryStatsService.getActiveStatistics().readLocked(); 2109 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2110 mOnBattery = DEBUG_POWER ? true 2111 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2112 mBatteryStatsService.getActiveStatistics().setCallback(this); 2113 2114 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2115 2116 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2117 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2118 2119 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2120 2121 // User 0 is the first and only user that runs at boot. 2122 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2123 mUserLru.add(Integer.valueOf(0)); 2124 updateStartedUserArrayLocked(); 2125 2126 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2127 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2128 2129 mConfiguration.setToDefaults(); 2130 mConfiguration.setLocale(Locale.getDefault()); 2131 2132 mConfigurationSeq = mConfiguration.seq = 1; 2133 mProcessCpuTracker.init(); 2134 2135 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2136 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2137 mStackSupervisor = new ActivityStackSupervisor(this); 2138 2139 mProcessCpuThread = new Thread("CpuTracker") { 2140 @Override 2141 public void run() { 2142 while (true) { 2143 try { 2144 try { 2145 synchronized(this) { 2146 final long now = SystemClock.uptimeMillis(); 2147 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2148 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2149 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2150 // + ", write delay=" + nextWriteDelay); 2151 if (nextWriteDelay < nextCpuDelay) { 2152 nextCpuDelay = nextWriteDelay; 2153 } 2154 if (nextCpuDelay > 0) { 2155 mProcessCpuMutexFree.set(true); 2156 this.wait(nextCpuDelay); 2157 } 2158 } 2159 } catch (InterruptedException e) { 2160 } 2161 updateCpuStatsNow(); 2162 } catch (Exception e) { 2163 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2164 } 2165 } 2166 } 2167 }; 2168 2169 Watchdog.getInstance().addMonitor(this); 2170 Watchdog.getInstance().addThread(mHandler); 2171 } 2172 2173 public void setSystemServiceManager(SystemServiceManager mgr) { 2174 mSystemServiceManager = mgr; 2175 } 2176 2177 private void start() { 2178 mProcessCpuThread.start(); 2179 2180 mBatteryStatsService.publish(mContext); 2181 mUsageStatsService.publish(mContext); 2182 mAppOpsService.publish(mContext); 2183 2184 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2185 } 2186 2187 @Override 2188 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2189 throws RemoteException { 2190 if (code == SYSPROPS_TRANSACTION) { 2191 // We need to tell all apps about the system property change. 2192 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2193 synchronized(this) { 2194 final int NP = mProcessNames.getMap().size(); 2195 for (int ip=0; ip<NP; ip++) { 2196 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2197 final int NA = apps.size(); 2198 for (int ia=0; ia<NA; ia++) { 2199 ProcessRecord app = apps.valueAt(ia); 2200 if (app.thread != null) { 2201 procs.add(app.thread.asBinder()); 2202 } 2203 } 2204 } 2205 } 2206 2207 int N = procs.size(); 2208 for (int i=0; i<N; i++) { 2209 Parcel data2 = Parcel.obtain(); 2210 try { 2211 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2212 } catch (RemoteException e) { 2213 } 2214 data2.recycle(); 2215 } 2216 } 2217 try { 2218 return super.onTransact(code, data, reply, flags); 2219 } catch (RuntimeException e) { 2220 // The activity manager only throws security exceptions, so let's 2221 // log all others. 2222 if (!(e instanceof SecurityException)) { 2223 Slog.wtf(TAG, "Activity Manager Crash", e); 2224 } 2225 throw e; 2226 } 2227 } 2228 2229 void updateCpuStats() { 2230 final long now = SystemClock.uptimeMillis(); 2231 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2232 return; 2233 } 2234 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2235 synchronized (mProcessCpuThread) { 2236 mProcessCpuThread.notify(); 2237 } 2238 } 2239 } 2240 2241 void updateCpuStatsNow() { 2242 synchronized (mProcessCpuThread) { 2243 mProcessCpuMutexFree.set(false); 2244 final long now = SystemClock.uptimeMillis(); 2245 boolean haveNewCpuStats = false; 2246 2247 if (MONITOR_CPU_USAGE && 2248 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2249 mLastCpuTime.set(now); 2250 haveNewCpuStats = true; 2251 mProcessCpuTracker.update(); 2252 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2253 //Slog.i(TAG, "Total CPU usage: " 2254 // + mProcessCpu.getTotalCpuPercent() + "%"); 2255 2256 // Slog the cpu usage if the property is set. 2257 if ("true".equals(SystemProperties.get("events.cpu"))) { 2258 int user = mProcessCpuTracker.getLastUserTime(); 2259 int system = mProcessCpuTracker.getLastSystemTime(); 2260 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2261 int irq = mProcessCpuTracker.getLastIrqTime(); 2262 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2263 int idle = mProcessCpuTracker.getLastIdleTime(); 2264 2265 int total = user + system + iowait + irq + softIrq + idle; 2266 if (total == 0) total = 1; 2267 2268 EventLog.writeEvent(EventLogTags.CPU, 2269 ((user+system+iowait+irq+softIrq) * 100) / total, 2270 (user * 100) / total, 2271 (system * 100) / total, 2272 (iowait * 100) / total, 2273 (irq * 100) / total, 2274 (softIrq * 100) / total); 2275 } 2276 } 2277 2278 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2279 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2280 synchronized(bstats) { 2281 synchronized(mPidsSelfLocked) { 2282 if (haveNewCpuStats) { 2283 if (mOnBattery) { 2284 int perc = bstats.startAddingCpuLocked(); 2285 int totalUTime = 0; 2286 int totalSTime = 0; 2287 final int N = mProcessCpuTracker.countStats(); 2288 for (int i=0; i<N; i++) { 2289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2290 if (!st.working) { 2291 continue; 2292 } 2293 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2294 int otherUTime = (st.rel_utime*perc)/100; 2295 int otherSTime = (st.rel_stime*perc)/100; 2296 totalUTime += otherUTime; 2297 totalSTime += otherSTime; 2298 if (pr != null) { 2299 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2300 if (ps == null || !ps.isActive()) { 2301 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2302 pr.info.uid, pr.processName); 2303 } 2304 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2305 st.rel_stime-otherSTime); 2306 ps.addSpeedStepTimes(cpuSpeedTimes); 2307 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2308 } else { 2309 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2310 if (ps == null || !ps.isActive()) { 2311 st.batteryStats = ps = bstats.getProcessStatsLocked( 2312 bstats.mapUid(st.uid), st.name); 2313 } 2314 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2315 st.rel_stime-otherSTime); 2316 ps.addSpeedStepTimes(cpuSpeedTimes); 2317 } 2318 } 2319 bstats.finishAddingCpuLocked(perc, totalUTime, 2320 totalSTime, cpuSpeedTimes); 2321 } 2322 } 2323 } 2324 2325 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2326 mLastWriteTime = now; 2327 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2328 } 2329 } 2330 } 2331 } 2332 2333 @Override 2334 public void batteryNeedsCpuUpdate() { 2335 updateCpuStatsNow(); 2336 } 2337 2338 @Override 2339 public void batteryPowerChanged(boolean onBattery) { 2340 // When plugging in, update the CPU stats first before changing 2341 // the plug state. 2342 updateCpuStatsNow(); 2343 synchronized (this) { 2344 synchronized(mPidsSelfLocked) { 2345 mOnBattery = DEBUG_POWER ? true : onBattery; 2346 } 2347 } 2348 } 2349 2350 /** 2351 * Initialize the application bind args. These are passed to each 2352 * process when the bindApplication() IPC is sent to the process. They're 2353 * lazily setup to make sure the services are running when they're asked for. 2354 */ 2355 private HashMap<String, IBinder> getCommonServicesLocked() { 2356 if (mAppBindArgs == null) { 2357 mAppBindArgs = new HashMap<String, IBinder>(); 2358 2359 // Setup the application init args 2360 mAppBindArgs.put("package", ServiceManager.getService("package")); 2361 mAppBindArgs.put("window", ServiceManager.getService("window")); 2362 mAppBindArgs.put(Context.ALARM_SERVICE, 2363 ServiceManager.getService(Context.ALARM_SERVICE)); 2364 } 2365 return mAppBindArgs; 2366 } 2367 2368 final void setFocusedActivityLocked(ActivityRecord r) { 2369 if (mFocusedActivity != r) { 2370 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2371 mFocusedActivity = r; 2372 if (r.task != null && r.task.voiceInteractor != null) { 2373 startRunningVoiceLocked(); 2374 } else { 2375 finishRunningVoiceLocked(); 2376 } 2377 mStackSupervisor.setFocusedStack(r); 2378 if (r != null) { 2379 mWindowManager.setFocusedApp(r.appToken, true); 2380 } 2381 applyUpdateLockStateLocked(r); 2382 } 2383 } 2384 2385 final void clearFocusedActivity(ActivityRecord r) { 2386 if (mFocusedActivity == r) { 2387 mFocusedActivity = null; 2388 } 2389 } 2390 2391 @Override 2392 public void setFocusedStack(int stackId) { 2393 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2394 synchronized (ActivityManagerService.this) { 2395 ActivityStack stack = mStackSupervisor.getStack(stackId); 2396 if (stack != null) { 2397 ActivityRecord r = stack.topRunningActivityLocked(null); 2398 if (r != null) { 2399 setFocusedActivityLocked(r); 2400 } 2401 } 2402 } 2403 } 2404 2405 @Override 2406 public void notifyActivityDrawn(IBinder token) { 2407 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2408 synchronized (this) { 2409 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2410 if (r != null) { 2411 r.task.stack.notifyActivityDrawnLocked(r); 2412 } 2413 } 2414 } 2415 2416 final void applyUpdateLockStateLocked(ActivityRecord r) { 2417 // Modifications to the UpdateLock state are done on our handler, outside 2418 // the activity manager's locks. The new state is determined based on the 2419 // state *now* of the relevant activity record. The object is passed to 2420 // the handler solely for logging detail, not to be consulted/modified. 2421 final boolean nextState = r != null && r.immersive; 2422 mHandler.sendMessage( 2423 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2424 } 2425 2426 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2427 Message msg = Message.obtain(); 2428 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2429 msg.obj = r.task.askedCompatMode ? null : r; 2430 mHandler.sendMessage(msg); 2431 } 2432 2433 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2434 String what, Object obj, ProcessRecord srcApp) { 2435 app.lastActivityTime = now; 2436 2437 if (app.activities.size() > 0) { 2438 // Don't want to touch dependent processes that are hosting activities. 2439 return index; 2440 } 2441 2442 int lrui = mLruProcesses.lastIndexOf(app); 2443 if (lrui < 0) { 2444 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2445 + what + " " + obj + " from " + srcApp); 2446 return index; 2447 } 2448 2449 if (lrui >= index) { 2450 // Don't want to cause this to move dependent processes *back* in the 2451 // list as if they were less frequently used. 2452 return index; 2453 } 2454 2455 if (lrui >= mLruProcessActivityStart) { 2456 // Don't want to touch dependent processes that are hosting activities. 2457 return index; 2458 } 2459 2460 mLruProcesses.remove(lrui); 2461 if (index > 0) { 2462 index--; 2463 } 2464 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2465 + " in LRU list: " + app); 2466 mLruProcesses.add(index, app); 2467 return index; 2468 } 2469 2470 final void removeLruProcessLocked(ProcessRecord app) { 2471 int lrui = mLruProcesses.lastIndexOf(app); 2472 if (lrui >= 0) { 2473 if (lrui <= mLruProcessActivityStart) { 2474 mLruProcessActivityStart--; 2475 } 2476 if (lrui <= mLruProcessServiceStart) { 2477 mLruProcessServiceStart--; 2478 } 2479 mLruProcesses.remove(lrui); 2480 } 2481 } 2482 2483 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2484 ProcessRecord client) { 2485 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2486 || app.treatLikeActivity; 2487 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2488 if (!activityChange && hasActivity) { 2489 // The process has activities, so we are only allowing activity-based adjustments 2490 // to move it. It should be kept in the front of the list with other 2491 // processes that have activities, and we don't want those to change their 2492 // order except due to activity operations. 2493 return; 2494 } 2495 2496 mLruSeq++; 2497 final long now = SystemClock.uptimeMillis(); 2498 app.lastActivityTime = now; 2499 2500 // First a quick reject: if the app is already at the position we will 2501 // put it, then there is nothing to do. 2502 if (hasActivity) { 2503 final int N = mLruProcesses.size(); 2504 if (N > 0 && mLruProcesses.get(N-1) == app) { 2505 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2506 return; 2507 } 2508 } else { 2509 if (mLruProcessServiceStart > 0 2510 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2511 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2512 return; 2513 } 2514 } 2515 2516 int lrui = mLruProcesses.lastIndexOf(app); 2517 2518 if (app.persistent && lrui >= 0) { 2519 // We don't care about the position of persistent processes, as long as 2520 // they are in the list. 2521 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2522 return; 2523 } 2524 2525 /* In progress: compute new position first, so we can avoid doing work 2526 if the process is not actually going to move. Not yet working. 2527 int addIndex; 2528 int nextIndex; 2529 boolean inActivity = false, inService = false; 2530 if (hasActivity) { 2531 // Process has activities, put it at the very tipsy-top. 2532 addIndex = mLruProcesses.size(); 2533 nextIndex = mLruProcessServiceStart; 2534 inActivity = true; 2535 } else if (hasService) { 2536 // Process has services, put it at the top of the service list. 2537 addIndex = mLruProcessActivityStart; 2538 nextIndex = mLruProcessServiceStart; 2539 inActivity = true; 2540 inService = true; 2541 } else { 2542 // Process not otherwise of interest, it goes to the top of the non-service area. 2543 addIndex = mLruProcessServiceStart; 2544 if (client != null) { 2545 int clientIndex = mLruProcesses.lastIndexOf(client); 2546 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2547 + app); 2548 if (clientIndex >= 0 && addIndex > clientIndex) { 2549 addIndex = clientIndex; 2550 } 2551 } 2552 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2553 } 2554 2555 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2556 + mLruProcessActivityStart + "): " + app); 2557 */ 2558 2559 if (lrui >= 0) { 2560 if (lrui < mLruProcessActivityStart) { 2561 mLruProcessActivityStart--; 2562 } 2563 if (lrui < mLruProcessServiceStart) { 2564 mLruProcessServiceStart--; 2565 } 2566 /* 2567 if (addIndex > lrui) { 2568 addIndex--; 2569 } 2570 if (nextIndex > lrui) { 2571 nextIndex--; 2572 } 2573 */ 2574 mLruProcesses.remove(lrui); 2575 } 2576 2577 /* 2578 mLruProcesses.add(addIndex, app); 2579 if (inActivity) { 2580 mLruProcessActivityStart++; 2581 } 2582 if (inService) { 2583 mLruProcessActivityStart++; 2584 } 2585 */ 2586 2587 int nextIndex; 2588 if (hasActivity) { 2589 final int N = mLruProcesses.size(); 2590 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2591 // Process doesn't have activities, but has clients with 2592 // activities... move it up, but one below the top (the top 2593 // should always have a real activity). 2594 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2595 mLruProcesses.add(N-1, app); 2596 // To keep it from spamming the LRU list (by making a bunch of clients), 2597 // we will push down any other entries owned by the app. 2598 final int uid = app.info.uid; 2599 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2600 ProcessRecord subProc = mLruProcesses.get(i); 2601 if (subProc.info.uid == uid) { 2602 // We want to push this one down the list. If the process after 2603 // it is for the same uid, however, don't do so, because we don't 2604 // want them internally to be re-ordered. 2605 if (mLruProcesses.get(i-1).info.uid != uid) { 2606 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2607 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2608 ProcessRecord tmp = mLruProcesses.get(i); 2609 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2610 mLruProcesses.set(i-1, tmp); 2611 i--; 2612 } 2613 } else { 2614 // A gap, we can stop here. 2615 break; 2616 } 2617 } 2618 } else { 2619 // Process has activities, put it at the very tipsy-top. 2620 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2621 mLruProcesses.add(app); 2622 } 2623 nextIndex = mLruProcessServiceStart; 2624 } else if (hasService) { 2625 // Process has services, put it at the top of the service list. 2626 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2627 mLruProcesses.add(mLruProcessActivityStart, app); 2628 nextIndex = mLruProcessServiceStart; 2629 mLruProcessActivityStart++; 2630 } else { 2631 // Process not otherwise of interest, it goes to the top of the non-service area. 2632 int index = mLruProcessServiceStart; 2633 if (client != null) { 2634 // If there is a client, don't allow the process to be moved up higher 2635 // in the list than that client. 2636 int clientIndex = mLruProcesses.lastIndexOf(client); 2637 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2638 + " when updating " + app); 2639 if (clientIndex <= lrui) { 2640 // Don't allow the client index restriction to push it down farther in the 2641 // list than it already is. 2642 clientIndex = lrui; 2643 } 2644 if (clientIndex >= 0 && index > clientIndex) { 2645 index = clientIndex; 2646 } 2647 } 2648 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2649 mLruProcesses.add(index, app); 2650 nextIndex = index-1; 2651 mLruProcessActivityStart++; 2652 mLruProcessServiceStart++; 2653 } 2654 2655 // If the app is currently using a content provider or service, 2656 // bump those processes as well. 2657 for (int j=app.connections.size()-1; j>=0; j--) { 2658 ConnectionRecord cr = app.connections.valueAt(j); 2659 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2660 && cr.binding.service.app != null 2661 && cr.binding.service.app.lruSeq != mLruSeq 2662 && !cr.binding.service.app.persistent) { 2663 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2664 "service connection", cr, app); 2665 } 2666 } 2667 for (int j=app.conProviders.size()-1; j>=0; j--) { 2668 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2669 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2670 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2671 "provider reference", cpr, app); 2672 } 2673 } 2674 } 2675 2676 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2677 if (uid == Process.SYSTEM_UID) { 2678 // The system gets to run in any process. If there are multiple 2679 // processes with the same uid, just pick the first (this 2680 // should never happen). 2681 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2682 if (procs == null) return null; 2683 final int N = procs.size(); 2684 for (int i = 0; i < N; i++) { 2685 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2686 } 2687 } 2688 ProcessRecord proc = mProcessNames.get(processName, uid); 2689 if (false && proc != null && !keepIfLarge 2690 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2691 && proc.lastCachedPss >= 4000) { 2692 // Turn this condition on to cause killing to happen regularly, for testing. 2693 if (proc.baseProcessTracker != null) { 2694 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2695 } 2696 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2697 + "k from cached"); 2698 } else if (proc != null && !keepIfLarge 2699 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2700 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2701 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2702 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2703 if (proc.baseProcessTracker != null) { 2704 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2705 } 2706 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2707 + "k from cached"); 2708 } 2709 } 2710 return proc; 2711 } 2712 2713 void ensurePackageDexOpt(String packageName) { 2714 IPackageManager pm = AppGlobals.getPackageManager(); 2715 try { 2716 if (pm.performDexOpt(packageName)) { 2717 mDidDexOpt = true; 2718 } 2719 } catch (RemoteException e) { 2720 } 2721 } 2722 2723 boolean isNextTransitionForward() { 2724 int transit = mWindowManager.getPendingAppTransition(); 2725 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2726 || transit == AppTransition.TRANSIT_TASK_OPEN 2727 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2728 } 2729 2730 final ProcessRecord startProcessLocked(String processName, 2731 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2732 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2733 boolean isolated, boolean keepIfLarge) { 2734 ProcessRecord app; 2735 if (!isolated) { 2736 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2737 } else { 2738 // If this is an isolated process, it can't re-use an existing process. 2739 app = null; 2740 } 2741 // We don't have to do anything more if: 2742 // (1) There is an existing application record; and 2743 // (2) The caller doesn't think it is dead, OR there is no thread 2744 // object attached to it so we know it couldn't have crashed; and 2745 // (3) There is a pid assigned to it, so it is either starting or 2746 // already running. 2747 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2748 + " app=" + app + " knownToBeDead=" + knownToBeDead 2749 + " thread=" + (app != null ? app.thread : null) 2750 + " pid=" + (app != null ? app.pid : -1)); 2751 if (app != null && app.pid > 0) { 2752 if (!knownToBeDead || app.thread == null) { 2753 // We already have the app running, or are waiting for it to 2754 // come up (we have a pid but not yet its thread), so keep it. 2755 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2756 // If this is a new package in the process, add the package to the list 2757 app.addPackage(info.packageName, mProcessStats); 2758 return app; 2759 } 2760 2761 // An application record is attached to a previous process, 2762 // clean it up now. 2763 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2764 handleAppDiedLocked(app, true, true); 2765 } 2766 2767 String hostingNameStr = hostingName != null 2768 ? hostingName.flattenToShortString() : null; 2769 2770 if (!isolated) { 2771 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2772 // If we are in the background, then check to see if this process 2773 // is bad. If so, we will just silently fail. 2774 if (mBadProcesses.get(info.processName, info.uid) != null) { 2775 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2776 + "/" + info.processName); 2777 return null; 2778 } 2779 } else { 2780 // When the user is explicitly starting a process, then clear its 2781 // crash count so that we won't make it bad until they see at 2782 // least one crash dialog again, and make the process good again 2783 // if it had been bad. 2784 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2785 + "/" + info.processName); 2786 mProcessCrashTimes.remove(info.processName, info.uid); 2787 if (mBadProcesses.get(info.processName, info.uid) != null) { 2788 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2789 UserHandle.getUserId(info.uid), info.uid, 2790 info.processName); 2791 mBadProcesses.remove(info.processName, info.uid); 2792 if (app != null) { 2793 app.bad = false; 2794 } 2795 } 2796 } 2797 } 2798 2799 if (app == null) { 2800 app = newProcessRecordLocked(info, processName, isolated); 2801 if (app == null) { 2802 Slog.w(TAG, "Failed making new process record for " 2803 + processName + "/" + info.uid + " isolated=" + isolated); 2804 return null; 2805 } 2806 mProcessNames.put(processName, app.uid, app); 2807 if (isolated) { 2808 mIsolatedProcesses.put(app.uid, app); 2809 } 2810 } else { 2811 // If this is a new package in the process, add the package to the list 2812 app.addPackage(info.packageName, mProcessStats); 2813 } 2814 2815 // If the system is not ready yet, then hold off on starting this 2816 // process until it is. 2817 if (!mProcessesReady 2818 && !isAllowedWhileBooting(info) 2819 && !allowWhileBooting) { 2820 if (!mProcessesOnHold.contains(app)) { 2821 mProcessesOnHold.add(app); 2822 } 2823 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2824 return app; 2825 } 2826 2827 startProcessLocked(app, hostingType, hostingNameStr); 2828 return (app.pid != 0) ? app : null; 2829 } 2830 2831 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2832 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2833 } 2834 2835 private final void startProcessLocked(ProcessRecord app, 2836 String hostingType, String hostingNameStr) { 2837 if (app.pid > 0 && app.pid != MY_PID) { 2838 synchronized (mPidsSelfLocked) { 2839 mPidsSelfLocked.remove(app.pid); 2840 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2841 } 2842 app.setPid(0); 2843 } 2844 2845 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2846 "startProcessLocked removing on hold: " + app); 2847 mProcessesOnHold.remove(app); 2848 2849 updateCpuStats(); 2850 2851 try { 2852 int uid = app.uid; 2853 2854 int[] gids = null; 2855 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2856 if (!app.isolated) { 2857 int[] permGids = null; 2858 try { 2859 final PackageManager pm = mContext.getPackageManager(); 2860 permGids = pm.getPackageGids(app.info.packageName); 2861 2862 if (Environment.isExternalStorageEmulated()) { 2863 if (pm.checkPermission( 2864 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2865 app.info.packageName) == PERMISSION_GRANTED) { 2866 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2867 } else { 2868 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2869 } 2870 } 2871 } catch (PackageManager.NameNotFoundException e) { 2872 Slog.w(TAG, "Unable to retrieve gids", e); 2873 } 2874 2875 /* 2876 * Add shared application GID so applications can share some 2877 * resources like shared libraries 2878 */ 2879 if (permGids == null) { 2880 gids = new int[1]; 2881 } else { 2882 gids = new int[permGids.length + 1]; 2883 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2884 } 2885 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2886 } 2887 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2888 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2889 && mTopComponent != null 2890 && app.processName.equals(mTopComponent.getPackageName())) { 2891 uid = 0; 2892 } 2893 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2894 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2895 uid = 0; 2896 } 2897 } 2898 int debugFlags = 0; 2899 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2900 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2901 // Also turn on CheckJNI for debuggable apps. It's quite 2902 // awkward to turn on otherwise. 2903 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2904 } 2905 // Run the app in safe mode if its manifest requests so or the 2906 // system is booted in safe mode. 2907 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2908 mSafeMode == true) { 2909 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2910 } 2911 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2912 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2913 } 2914 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2915 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2916 } 2917 if ("1".equals(SystemProperties.get("debug.assert"))) { 2918 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2919 } 2920 2921 String requiredAbi = app.info.requiredCpuAbi; 2922 if (requiredAbi == null) { 2923 requiredAbi = Build.SUPPORTED_ABIS[0]; 2924 } 2925 2926 // Start the process. It will either succeed and return a result containing 2927 // the PID of the new process, or else throw a RuntimeException. 2928 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2929 app.processName, uid, uid, gids, debugFlags, mountExternal, 2930 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2931 2932 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2933 synchronized (bs) { 2934 if (bs.isOnBattery()) { 2935 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2936 } 2937 } 2938 2939 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2940 UserHandle.getUserId(uid), startResult.pid, uid, 2941 app.processName, hostingType, 2942 hostingNameStr != null ? hostingNameStr : ""); 2943 2944 if (app.persistent) { 2945 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2946 } 2947 2948 StringBuilder buf = mStringBuilder; 2949 buf.setLength(0); 2950 buf.append("Start proc "); 2951 buf.append(app.processName); 2952 buf.append(" for "); 2953 buf.append(hostingType); 2954 if (hostingNameStr != null) { 2955 buf.append(" "); 2956 buf.append(hostingNameStr); 2957 } 2958 buf.append(": pid="); 2959 buf.append(startResult.pid); 2960 buf.append(" uid="); 2961 buf.append(uid); 2962 buf.append(" gids={"); 2963 if (gids != null) { 2964 for (int gi=0; gi<gids.length; gi++) { 2965 if (gi != 0) buf.append(", "); 2966 buf.append(gids[gi]); 2967 2968 } 2969 } 2970 buf.append("}"); 2971 Slog.i(TAG, buf.toString()); 2972 app.setPid(startResult.pid); 2973 app.usingWrapper = startResult.usingWrapper; 2974 app.removed = false; 2975 synchronized (mPidsSelfLocked) { 2976 this.mPidsSelfLocked.put(startResult.pid, app); 2977 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2978 msg.obj = app; 2979 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2980 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2981 } 2982 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2983 app.processName, app.info.uid); 2984 if (app.isolated) { 2985 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2986 } 2987 } catch (RuntimeException e) { 2988 // XXX do better error recovery. 2989 app.setPid(0); 2990 Slog.e(TAG, "Failure starting process " + app.processName, e); 2991 } 2992 } 2993 2994 void updateUsageStats(ActivityRecord component, boolean resumed) { 2995 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2996 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2997 if (resumed) { 2998 mUsageStatsService.noteResumeComponent(component.realActivity); 2999 synchronized (stats) { 3000 stats.noteActivityResumedLocked(component.app.uid); 3001 } 3002 } else { 3003 mUsageStatsService.notePauseComponent(component.realActivity); 3004 synchronized (stats) { 3005 stats.noteActivityPausedLocked(component.app.uid); 3006 } 3007 } 3008 } 3009 3010 Intent getHomeIntent() { 3011 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3012 intent.setComponent(mTopComponent); 3013 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3014 intent.addCategory(Intent.CATEGORY_HOME); 3015 } 3016 return intent; 3017 } 3018 3019 boolean startHomeActivityLocked(int userId) { 3020 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3021 && mTopAction == null) { 3022 // We are running in factory test mode, but unable to find 3023 // the factory test app, so just sit around displaying the 3024 // error message and don't try to start anything. 3025 return false; 3026 } 3027 Intent intent = getHomeIntent(); 3028 ActivityInfo aInfo = 3029 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3030 if (aInfo != null) { 3031 intent.setComponent(new ComponentName( 3032 aInfo.applicationInfo.packageName, aInfo.name)); 3033 // Don't do this if the home app is currently being 3034 // instrumented. 3035 aInfo = new ActivityInfo(aInfo); 3036 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3037 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3038 aInfo.applicationInfo.uid, true); 3039 if (app == null || app.instrumentationClass == null) { 3040 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3041 mStackSupervisor.startHomeActivity(intent, aInfo); 3042 } 3043 } 3044 3045 return true; 3046 } 3047 3048 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3049 ActivityInfo ai = null; 3050 ComponentName comp = intent.getComponent(); 3051 try { 3052 if (comp != null) { 3053 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3054 } else { 3055 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3056 intent, 3057 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3058 flags, userId); 3059 3060 if (info != null) { 3061 ai = info.activityInfo; 3062 } 3063 } 3064 } catch (RemoteException e) { 3065 // ignore 3066 } 3067 3068 return ai; 3069 } 3070 3071 /** 3072 * Starts the "new version setup screen" if appropriate. 3073 */ 3074 void startSetupActivityLocked() { 3075 // Only do this once per boot. 3076 if (mCheckedForSetup) { 3077 return; 3078 } 3079 3080 // We will show this screen if the current one is a different 3081 // version than the last one shown, and we are not running in 3082 // low-level factory test mode. 3083 final ContentResolver resolver = mContext.getContentResolver(); 3084 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3085 Settings.Global.getInt(resolver, 3086 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3087 mCheckedForSetup = true; 3088 3089 // See if we should be showing the platform update setup UI. 3090 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3091 List<ResolveInfo> ris = mContext.getPackageManager() 3092 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3093 3094 // We don't allow third party apps to replace this. 3095 ResolveInfo ri = null; 3096 for (int i=0; ris != null && i<ris.size(); i++) { 3097 if ((ris.get(i).activityInfo.applicationInfo.flags 3098 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3099 ri = ris.get(i); 3100 break; 3101 } 3102 } 3103 3104 if (ri != null) { 3105 String vers = ri.activityInfo.metaData != null 3106 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3107 : null; 3108 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3109 vers = ri.activityInfo.applicationInfo.metaData.getString( 3110 Intent.METADATA_SETUP_VERSION); 3111 } 3112 String lastVers = Settings.Secure.getString( 3113 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3114 if (vers != null && !vers.equals(lastVers)) { 3115 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3116 intent.setComponent(new ComponentName( 3117 ri.activityInfo.packageName, ri.activityInfo.name)); 3118 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3119 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3120 } 3121 } 3122 } 3123 } 3124 3125 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3126 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3127 } 3128 3129 void enforceNotIsolatedCaller(String caller) { 3130 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3131 throw new SecurityException("Isolated process not allowed to call " + caller); 3132 } 3133 } 3134 3135 @Override 3136 public int getFrontActivityScreenCompatMode() { 3137 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3138 synchronized (this) { 3139 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3140 } 3141 } 3142 3143 @Override 3144 public void setFrontActivityScreenCompatMode(int mode) { 3145 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3146 "setFrontActivityScreenCompatMode"); 3147 synchronized (this) { 3148 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3149 } 3150 } 3151 3152 @Override 3153 public int getPackageScreenCompatMode(String packageName) { 3154 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3155 synchronized (this) { 3156 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3157 } 3158 } 3159 3160 @Override 3161 public void setPackageScreenCompatMode(String packageName, int mode) { 3162 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3163 "setPackageScreenCompatMode"); 3164 synchronized (this) { 3165 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3166 } 3167 } 3168 3169 @Override 3170 public boolean getPackageAskScreenCompat(String packageName) { 3171 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3172 synchronized (this) { 3173 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3174 } 3175 } 3176 3177 @Override 3178 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3179 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3180 "setPackageAskScreenCompat"); 3181 synchronized (this) { 3182 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3183 } 3184 } 3185 3186 private void dispatchProcessesChanged() { 3187 int N; 3188 synchronized (this) { 3189 N = mPendingProcessChanges.size(); 3190 if (mActiveProcessChanges.length < N) { 3191 mActiveProcessChanges = new ProcessChangeItem[N]; 3192 } 3193 mPendingProcessChanges.toArray(mActiveProcessChanges); 3194 mAvailProcessChanges.addAll(mPendingProcessChanges); 3195 mPendingProcessChanges.clear(); 3196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3197 } 3198 3199 int i = mProcessObservers.beginBroadcast(); 3200 while (i > 0) { 3201 i--; 3202 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3203 if (observer != null) { 3204 try { 3205 for (int j=0; j<N; j++) { 3206 ProcessChangeItem item = mActiveProcessChanges[j]; 3207 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3208 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3209 + item.pid + " uid=" + item.uid + ": " 3210 + item.foregroundActivities); 3211 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3212 item.foregroundActivities); 3213 } 3214 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3215 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3216 + item.pid + " uid=" + item.uid + ": " + item.processState); 3217 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3218 } 3219 } 3220 } catch (RemoteException e) { 3221 } 3222 } 3223 } 3224 mProcessObservers.finishBroadcast(); 3225 } 3226 3227 private void dispatchProcessDied(int pid, int uid) { 3228 int i = mProcessObservers.beginBroadcast(); 3229 while (i > 0) { 3230 i--; 3231 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3232 if (observer != null) { 3233 try { 3234 observer.onProcessDied(pid, uid); 3235 } catch (RemoteException e) { 3236 } 3237 } 3238 } 3239 mProcessObservers.finishBroadcast(); 3240 } 3241 3242 final void doPendingActivityLaunchesLocked(boolean doResume) { 3243 final int N = mPendingActivityLaunches.size(); 3244 if (N <= 0) { 3245 return; 3246 } 3247 for (int i=0; i<N; i++) { 3248 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3249 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3250 doResume && i == (N-1), null); 3251 } 3252 mPendingActivityLaunches.clear(); 3253 } 3254 3255 @Override 3256 public final int startActivity(IApplicationThread caller, String callingPackage, 3257 Intent intent, String resolvedType, IBinder resultTo, 3258 String resultWho, int requestCode, int startFlags, 3259 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3260 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3261 resultWho, requestCode, 3262 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3263 } 3264 3265 @Override 3266 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3267 Intent intent, String resolvedType, IBinder resultTo, 3268 String resultWho, int requestCode, int startFlags, 3269 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3270 enforceNotIsolatedCaller("startActivity"); 3271 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3272 false, true, "startActivity", null); 3273 // TODO: Switch to user app stacks here. 3274 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3275 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3276 null, null, options, userId, null); 3277 } 3278 3279 @Override 3280 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3281 Intent intent, String resolvedType, IBinder resultTo, 3282 String resultWho, int requestCode, int startFlags, String profileFile, 3283 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3284 enforceNotIsolatedCaller("startActivityAndWait"); 3285 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3286 false, true, "startActivityAndWait", null); 3287 WaitResult res = new WaitResult(); 3288 // TODO: Switch to user app stacks here. 3289 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3290 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3291 res, null, options, UserHandle.getCallingUserId(), null); 3292 return res; 3293 } 3294 3295 @Override 3296 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3297 Intent intent, String resolvedType, IBinder resultTo, 3298 String resultWho, int requestCode, int startFlags, Configuration config, 3299 Bundle options, int userId) { 3300 enforceNotIsolatedCaller("startActivityWithConfig"); 3301 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3302 false, true, "startActivityWithConfig", null); 3303 // TODO: Switch to user app stacks here. 3304 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3305 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3306 null, null, null, config, options, userId, null); 3307 return ret; 3308 } 3309 3310 @Override 3311 public int startActivityIntentSender(IApplicationThread caller, 3312 IntentSender intent, Intent fillInIntent, String resolvedType, 3313 IBinder resultTo, String resultWho, int requestCode, 3314 int flagsMask, int flagsValues, Bundle options) { 3315 enforceNotIsolatedCaller("startActivityIntentSender"); 3316 // Refuse possible leaked file descriptors 3317 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3318 throw new IllegalArgumentException("File descriptors passed in Intent"); 3319 } 3320 3321 IIntentSender sender = intent.getTarget(); 3322 if (!(sender instanceof PendingIntentRecord)) { 3323 throw new IllegalArgumentException("Bad PendingIntent object"); 3324 } 3325 3326 PendingIntentRecord pir = (PendingIntentRecord)sender; 3327 3328 synchronized (this) { 3329 // If this is coming from the currently resumed activity, it is 3330 // effectively saying that app switches are allowed at this point. 3331 final ActivityStack stack = getFocusedStack(); 3332 if (stack.mResumedActivity != null && 3333 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3334 mAppSwitchesAllowedTime = 0; 3335 } 3336 } 3337 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3338 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3339 return ret; 3340 } 3341 3342 @Override 3343 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3344 Intent intent, String resolvedType, IVoiceInteractionSession session, 3345 IVoiceInteractor interactor, int startFlags, String profileFile, 3346 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3347 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3348 != PackageManager.PERMISSION_GRANTED) { 3349 String msg = "Permission Denial: startVoiceActivity() from pid=" 3350 + Binder.getCallingPid() 3351 + ", uid=" + Binder.getCallingUid() 3352 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3353 Slog.w(TAG, msg); 3354 throw new SecurityException(msg); 3355 } 3356 if (session == null || interactor == null) { 3357 throw new NullPointerException("null session or interactor"); 3358 } 3359 userId = handleIncomingUser(callingPid, callingUid, userId, 3360 false, true, "startVoiceActivity", null); 3361 // TODO: Switch to user app stacks here. 3362 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3363 resolvedType, session, interactor, null, null, 0, startFlags, 3364 profileFile, profileFd, null, null, options, userId, null); 3365 } 3366 3367 @Override 3368 public boolean startNextMatchingActivity(IBinder callingActivity, 3369 Intent intent, Bundle options) { 3370 // Refuse possible leaked file descriptors 3371 if (intent != null && intent.hasFileDescriptors() == true) { 3372 throw new IllegalArgumentException("File descriptors passed in Intent"); 3373 } 3374 3375 synchronized (this) { 3376 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3377 if (r == null) { 3378 ActivityOptions.abort(options); 3379 return false; 3380 } 3381 if (r.app == null || r.app.thread == null) { 3382 // The caller is not running... d'oh! 3383 ActivityOptions.abort(options); 3384 return false; 3385 } 3386 intent = new Intent(intent); 3387 // The caller is not allowed to change the data. 3388 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3389 // And we are resetting to find the next component... 3390 intent.setComponent(null); 3391 3392 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3393 3394 ActivityInfo aInfo = null; 3395 try { 3396 List<ResolveInfo> resolves = 3397 AppGlobals.getPackageManager().queryIntentActivities( 3398 intent, r.resolvedType, 3399 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3400 UserHandle.getCallingUserId()); 3401 3402 // Look for the original activity in the list... 3403 final int N = resolves != null ? resolves.size() : 0; 3404 for (int i=0; i<N; i++) { 3405 ResolveInfo rInfo = resolves.get(i); 3406 if (rInfo.activityInfo.packageName.equals(r.packageName) 3407 && rInfo.activityInfo.name.equals(r.info.name)) { 3408 // We found the current one... the next matching is 3409 // after it. 3410 i++; 3411 if (i<N) { 3412 aInfo = resolves.get(i).activityInfo; 3413 } 3414 if (debug) { 3415 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3416 + "/" + r.info.name); 3417 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3418 + "/" + aInfo.name); 3419 } 3420 break; 3421 } 3422 } 3423 } catch (RemoteException e) { 3424 } 3425 3426 if (aInfo == null) { 3427 // Nobody who is next! 3428 ActivityOptions.abort(options); 3429 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3430 return false; 3431 } 3432 3433 intent.setComponent(new ComponentName( 3434 aInfo.applicationInfo.packageName, aInfo.name)); 3435 intent.setFlags(intent.getFlags()&~( 3436 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3437 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3438 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3439 Intent.FLAG_ACTIVITY_NEW_TASK)); 3440 3441 // Okay now we need to start the new activity, replacing the 3442 // currently running activity. This is a little tricky because 3443 // we want to start the new one as if the current one is finished, 3444 // but not finish the current one first so that there is no flicker. 3445 // And thus... 3446 final boolean wasFinishing = r.finishing; 3447 r.finishing = true; 3448 3449 // Propagate reply information over to the new activity. 3450 final ActivityRecord resultTo = r.resultTo; 3451 final String resultWho = r.resultWho; 3452 final int requestCode = r.requestCode; 3453 r.resultTo = null; 3454 if (resultTo != null) { 3455 resultTo.removeResultsLocked(r, resultWho, requestCode); 3456 } 3457 3458 final long origId = Binder.clearCallingIdentity(); 3459 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3460 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3461 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3462 options, false, null, null); 3463 Binder.restoreCallingIdentity(origId); 3464 3465 r.finishing = wasFinishing; 3466 if (res != ActivityManager.START_SUCCESS) { 3467 return false; 3468 } 3469 return true; 3470 } 3471 } 3472 3473 final int startActivityInPackage(int uid, String callingPackage, 3474 Intent intent, String resolvedType, IBinder resultTo, 3475 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3476 IActivityContainer container) { 3477 3478 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3479 false, true, "startActivityInPackage", null); 3480 3481 // TODO: Switch to user app stacks here. 3482 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3483 null, null, resultTo, resultWho, requestCode, startFlags, 3484 null, null, null, null, options, userId, container); 3485 return ret; 3486 } 3487 3488 @Override 3489 public final int startActivities(IApplicationThread caller, String callingPackage, 3490 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3491 int userId) { 3492 enforceNotIsolatedCaller("startActivities"); 3493 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3494 false, true, "startActivity", null); 3495 // TODO: Switch to user app stacks here. 3496 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3497 resolvedTypes, resultTo, options, userId); 3498 return ret; 3499 } 3500 3501 final int startActivitiesInPackage(int uid, String callingPackage, 3502 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3503 Bundle options, int userId) { 3504 3505 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3506 false, true, "startActivityInPackage", null); 3507 // TODO: Switch to user app stacks here. 3508 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3509 resultTo, options, userId); 3510 return ret; 3511 } 3512 3513 final void addRecentTaskLocked(TaskRecord task) { 3514 int N = mRecentTasks.size(); 3515 // Quick case: check if the top-most recent task is the same. 3516 if (N > 0 && mRecentTasks.get(0) == task) { 3517 return; 3518 } 3519 // Another quick case: never add voice sessions. 3520 if (task.voiceSession != null) { 3521 return; 3522 } 3523 // Remove any existing entries that are the same kind of task. 3524 final Intent intent = task.intent; 3525 final boolean document = intent != null && intent.isDocument(); 3526 for (int i=0; i<N; i++) { 3527 TaskRecord tr = mRecentTasks.get(i); 3528 if (task != tr) { 3529 if (task.userId != tr.userId) { 3530 continue; 3531 } 3532 final Intent trIntent = tr.intent; 3533 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3534 (intent == null || !intent.filterEquals(trIntent))) { 3535 continue; 3536 } 3537 if (document || trIntent != null && trIntent.isDocument()) { 3538 // Document tasks do not match other tasks. 3539 continue; 3540 } 3541 } 3542 3543 // Either task and tr are the same or, their affinities match or their intents match 3544 // and neither of them is a document. 3545 tr.disposeThumbnail(); 3546 mRecentTasks.remove(i); 3547 i--; 3548 N--; 3549 if (task.intent == null) { 3550 // If the new recent task we are adding is not fully 3551 // specified, then replace it with the existing recent task. 3552 task = tr; 3553 } 3554 } 3555 if (N >= MAX_RECENT_TASKS) { 3556 mRecentTasks.remove(N-1).disposeThumbnail(); 3557 } 3558 mRecentTasks.add(0, task); 3559 } 3560 3561 @Override 3562 public void reportActivityFullyDrawn(IBinder token) { 3563 synchronized (this) { 3564 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3565 if (r == null) { 3566 return; 3567 } 3568 r.reportFullyDrawnLocked(); 3569 } 3570 } 3571 3572 @Override 3573 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3574 synchronized (this) { 3575 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3576 if (r == null) { 3577 return; 3578 } 3579 final long origId = Binder.clearCallingIdentity(); 3580 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3581 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3582 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3583 if (config != null) { 3584 r.frozenBeforeDestroy = true; 3585 if (!updateConfigurationLocked(config, r, false, false)) { 3586 mStackSupervisor.resumeTopActivitiesLocked(); 3587 } 3588 } 3589 Binder.restoreCallingIdentity(origId); 3590 } 3591 } 3592 3593 @Override 3594 public int getRequestedOrientation(IBinder token) { 3595 synchronized (this) { 3596 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3597 if (r == null) { 3598 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3599 } 3600 return mWindowManager.getAppOrientation(r.appToken); 3601 } 3602 } 3603 3604 /** 3605 * This is the internal entry point for handling Activity.finish(). 3606 * 3607 * @param token The Binder token referencing the Activity we want to finish. 3608 * @param resultCode Result code, if any, from this Activity. 3609 * @param resultData Result data (Intent), if any, from this Activity. 3610 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3611 * the root Activity in the task. 3612 * 3613 * @return Returns true if the activity successfully finished, or false if it is still running. 3614 */ 3615 @Override 3616 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3617 boolean finishTask) { 3618 // Refuse possible leaked file descriptors 3619 if (resultData != null && resultData.hasFileDescriptors() == true) { 3620 throw new IllegalArgumentException("File descriptors passed in Intent"); 3621 } 3622 3623 synchronized(this) { 3624 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3625 if (r == null) { 3626 return true; 3627 } 3628 // Keep track of the root activity of the task before we finish it 3629 TaskRecord tr = r.task; 3630 ActivityRecord rootR = tr.getRootActivity(); 3631 if (mController != null) { 3632 // Find the first activity that is not finishing. 3633 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3634 if (next != null) { 3635 // ask watcher if this is allowed 3636 boolean resumeOK = true; 3637 try { 3638 resumeOK = mController.activityResuming(next.packageName); 3639 } catch (RemoteException e) { 3640 mController = null; 3641 Watchdog.getInstance().setActivityController(null); 3642 } 3643 3644 if (!resumeOK) { 3645 return false; 3646 } 3647 } 3648 } 3649 final long origId = Binder.clearCallingIdentity(); 3650 try { 3651 boolean res; 3652 if (finishTask && r == rootR) { 3653 // If requested, remove the task that is associated to this activity only if it 3654 // was the root activity in the task. The result code and data is ignored because 3655 // we don't support returning them across task boundaries. 3656 res = removeTaskByIdLocked(tr.taskId, 0); 3657 } else { 3658 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3659 resultData, "app-request", true); 3660 } 3661 return res; 3662 } finally { 3663 Binder.restoreCallingIdentity(origId); 3664 } 3665 } 3666 } 3667 3668 @Override 3669 public final void finishHeavyWeightApp() { 3670 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3671 != PackageManager.PERMISSION_GRANTED) { 3672 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3673 + Binder.getCallingPid() 3674 + ", uid=" + Binder.getCallingUid() 3675 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3676 Slog.w(TAG, msg); 3677 throw new SecurityException(msg); 3678 } 3679 3680 synchronized(this) { 3681 if (mHeavyWeightProcess == null) { 3682 return; 3683 } 3684 3685 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3686 mHeavyWeightProcess.activities); 3687 for (int i=0; i<activities.size(); i++) { 3688 ActivityRecord r = activities.get(i); 3689 if (!r.finishing) { 3690 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3691 null, "finish-heavy", true); 3692 } 3693 } 3694 3695 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3696 mHeavyWeightProcess.userId, 0)); 3697 mHeavyWeightProcess = null; 3698 } 3699 } 3700 3701 @Override 3702 public void crashApplication(int uid, int initialPid, String packageName, 3703 String message) { 3704 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3705 != PackageManager.PERMISSION_GRANTED) { 3706 String msg = "Permission Denial: crashApplication() 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 ProcessRecord proc = null; 3716 3717 // Figure out which process to kill. We don't trust that initialPid 3718 // still has any relation to current pids, so must scan through the 3719 // list. 3720 synchronized (mPidsSelfLocked) { 3721 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3722 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3723 if (p.uid != uid) { 3724 continue; 3725 } 3726 if (p.pid == initialPid) { 3727 proc = p; 3728 break; 3729 } 3730 if (p.pkgList.containsKey(packageName)) { 3731 proc = p; 3732 } 3733 } 3734 } 3735 3736 if (proc == null) { 3737 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3738 + " initialPid=" + initialPid 3739 + " packageName=" + packageName); 3740 return; 3741 } 3742 3743 if (proc.thread != null) { 3744 if (proc.pid == Process.myPid()) { 3745 Log.w(TAG, "crashApplication: trying to crash self!"); 3746 return; 3747 } 3748 long ident = Binder.clearCallingIdentity(); 3749 try { 3750 proc.thread.scheduleCrash(message); 3751 } catch (RemoteException e) { 3752 } 3753 Binder.restoreCallingIdentity(ident); 3754 } 3755 } 3756 } 3757 3758 @Override 3759 public final void finishSubActivity(IBinder token, String resultWho, 3760 int requestCode) { 3761 synchronized(this) { 3762 final long origId = Binder.clearCallingIdentity(); 3763 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3764 if (r != null) { 3765 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3766 } 3767 Binder.restoreCallingIdentity(origId); 3768 } 3769 } 3770 3771 @Override 3772 public boolean finishActivityAffinity(IBinder token) { 3773 synchronized(this) { 3774 final long origId = Binder.clearCallingIdentity(); 3775 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3776 boolean res = false; 3777 if (r != null) { 3778 res = r.task.stack.finishActivityAffinityLocked(r); 3779 } 3780 Binder.restoreCallingIdentity(origId); 3781 return res; 3782 } 3783 } 3784 3785 @Override 3786 public boolean willActivityBeVisible(IBinder token) { 3787 synchronized(this) { 3788 ActivityStack stack = ActivityRecord.getStackLocked(token); 3789 if (stack != null) { 3790 return stack.willActivityBeVisibleLocked(token); 3791 } 3792 return false; 3793 } 3794 } 3795 3796 @Override 3797 public void overridePendingTransition(IBinder token, String packageName, 3798 int enterAnim, int exitAnim) { 3799 synchronized(this) { 3800 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3801 if (self == null) { 3802 return; 3803 } 3804 3805 final long origId = Binder.clearCallingIdentity(); 3806 3807 if (self.state == ActivityState.RESUMED 3808 || self.state == ActivityState.PAUSING) { 3809 mWindowManager.overridePendingAppTransition(packageName, 3810 enterAnim, exitAnim, null); 3811 } 3812 3813 Binder.restoreCallingIdentity(origId); 3814 } 3815 } 3816 3817 /** 3818 * Main function for removing an existing process from the activity manager 3819 * as a result of that process going away. Clears out all connections 3820 * to the process. 3821 */ 3822 private final void handleAppDiedLocked(ProcessRecord app, 3823 boolean restarting, boolean allowRestart) { 3824 int pid = app.pid; 3825 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3826 if (!restarting) { 3827 removeLruProcessLocked(app); 3828 if (pid > 0) { 3829 ProcessList.remove(pid); 3830 } 3831 } 3832 3833 if (mProfileProc == app) { 3834 clearProfilerLocked(); 3835 } 3836 3837 // Remove this application's activities from active lists. 3838 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3839 3840 app.activities.clear(); 3841 3842 if (app.instrumentationClass != null) { 3843 Slog.w(TAG, "Crash of app " + app.processName 3844 + " running instrumentation " + app.instrumentationClass); 3845 Bundle info = new Bundle(); 3846 info.putString("shortMsg", "Process crashed."); 3847 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3848 } 3849 3850 if (!restarting) { 3851 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3852 // If there was nothing to resume, and we are not already 3853 // restarting this process, but there is a visible activity that 3854 // is hosted by the process... then make sure all visible 3855 // activities are running, taking care of restarting this 3856 // process. 3857 if (hasVisibleActivities) { 3858 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3859 } 3860 } 3861 } 3862 } 3863 3864 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3865 IBinder threadBinder = thread.asBinder(); 3866 // Find the application record. 3867 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3868 ProcessRecord rec = mLruProcesses.get(i); 3869 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3870 return i; 3871 } 3872 } 3873 return -1; 3874 } 3875 3876 final ProcessRecord getRecordForAppLocked( 3877 IApplicationThread thread) { 3878 if (thread == null) { 3879 return null; 3880 } 3881 3882 int appIndex = getLRURecordIndexForAppLocked(thread); 3883 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3884 } 3885 3886 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3887 // If there are no longer any background processes running, 3888 // and the app that died was not running instrumentation, 3889 // then tell everyone we are now low on memory. 3890 boolean haveBg = false; 3891 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3892 ProcessRecord rec = mLruProcesses.get(i); 3893 if (rec.thread != null 3894 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3895 haveBg = true; 3896 break; 3897 } 3898 } 3899 3900 if (!haveBg) { 3901 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3902 if (doReport) { 3903 long now = SystemClock.uptimeMillis(); 3904 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3905 doReport = false; 3906 } else { 3907 mLastMemUsageReportTime = now; 3908 } 3909 } 3910 final ArrayList<ProcessMemInfo> memInfos 3911 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3912 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3913 long now = SystemClock.uptimeMillis(); 3914 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3915 ProcessRecord rec = mLruProcesses.get(i); 3916 if (rec == dyingProc || rec.thread == null) { 3917 continue; 3918 } 3919 if (doReport) { 3920 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3921 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3922 } 3923 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3924 // The low memory report is overriding any current 3925 // state for a GC request. Make sure to do 3926 // heavy/important/visible/foreground processes first. 3927 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3928 rec.lastRequestedGc = 0; 3929 } else { 3930 rec.lastRequestedGc = rec.lastLowMemory; 3931 } 3932 rec.reportLowMemory = true; 3933 rec.lastLowMemory = now; 3934 mProcessesToGc.remove(rec); 3935 addProcessToGcListLocked(rec); 3936 } 3937 } 3938 if (doReport) { 3939 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3940 mHandler.sendMessage(msg); 3941 } 3942 scheduleAppGcsLocked(); 3943 } 3944 } 3945 3946 final void appDiedLocked(ProcessRecord app, int pid, 3947 IApplicationThread thread) { 3948 3949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3950 synchronized (stats) { 3951 stats.noteProcessDiedLocked(app.info.uid, pid); 3952 } 3953 3954 // Clean up already done if the process has been re-started. 3955 if (app.pid == pid && app.thread != null && 3956 app.thread.asBinder() == thread.asBinder()) { 3957 boolean doLowMem = app.instrumentationClass == null; 3958 boolean doOomAdj = doLowMem; 3959 if (!app.killedByAm) { 3960 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3961 + ") has died."); 3962 mAllowLowerMemLevel = true; 3963 } else { 3964 // Note that we always want to do oom adj to update our state with the 3965 // new number of procs. 3966 mAllowLowerMemLevel = false; 3967 doLowMem = false; 3968 } 3969 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3970 if (DEBUG_CLEANUP) Slog.v( 3971 TAG, "Dying app: " + app + ", pid: " + pid 3972 + ", thread: " + thread.asBinder()); 3973 handleAppDiedLocked(app, false, true); 3974 3975 if (doOomAdj) { 3976 updateOomAdjLocked(); 3977 } 3978 if (doLowMem) { 3979 doLowMemReportIfNeededLocked(app); 3980 } 3981 } else if (app.pid != pid) { 3982 // A new process has already been started. 3983 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3984 + ") has died and restarted (pid " + app.pid + ")."); 3985 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3986 } else if (DEBUG_PROCESSES) { 3987 Slog.d(TAG, "Received spurious death notification for thread " 3988 + thread.asBinder()); 3989 } 3990 } 3991 3992 /** 3993 * If a stack trace dump file is configured, dump process stack traces. 3994 * @param clearTraces causes the dump file to be erased prior to the new 3995 * traces being written, if true; when false, the new traces will be 3996 * appended to any existing file content. 3997 * @param firstPids of dalvik VM processes to dump stack traces for first 3998 * @param lastPids of dalvik VM processes to dump stack traces for last 3999 * @param nativeProcs optional list of native process names to dump stack crawls 4000 * @return file containing stack traces, or null if no dump file is configured 4001 */ 4002 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4003 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4004 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4005 if (tracesPath == null || tracesPath.length() == 0) { 4006 return null; 4007 } 4008 4009 File tracesFile = new File(tracesPath); 4010 try { 4011 File tracesDir = tracesFile.getParentFile(); 4012 if (!tracesDir.exists()) { 4013 tracesFile.mkdirs(); 4014 if (!SELinux.restorecon(tracesDir)) { 4015 return null; 4016 } 4017 } 4018 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4019 4020 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4021 tracesFile.createNewFile(); 4022 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4023 } catch (IOException e) { 4024 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4025 return null; 4026 } 4027 4028 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4029 return tracesFile; 4030 } 4031 4032 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4033 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4034 // Use a FileObserver to detect when traces finish writing. 4035 // The order of traces is considered important to maintain for legibility. 4036 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4037 @Override 4038 public synchronized void onEvent(int event, String path) { notify(); } 4039 }; 4040 4041 try { 4042 observer.startWatching(); 4043 4044 // First collect all of the stacks of the most important pids. 4045 if (firstPids != null) { 4046 try { 4047 int num = firstPids.size(); 4048 for (int i = 0; i < num; i++) { 4049 synchronized (observer) { 4050 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4051 observer.wait(200); // Wait for write-close, give up after 200msec 4052 } 4053 } 4054 } catch (InterruptedException e) { 4055 Log.wtf(TAG, e); 4056 } 4057 } 4058 4059 // Next collect the stacks of the native pids 4060 if (nativeProcs != null) { 4061 int[] pids = Process.getPidsForCommands(nativeProcs); 4062 if (pids != null) { 4063 for (int pid : pids) { 4064 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4065 } 4066 } 4067 } 4068 4069 // Lastly, measure CPU usage. 4070 if (processCpuTracker != null) { 4071 processCpuTracker.init(); 4072 System.gc(); 4073 processCpuTracker.update(); 4074 try { 4075 synchronized (processCpuTracker) { 4076 processCpuTracker.wait(500); // measure over 1/2 second. 4077 } 4078 } catch (InterruptedException e) { 4079 } 4080 processCpuTracker.update(); 4081 4082 // We'll take the stack crawls of just the top apps using CPU. 4083 final int N = processCpuTracker.countWorkingStats(); 4084 int numProcs = 0; 4085 for (int i=0; i<N && numProcs<5; i++) { 4086 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4087 if (lastPids.indexOfKey(stats.pid) >= 0) { 4088 numProcs++; 4089 try { 4090 synchronized (observer) { 4091 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4092 observer.wait(200); // Wait for write-close, give up after 200msec 4093 } 4094 } catch (InterruptedException e) { 4095 Log.wtf(TAG, e); 4096 } 4097 4098 } 4099 } 4100 } 4101 } finally { 4102 observer.stopWatching(); 4103 } 4104 } 4105 4106 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4107 if (true || IS_USER_BUILD) { 4108 return; 4109 } 4110 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4111 if (tracesPath == null || tracesPath.length() == 0) { 4112 return; 4113 } 4114 4115 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4116 StrictMode.allowThreadDiskWrites(); 4117 try { 4118 final File tracesFile = new File(tracesPath); 4119 final File tracesDir = tracesFile.getParentFile(); 4120 final File tracesTmp = new File(tracesDir, "__tmp__"); 4121 try { 4122 if (!tracesDir.exists()) { 4123 tracesFile.mkdirs(); 4124 if (!SELinux.restorecon(tracesDir.getPath())) { 4125 return; 4126 } 4127 } 4128 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4129 4130 if (tracesFile.exists()) { 4131 tracesTmp.delete(); 4132 tracesFile.renameTo(tracesTmp); 4133 } 4134 StringBuilder sb = new StringBuilder(); 4135 Time tobj = new Time(); 4136 tobj.set(System.currentTimeMillis()); 4137 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4138 sb.append(": "); 4139 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4140 sb.append(" since "); 4141 sb.append(msg); 4142 FileOutputStream fos = new FileOutputStream(tracesFile); 4143 fos.write(sb.toString().getBytes()); 4144 if (app == null) { 4145 fos.write("\n*** No application process!".getBytes()); 4146 } 4147 fos.close(); 4148 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4149 } catch (IOException e) { 4150 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4151 return; 4152 } 4153 4154 if (app != null) { 4155 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4156 firstPids.add(app.pid); 4157 dumpStackTraces(tracesPath, firstPids, null, null, null); 4158 } 4159 4160 File lastTracesFile = null; 4161 File curTracesFile = null; 4162 for (int i=9; i>=0; i--) { 4163 String name = String.format(Locale.US, "slow%02d.txt", i); 4164 curTracesFile = new File(tracesDir, name); 4165 if (curTracesFile.exists()) { 4166 if (lastTracesFile != null) { 4167 curTracesFile.renameTo(lastTracesFile); 4168 } else { 4169 curTracesFile.delete(); 4170 } 4171 } 4172 lastTracesFile = curTracesFile; 4173 } 4174 tracesFile.renameTo(curTracesFile); 4175 if (tracesTmp.exists()) { 4176 tracesTmp.renameTo(tracesFile); 4177 } 4178 } finally { 4179 StrictMode.setThreadPolicy(oldPolicy); 4180 } 4181 } 4182 4183 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4184 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4185 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4186 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4187 4188 if (mController != null) { 4189 try { 4190 // 0 == continue, -1 = kill process immediately 4191 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4192 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4193 } catch (RemoteException e) { 4194 mController = null; 4195 Watchdog.getInstance().setActivityController(null); 4196 } 4197 } 4198 4199 long anrTime = SystemClock.uptimeMillis(); 4200 if (MONITOR_CPU_USAGE) { 4201 updateCpuStatsNow(); 4202 } 4203 4204 synchronized (this) { 4205 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4206 if (mShuttingDown) { 4207 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4208 return; 4209 } else if (app.notResponding) { 4210 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4211 return; 4212 } else if (app.crashing) { 4213 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4214 return; 4215 } 4216 4217 // In case we come through here for the same app before completing 4218 // this one, mark as anring now so we will bail out. 4219 app.notResponding = true; 4220 4221 // Log the ANR to the event log. 4222 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4223 app.processName, app.info.flags, annotation); 4224 4225 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4226 firstPids.add(app.pid); 4227 4228 int parentPid = app.pid; 4229 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4230 if (parentPid != app.pid) firstPids.add(parentPid); 4231 4232 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4233 4234 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4235 ProcessRecord r = mLruProcesses.get(i); 4236 if (r != null && r.thread != null) { 4237 int pid = r.pid; 4238 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4239 if (r.persistent) { 4240 firstPids.add(pid); 4241 } else { 4242 lastPids.put(pid, Boolean.TRUE); 4243 } 4244 } 4245 } 4246 } 4247 } 4248 4249 // Log the ANR to the main log. 4250 StringBuilder info = new StringBuilder(); 4251 info.setLength(0); 4252 info.append("ANR in ").append(app.processName); 4253 if (activity != null && activity.shortComponentName != null) { 4254 info.append(" (").append(activity.shortComponentName).append(")"); 4255 } 4256 info.append("\n"); 4257 info.append("PID: ").append(app.pid).append("\n"); 4258 if (annotation != null) { 4259 info.append("Reason: ").append(annotation).append("\n"); 4260 } 4261 if (parent != null && parent != activity) { 4262 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4263 } 4264 4265 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4266 4267 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4268 NATIVE_STACKS_OF_INTEREST); 4269 4270 String cpuInfo = null; 4271 if (MONITOR_CPU_USAGE) { 4272 updateCpuStatsNow(); 4273 synchronized (mProcessCpuThread) { 4274 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4275 } 4276 info.append(processCpuTracker.printCurrentLoad()); 4277 info.append(cpuInfo); 4278 } 4279 4280 info.append(processCpuTracker.printCurrentState(anrTime)); 4281 4282 Slog.e(TAG, info.toString()); 4283 if (tracesFile == null) { 4284 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4285 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4286 } 4287 4288 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4289 cpuInfo, tracesFile, null); 4290 4291 if (mController != null) { 4292 try { 4293 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4294 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4295 if (res != 0) { 4296 if (res < 0 && app.pid != MY_PID) { 4297 Process.killProcess(app.pid); 4298 } else { 4299 synchronized (this) { 4300 mServices.scheduleServiceTimeoutLocked(app); 4301 } 4302 } 4303 return; 4304 } 4305 } catch (RemoteException e) { 4306 mController = null; 4307 Watchdog.getInstance().setActivityController(null); 4308 } 4309 } 4310 4311 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4312 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4313 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4314 4315 synchronized (this) { 4316 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4317 killUnneededProcessLocked(app, "background ANR"); 4318 return; 4319 } 4320 4321 // Set the app's notResponding state, and look up the errorReportReceiver 4322 makeAppNotRespondingLocked(app, 4323 activity != null ? activity.shortComponentName : null, 4324 annotation != null ? "ANR " + annotation : "ANR", 4325 info.toString()); 4326 4327 // Bring up the infamous App Not Responding dialog 4328 Message msg = Message.obtain(); 4329 HashMap<String, Object> map = new HashMap<String, Object>(); 4330 msg.what = SHOW_NOT_RESPONDING_MSG; 4331 msg.obj = map; 4332 msg.arg1 = aboveSystem ? 1 : 0; 4333 map.put("app", app); 4334 if (activity != null) { 4335 map.put("activity", activity); 4336 } 4337 4338 mHandler.sendMessage(msg); 4339 } 4340 } 4341 4342 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4343 if (!mLaunchWarningShown) { 4344 mLaunchWarningShown = true; 4345 mHandler.post(new Runnable() { 4346 @Override 4347 public void run() { 4348 synchronized (ActivityManagerService.this) { 4349 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4350 d.show(); 4351 mHandler.postDelayed(new Runnable() { 4352 @Override 4353 public void run() { 4354 synchronized (ActivityManagerService.this) { 4355 d.dismiss(); 4356 mLaunchWarningShown = false; 4357 } 4358 } 4359 }, 4000); 4360 } 4361 } 4362 }); 4363 } 4364 } 4365 4366 @Override 4367 public boolean clearApplicationUserData(final String packageName, 4368 final IPackageDataObserver observer, int userId) { 4369 enforceNotIsolatedCaller("clearApplicationUserData"); 4370 int uid = Binder.getCallingUid(); 4371 int pid = Binder.getCallingPid(); 4372 userId = handleIncomingUser(pid, uid, 4373 userId, false, true, "clearApplicationUserData", null); 4374 long callingId = Binder.clearCallingIdentity(); 4375 try { 4376 IPackageManager pm = AppGlobals.getPackageManager(); 4377 int pkgUid = -1; 4378 synchronized(this) { 4379 try { 4380 pkgUid = pm.getPackageUid(packageName, userId); 4381 } catch (RemoteException e) { 4382 } 4383 if (pkgUid == -1) { 4384 Slog.w(TAG, "Invalid packageName: " + packageName); 4385 if (observer != null) { 4386 try { 4387 observer.onRemoveCompleted(packageName, false); 4388 } catch (RemoteException e) { 4389 Slog.i(TAG, "Observer no longer exists."); 4390 } 4391 } 4392 return false; 4393 } 4394 if (uid == pkgUid || checkComponentPermission( 4395 android.Manifest.permission.CLEAR_APP_USER_DATA, 4396 pid, uid, -1, true) 4397 == PackageManager.PERMISSION_GRANTED) { 4398 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4399 } else { 4400 throw new SecurityException("PID " + pid + " does not have permission " 4401 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4402 + " of package " + packageName); 4403 } 4404 } 4405 4406 try { 4407 // Clear application user data 4408 pm.clearApplicationUserData(packageName, observer, userId); 4409 4410 // Remove all permissions granted from/to this package 4411 removeUriPermissionsForPackageLocked(packageName, userId, true); 4412 4413 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4414 Uri.fromParts("package", packageName, null)); 4415 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4416 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4417 null, null, 0, null, null, null, false, false, userId); 4418 } catch (RemoteException e) { 4419 } 4420 } finally { 4421 Binder.restoreCallingIdentity(callingId); 4422 } 4423 return true; 4424 } 4425 4426 @Override 4427 public void killBackgroundProcesses(final String packageName, int userId) { 4428 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4429 != PackageManager.PERMISSION_GRANTED && 4430 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4431 != PackageManager.PERMISSION_GRANTED) { 4432 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4433 + Binder.getCallingPid() 4434 + ", uid=" + Binder.getCallingUid() 4435 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4436 Slog.w(TAG, msg); 4437 throw new SecurityException(msg); 4438 } 4439 4440 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4441 userId, true, true, "killBackgroundProcesses", null); 4442 long callingId = Binder.clearCallingIdentity(); 4443 try { 4444 IPackageManager pm = AppGlobals.getPackageManager(); 4445 synchronized(this) { 4446 int appId = -1; 4447 try { 4448 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4449 } catch (RemoteException e) { 4450 } 4451 if (appId == -1) { 4452 Slog.w(TAG, "Invalid packageName: " + packageName); 4453 return; 4454 } 4455 killPackageProcessesLocked(packageName, appId, userId, 4456 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4457 } 4458 } finally { 4459 Binder.restoreCallingIdentity(callingId); 4460 } 4461 } 4462 4463 @Override 4464 public void killAllBackgroundProcesses() { 4465 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4466 != PackageManager.PERMISSION_GRANTED) { 4467 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4468 + Binder.getCallingPid() 4469 + ", uid=" + Binder.getCallingUid() 4470 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4471 Slog.w(TAG, msg); 4472 throw new SecurityException(msg); 4473 } 4474 4475 long callingId = Binder.clearCallingIdentity(); 4476 try { 4477 synchronized(this) { 4478 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4479 final int NP = mProcessNames.getMap().size(); 4480 for (int ip=0; ip<NP; ip++) { 4481 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4482 final int NA = apps.size(); 4483 for (int ia=0; ia<NA; ia++) { 4484 ProcessRecord app = apps.valueAt(ia); 4485 if (app.persistent) { 4486 // we don't kill persistent processes 4487 continue; 4488 } 4489 if (app.removed) { 4490 procs.add(app); 4491 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4492 app.removed = true; 4493 procs.add(app); 4494 } 4495 } 4496 } 4497 4498 int N = procs.size(); 4499 for (int i=0; i<N; i++) { 4500 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4501 } 4502 mAllowLowerMemLevel = true; 4503 updateOomAdjLocked(); 4504 doLowMemReportIfNeededLocked(null); 4505 } 4506 } finally { 4507 Binder.restoreCallingIdentity(callingId); 4508 } 4509 } 4510 4511 @Override 4512 public void forceStopPackage(final String packageName, int userId) { 4513 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4514 != PackageManager.PERMISSION_GRANTED) { 4515 String msg = "Permission Denial: forceStopPackage() from pid=" 4516 + Binder.getCallingPid() 4517 + ", uid=" + Binder.getCallingUid() 4518 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4519 Slog.w(TAG, msg); 4520 throw new SecurityException(msg); 4521 } 4522 final int callingPid = Binder.getCallingPid(); 4523 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4524 userId, true, true, "forceStopPackage", null); 4525 long callingId = Binder.clearCallingIdentity(); 4526 try { 4527 IPackageManager pm = AppGlobals.getPackageManager(); 4528 synchronized(this) { 4529 int[] users = userId == UserHandle.USER_ALL 4530 ? getUsersLocked() : new int[] { userId }; 4531 for (int user : users) { 4532 int pkgUid = -1; 4533 try { 4534 pkgUid = pm.getPackageUid(packageName, user); 4535 } catch (RemoteException e) { 4536 } 4537 if (pkgUid == -1) { 4538 Slog.w(TAG, "Invalid packageName: " + packageName); 4539 continue; 4540 } 4541 try { 4542 pm.setPackageStoppedState(packageName, true, user); 4543 } catch (RemoteException e) { 4544 } catch (IllegalArgumentException e) { 4545 Slog.w(TAG, "Failed trying to unstop package " 4546 + packageName + ": " + e); 4547 } 4548 if (isUserRunningLocked(user, false)) { 4549 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4550 } 4551 } 4552 } 4553 } finally { 4554 Binder.restoreCallingIdentity(callingId); 4555 } 4556 } 4557 4558 /* 4559 * The pkg name and app id have to be specified. 4560 */ 4561 @Override 4562 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4563 if (pkg == null) { 4564 return; 4565 } 4566 // Make sure the uid is valid. 4567 if (appid < 0) { 4568 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4569 return; 4570 } 4571 int callerUid = Binder.getCallingUid(); 4572 // Only the system server can kill an application 4573 if (callerUid == Process.SYSTEM_UID) { 4574 // Post an aysnc message to kill the application 4575 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4576 msg.arg1 = appid; 4577 msg.arg2 = 0; 4578 Bundle bundle = new Bundle(); 4579 bundle.putString("pkg", pkg); 4580 bundle.putString("reason", reason); 4581 msg.obj = bundle; 4582 mHandler.sendMessage(msg); 4583 } else { 4584 throw new SecurityException(callerUid + " cannot kill pkg: " + 4585 pkg); 4586 } 4587 } 4588 4589 @Override 4590 public void closeSystemDialogs(String reason) { 4591 enforceNotIsolatedCaller("closeSystemDialogs"); 4592 4593 final int pid = Binder.getCallingPid(); 4594 final int uid = Binder.getCallingUid(); 4595 final long origId = Binder.clearCallingIdentity(); 4596 try { 4597 synchronized (this) { 4598 // Only allow this from foreground processes, so that background 4599 // applications can't abuse it to prevent system UI from being shown. 4600 if (uid >= Process.FIRST_APPLICATION_UID) { 4601 ProcessRecord proc; 4602 synchronized (mPidsSelfLocked) { 4603 proc = mPidsSelfLocked.get(pid); 4604 } 4605 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4606 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4607 + " from background process " + proc); 4608 return; 4609 } 4610 } 4611 closeSystemDialogsLocked(reason); 4612 } 4613 } finally { 4614 Binder.restoreCallingIdentity(origId); 4615 } 4616 } 4617 4618 void closeSystemDialogsLocked(String reason) { 4619 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4620 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4621 | Intent.FLAG_RECEIVER_FOREGROUND); 4622 if (reason != null) { 4623 intent.putExtra("reason", reason); 4624 } 4625 mWindowManager.closeSystemDialogs(reason); 4626 4627 mStackSupervisor.closeSystemDialogsLocked(); 4628 4629 broadcastIntentLocked(null, null, intent, null, 4630 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4631 Process.SYSTEM_UID, UserHandle.USER_ALL); 4632 } 4633 4634 @Override 4635 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4636 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4637 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4638 for (int i=pids.length-1; i>=0; i--) { 4639 ProcessRecord proc; 4640 int oomAdj; 4641 synchronized (this) { 4642 synchronized (mPidsSelfLocked) { 4643 proc = mPidsSelfLocked.get(pids[i]); 4644 oomAdj = proc != null ? proc.setAdj : 0; 4645 } 4646 } 4647 infos[i] = new Debug.MemoryInfo(); 4648 Debug.getMemoryInfo(pids[i], infos[i]); 4649 if (proc != null) { 4650 synchronized (this) { 4651 if (proc.thread != null && proc.setAdj == oomAdj) { 4652 // Record this for posterity if the process has been stable. 4653 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4654 infos[i].getTotalUss(), false, proc.pkgList); 4655 } 4656 } 4657 } 4658 } 4659 return infos; 4660 } 4661 4662 @Override 4663 public long[] getProcessPss(int[] pids) { 4664 enforceNotIsolatedCaller("getProcessPss"); 4665 long[] pss = new long[pids.length]; 4666 for (int i=pids.length-1; i>=0; i--) { 4667 ProcessRecord proc; 4668 int oomAdj; 4669 synchronized (this) { 4670 synchronized (mPidsSelfLocked) { 4671 proc = mPidsSelfLocked.get(pids[i]); 4672 oomAdj = proc != null ? proc.setAdj : 0; 4673 } 4674 } 4675 long[] tmpUss = new long[1]; 4676 pss[i] = Debug.getPss(pids[i], tmpUss); 4677 if (proc != null) { 4678 synchronized (this) { 4679 if (proc.thread != null && proc.setAdj == oomAdj) { 4680 // Record this for posterity if the process has been stable. 4681 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4682 } 4683 } 4684 } 4685 } 4686 return pss; 4687 } 4688 4689 @Override 4690 public void killApplicationProcess(String processName, int uid) { 4691 if (processName == null) { 4692 return; 4693 } 4694 4695 int callerUid = Binder.getCallingUid(); 4696 // Only the system server can kill an application 4697 if (callerUid == Process.SYSTEM_UID) { 4698 synchronized (this) { 4699 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4700 if (app != null && app.thread != null) { 4701 try { 4702 app.thread.scheduleSuicide(); 4703 } catch (RemoteException e) { 4704 // If the other end already died, then our work here is done. 4705 } 4706 } else { 4707 Slog.w(TAG, "Process/uid not found attempting kill of " 4708 + processName + " / " + uid); 4709 } 4710 } 4711 } else { 4712 throw new SecurityException(callerUid + " cannot kill app process: " + 4713 processName); 4714 } 4715 } 4716 4717 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4718 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4719 false, true, false, false, UserHandle.getUserId(uid), reason); 4720 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4721 Uri.fromParts("package", packageName, null)); 4722 if (!mProcessesReady) { 4723 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4724 | Intent.FLAG_RECEIVER_FOREGROUND); 4725 } 4726 intent.putExtra(Intent.EXTRA_UID, uid); 4727 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4728 broadcastIntentLocked(null, null, intent, 4729 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4730 false, false, 4731 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4732 } 4733 4734 private void forceStopUserLocked(int userId, String reason) { 4735 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4736 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4737 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4738 | Intent.FLAG_RECEIVER_FOREGROUND); 4739 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4740 broadcastIntentLocked(null, null, intent, 4741 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4742 false, false, 4743 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4744 } 4745 4746 private final boolean killPackageProcessesLocked(String packageName, int appId, 4747 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4748 boolean doit, boolean evenPersistent, String reason) { 4749 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4750 4751 // Remove all processes this package may have touched: all with the 4752 // same UID (except for the system or root user), and all whose name 4753 // matches the package name. 4754 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4755 final int NP = mProcessNames.getMap().size(); 4756 for (int ip=0; ip<NP; ip++) { 4757 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4758 final int NA = apps.size(); 4759 for (int ia=0; ia<NA; ia++) { 4760 ProcessRecord app = apps.valueAt(ia); 4761 if (app.persistent && !evenPersistent) { 4762 // we don't kill persistent processes 4763 continue; 4764 } 4765 if (app.removed) { 4766 if (doit) { 4767 procs.add(app); 4768 } 4769 continue; 4770 } 4771 4772 // Skip process if it doesn't meet our oom adj requirement. 4773 if (app.setAdj < minOomAdj) { 4774 continue; 4775 } 4776 4777 // If no package is specified, we call all processes under the 4778 // give user id. 4779 if (packageName == null) { 4780 if (app.userId != userId) { 4781 continue; 4782 } 4783 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4784 continue; 4785 } 4786 // Package has been specified, we want to hit all processes 4787 // that match it. We need to qualify this by the processes 4788 // that are running under the specified app and user ID. 4789 } else { 4790 if (UserHandle.getAppId(app.uid) != appId) { 4791 continue; 4792 } 4793 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4794 continue; 4795 } 4796 if (!app.pkgList.containsKey(packageName)) { 4797 continue; 4798 } 4799 } 4800 4801 // Process has passed all conditions, kill it! 4802 if (!doit) { 4803 return true; 4804 } 4805 app.removed = true; 4806 procs.add(app); 4807 } 4808 } 4809 4810 int N = procs.size(); 4811 for (int i=0; i<N; i++) { 4812 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4813 } 4814 updateOomAdjLocked(); 4815 return N > 0; 4816 } 4817 4818 private final boolean forceStopPackageLocked(String name, int appId, 4819 boolean callerWillRestart, boolean purgeCache, boolean doit, 4820 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4821 int i; 4822 int N; 4823 4824 if (userId == UserHandle.USER_ALL && name == null) { 4825 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4826 } 4827 4828 if (appId < 0 && name != null) { 4829 try { 4830 appId = UserHandle.getAppId( 4831 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4832 } catch (RemoteException e) { 4833 } 4834 } 4835 4836 if (doit) { 4837 if (name != null) { 4838 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4839 + " user=" + userId + ": " + reason); 4840 } else { 4841 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4842 } 4843 4844 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4845 for (int ip=pmap.size()-1; ip>=0; ip--) { 4846 SparseArray<Long> ba = pmap.valueAt(ip); 4847 for (i=ba.size()-1; i>=0; i--) { 4848 boolean remove = false; 4849 final int entUid = ba.keyAt(i); 4850 if (name != null) { 4851 if (userId == UserHandle.USER_ALL) { 4852 if (UserHandle.getAppId(entUid) == appId) { 4853 remove = true; 4854 } 4855 } else { 4856 if (entUid == UserHandle.getUid(userId, appId)) { 4857 remove = true; 4858 } 4859 } 4860 } else if (UserHandle.getUserId(entUid) == userId) { 4861 remove = true; 4862 } 4863 if (remove) { 4864 ba.removeAt(i); 4865 } 4866 } 4867 if (ba.size() == 0) { 4868 pmap.removeAt(ip); 4869 } 4870 } 4871 } 4872 4873 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4874 -100, callerWillRestart, true, doit, evenPersistent, 4875 name == null ? ("stop user " + userId) : ("stop " + name)); 4876 4877 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4878 if (!doit) { 4879 return true; 4880 } 4881 didSomething = true; 4882 } 4883 4884 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4885 if (!doit) { 4886 return true; 4887 } 4888 didSomething = true; 4889 } 4890 4891 if (name == null) { 4892 // Remove all sticky broadcasts from this user. 4893 mStickyBroadcasts.remove(userId); 4894 } 4895 4896 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4897 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4898 userId, providers)) { 4899 if (!doit) { 4900 return true; 4901 } 4902 didSomething = true; 4903 } 4904 N = providers.size(); 4905 for (i=0; i<N; i++) { 4906 removeDyingProviderLocked(null, providers.get(i), true); 4907 } 4908 4909 // Remove transient permissions granted from/to this package/user 4910 removeUriPermissionsForPackageLocked(name, userId, false); 4911 4912 if (name == null || uninstalling) { 4913 // Remove pending intents. For now we only do this when force 4914 // stopping users, because we have some problems when doing this 4915 // for packages -- app widgets are not currently cleaned up for 4916 // such packages, so they can be left with bad pending intents. 4917 if (mIntentSenderRecords.size() > 0) { 4918 Iterator<WeakReference<PendingIntentRecord>> it 4919 = mIntentSenderRecords.values().iterator(); 4920 while (it.hasNext()) { 4921 WeakReference<PendingIntentRecord> wpir = it.next(); 4922 if (wpir == null) { 4923 it.remove(); 4924 continue; 4925 } 4926 PendingIntentRecord pir = wpir.get(); 4927 if (pir == null) { 4928 it.remove(); 4929 continue; 4930 } 4931 if (name == null) { 4932 // Stopping user, remove all objects for the user. 4933 if (pir.key.userId != userId) { 4934 // Not the same user, skip it. 4935 continue; 4936 } 4937 } else { 4938 if (UserHandle.getAppId(pir.uid) != appId) { 4939 // Different app id, skip it. 4940 continue; 4941 } 4942 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4943 // Different user, skip it. 4944 continue; 4945 } 4946 if (!pir.key.packageName.equals(name)) { 4947 // Different package, skip it. 4948 continue; 4949 } 4950 } 4951 if (!doit) { 4952 return true; 4953 } 4954 didSomething = true; 4955 it.remove(); 4956 pir.canceled = true; 4957 if (pir.key.activity != null) { 4958 pir.key.activity.pendingResults.remove(pir.ref); 4959 } 4960 } 4961 } 4962 } 4963 4964 if (doit) { 4965 if (purgeCache && name != null) { 4966 AttributeCache ac = AttributeCache.instance(); 4967 if (ac != null) { 4968 ac.removePackage(name); 4969 } 4970 } 4971 if (mBooted) { 4972 mStackSupervisor.resumeTopActivitiesLocked(); 4973 mStackSupervisor.scheduleIdleLocked(); 4974 } 4975 } 4976 4977 return didSomething; 4978 } 4979 4980 private final boolean removeProcessLocked(ProcessRecord app, 4981 boolean callerWillRestart, boolean allowRestart, String reason) { 4982 final String name = app.processName; 4983 final int uid = app.uid; 4984 if (DEBUG_PROCESSES) Slog.d( 4985 TAG, "Force removing proc " + app.toShortString() + " (" + name 4986 + "/" + uid + ")"); 4987 4988 mProcessNames.remove(name, uid); 4989 mIsolatedProcesses.remove(app.uid); 4990 if (mHeavyWeightProcess == app) { 4991 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4992 mHeavyWeightProcess.userId, 0)); 4993 mHeavyWeightProcess = null; 4994 } 4995 boolean needRestart = false; 4996 if (app.pid > 0 && app.pid != MY_PID) { 4997 int pid = app.pid; 4998 synchronized (mPidsSelfLocked) { 4999 mPidsSelfLocked.remove(pid); 5000 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5001 } 5002 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5003 app.processName, app.info.uid); 5004 if (app.isolated) { 5005 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5006 } 5007 killUnneededProcessLocked(app, reason); 5008 handleAppDiedLocked(app, true, allowRestart); 5009 removeLruProcessLocked(app); 5010 5011 if (app.persistent && !app.isolated) { 5012 if (!callerWillRestart) { 5013 addAppLocked(app.info, false); 5014 } else { 5015 needRestart = true; 5016 } 5017 } 5018 } else { 5019 mRemovedProcesses.add(app); 5020 } 5021 5022 return needRestart; 5023 } 5024 5025 private final void processStartTimedOutLocked(ProcessRecord app) { 5026 final int pid = app.pid; 5027 boolean gone = false; 5028 synchronized (mPidsSelfLocked) { 5029 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5030 if (knownApp != null && knownApp.thread == null) { 5031 mPidsSelfLocked.remove(pid); 5032 gone = true; 5033 } 5034 } 5035 5036 if (gone) { 5037 Slog.w(TAG, "Process " + app + " failed to attach"); 5038 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5039 pid, app.uid, app.processName); 5040 mProcessNames.remove(app.processName, app.uid); 5041 mIsolatedProcesses.remove(app.uid); 5042 if (mHeavyWeightProcess == app) { 5043 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5044 mHeavyWeightProcess.userId, 0)); 5045 mHeavyWeightProcess = null; 5046 } 5047 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5048 app.processName, app.info.uid); 5049 if (app.isolated) { 5050 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5051 } 5052 // Take care of any launching providers waiting for this process. 5053 checkAppInLaunchingProvidersLocked(app, true); 5054 // Take care of any services that are waiting for the process. 5055 mServices.processStartTimedOutLocked(app); 5056 killUnneededProcessLocked(app, "start timeout"); 5057 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5058 Slog.w(TAG, "Unattached app died before backup, skipping"); 5059 try { 5060 IBackupManager bm = IBackupManager.Stub.asInterface( 5061 ServiceManager.getService(Context.BACKUP_SERVICE)); 5062 bm.agentDisconnected(app.info.packageName); 5063 } catch (RemoteException e) { 5064 // Can't happen; the backup manager is local 5065 } 5066 } 5067 if (isPendingBroadcastProcessLocked(pid)) { 5068 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5069 skipPendingBroadcastLocked(pid); 5070 } 5071 } else { 5072 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5073 } 5074 } 5075 5076 private final boolean attachApplicationLocked(IApplicationThread thread, 5077 int pid) { 5078 5079 // Find the application record that is being attached... either via 5080 // the pid if we are running in multiple processes, or just pull the 5081 // next app record if we are emulating process with anonymous threads. 5082 ProcessRecord app; 5083 if (pid != MY_PID && pid >= 0) { 5084 synchronized (mPidsSelfLocked) { 5085 app = mPidsSelfLocked.get(pid); 5086 } 5087 } else { 5088 app = null; 5089 } 5090 5091 if (app == null) { 5092 Slog.w(TAG, "No pending application record for pid " + pid 5093 + " (IApplicationThread " + thread + "); dropping process"); 5094 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5095 if (pid > 0 && pid != MY_PID) { 5096 Process.killProcessQuiet(pid); 5097 } else { 5098 try { 5099 thread.scheduleExit(); 5100 } catch (Exception e) { 5101 // Ignore exceptions. 5102 } 5103 } 5104 return false; 5105 } 5106 5107 // If this application record is still attached to a previous 5108 // process, clean it up now. 5109 if (app.thread != null) { 5110 handleAppDiedLocked(app, true, true); 5111 } 5112 5113 // Tell the process all about itself. 5114 5115 if (localLOGV) Slog.v( 5116 TAG, "Binding process pid " + pid + " to record " + app); 5117 5118 final String processName = app.processName; 5119 try { 5120 AppDeathRecipient adr = new AppDeathRecipient( 5121 app, pid, thread); 5122 thread.asBinder().linkToDeath(adr, 0); 5123 app.deathRecipient = adr; 5124 } catch (RemoteException e) { 5125 app.resetPackageList(mProcessStats); 5126 startProcessLocked(app, "link fail", processName); 5127 return false; 5128 } 5129 5130 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5131 5132 app.makeActive(thread, mProcessStats); 5133 app.curAdj = app.setAdj = -100; 5134 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5135 app.forcingToForeground = null; 5136 updateProcessForegroundLocked(app, false, false); 5137 app.hasShownUi = false; 5138 app.debugging = false; 5139 app.cached = false; 5140 5141 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5142 5143 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5144 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5145 5146 if (!normalMode) { 5147 Slog.i(TAG, "Launching preboot mode app: " + app); 5148 } 5149 5150 if (localLOGV) Slog.v( 5151 TAG, "New app record " + app 5152 + " thread=" + thread.asBinder() + " pid=" + pid); 5153 try { 5154 int testMode = IApplicationThread.DEBUG_OFF; 5155 if (mDebugApp != null && mDebugApp.equals(processName)) { 5156 testMode = mWaitForDebugger 5157 ? IApplicationThread.DEBUG_WAIT 5158 : IApplicationThread.DEBUG_ON; 5159 app.debugging = true; 5160 if (mDebugTransient) { 5161 mDebugApp = mOrigDebugApp; 5162 mWaitForDebugger = mOrigWaitForDebugger; 5163 } 5164 } 5165 String profileFile = app.instrumentationProfileFile; 5166 ParcelFileDescriptor profileFd = null; 5167 boolean profileAutoStop = false; 5168 if (mProfileApp != null && mProfileApp.equals(processName)) { 5169 mProfileProc = app; 5170 profileFile = mProfileFile; 5171 profileFd = mProfileFd; 5172 profileAutoStop = mAutoStopProfiler; 5173 } 5174 boolean enableOpenGlTrace = false; 5175 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5176 enableOpenGlTrace = true; 5177 mOpenGlTraceApp = null; 5178 } 5179 5180 // If the app is being launched for restore or full backup, set it up specially 5181 boolean isRestrictedBackupMode = false; 5182 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5183 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5184 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5185 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5186 } 5187 5188 ensurePackageDexOpt(app.instrumentationInfo != null 5189 ? app.instrumentationInfo.packageName 5190 : app.info.packageName); 5191 if (app.instrumentationClass != null) { 5192 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5193 } 5194 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5195 + processName + " with config " + mConfiguration); 5196 ApplicationInfo appInfo = app.instrumentationInfo != null 5197 ? app.instrumentationInfo : app.info; 5198 app.compat = compatibilityInfoForPackageLocked(appInfo); 5199 if (profileFd != null) { 5200 profileFd = profileFd.dup(); 5201 } 5202 thread.bindApplication(processName, appInfo, providers, 5203 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5204 app.instrumentationArguments, app.instrumentationWatcher, 5205 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5206 isRestrictedBackupMode || !normalMode, app.persistent, 5207 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5208 mCoreSettingsObserver.getCoreSettingsLocked()); 5209 updateLruProcessLocked(app, false, null); 5210 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5211 } catch (Exception e) { 5212 // todo: Yikes! What should we do? For now we will try to 5213 // start another process, but that could easily get us in 5214 // an infinite loop of restarting processes... 5215 Slog.w(TAG, "Exception thrown during bind!", e); 5216 5217 app.resetPackageList(mProcessStats); 5218 app.unlinkDeathRecipient(); 5219 startProcessLocked(app, "bind fail", processName); 5220 return false; 5221 } 5222 5223 // Remove this record from the list of starting applications. 5224 mPersistentStartingProcesses.remove(app); 5225 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5226 "Attach application locked removing on hold: " + app); 5227 mProcessesOnHold.remove(app); 5228 5229 boolean badApp = false; 5230 boolean didSomething = false; 5231 5232 // See if the top visible activity is waiting to run in this process... 5233 if (normalMode) { 5234 try { 5235 if (mStackSupervisor.attachApplicationLocked(app)) { 5236 didSomething = true; 5237 } 5238 } catch (Exception e) { 5239 badApp = true; 5240 } 5241 } 5242 5243 // Find any services that should be running in this process... 5244 if (!badApp) { 5245 try { 5246 didSomething |= mServices.attachApplicationLocked(app, processName); 5247 } catch (Exception e) { 5248 badApp = true; 5249 } 5250 } 5251 5252 // Check if a next-broadcast receiver is in this process... 5253 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5254 try { 5255 didSomething |= sendPendingBroadcastsLocked(app); 5256 } catch (Exception e) { 5257 // If the app died trying to launch the receiver we declare it 'bad' 5258 badApp = true; 5259 } 5260 } 5261 5262 // Check whether the next backup agent is in this process... 5263 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5264 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5265 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5266 try { 5267 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5268 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5269 mBackupTarget.backupMode); 5270 } catch (Exception e) { 5271 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5272 e.printStackTrace(); 5273 } 5274 } 5275 5276 if (badApp) { 5277 // todo: Also need to kill application to deal with all 5278 // kinds of exceptions. 5279 handleAppDiedLocked(app, false, true); 5280 return false; 5281 } 5282 5283 if (!didSomething) { 5284 updateOomAdjLocked(); 5285 } 5286 5287 return true; 5288 } 5289 5290 @Override 5291 public final void attachApplication(IApplicationThread thread) { 5292 synchronized (this) { 5293 int callingPid = Binder.getCallingPid(); 5294 final long origId = Binder.clearCallingIdentity(); 5295 attachApplicationLocked(thread, callingPid); 5296 Binder.restoreCallingIdentity(origId); 5297 } 5298 } 5299 5300 @Override 5301 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5302 final long origId = Binder.clearCallingIdentity(); 5303 synchronized (this) { 5304 ActivityStack stack = ActivityRecord.getStackLocked(token); 5305 if (stack != null) { 5306 ActivityRecord r = 5307 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5308 if (stopProfiling) { 5309 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5310 try { 5311 mProfileFd.close(); 5312 } catch (IOException e) { 5313 } 5314 clearProfilerLocked(); 5315 } 5316 } 5317 } 5318 } 5319 Binder.restoreCallingIdentity(origId); 5320 } 5321 5322 void enableScreenAfterBoot() { 5323 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5324 SystemClock.uptimeMillis()); 5325 mWindowManager.enableScreenAfterBoot(); 5326 5327 synchronized (this) { 5328 updateEventDispatchingLocked(); 5329 } 5330 } 5331 5332 @Override 5333 public void showBootMessage(final CharSequence msg, final boolean always) { 5334 enforceNotIsolatedCaller("showBootMessage"); 5335 mWindowManager.showBootMessage(msg, always); 5336 } 5337 5338 @Override 5339 public void dismissKeyguardOnNextActivity() { 5340 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5341 final long token = Binder.clearCallingIdentity(); 5342 try { 5343 synchronized (this) { 5344 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5345 if (mLockScreenShown) { 5346 mLockScreenShown = false; 5347 comeOutOfSleepIfNeededLocked(); 5348 } 5349 mStackSupervisor.setDismissKeyguard(true); 5350 } 5351 } finally { 5352 Binder.restoreCallingIdentity(token); 5353 } 5354 } 5355 5356 final void finishBooting() { 5357 // Register receivers to handle package update events 5358 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5359 5360 synchronized (this) { 5361 // Ensure that any processes we had put on hold are now started 5362 // up. 5363 final int NP = mProcessesOnHold.size(); 5364 if (NP > 0) { 5365 ArrayList<ProcessRecord> procs = 5366 new ArrayList<ProcessRecord>(mProcessesOnHold); 5367 for (int ip=0; ip<NP; ip++) { 5368 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5369 + procs.get(ip)); 5370 startProcessLocked(procs.get(ip), "on-hold", null); 5371 } 5372 } 5373 5374 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5375 // Start looking for apps that are abusing wake locks. 5376 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5377 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5378 // Tell anyone interested that we are done booting! 5379 SystemProperties.set("sys.boot_completed", "1"); 5380 SystemProperties.set("dev.bootcomplete", "1"); 5381 for (int i=0; i<mStartedUsers.size(); i++) { 5382 UserStartedState uss = mStartedUsers.valueAt(i); 5383 if (uss.mState == UserStartedState.STATE_BOOTING) { 5384 uss.mState = UserStartedState.STATE_RUNNING; 5385 final int userId = mStartedUsers.keyAt(i); 5386 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5387 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5388 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5389 broadcastIntentLocked(null, null, intent, null, 5390 new IIntentReceiver.Stub() { 5391 @Override 5392 public void performReceive(Intent intent, int resultCode, 5393 String data, Bundle extras, boolean ordered, 5394 boolean sticky, int sendingUser) { 5395 synchronized (ActivityManagerService.this) { 5396 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5397 true, false); 5398 } 5399 } 5400 }, 5401 0, null, null, 5402 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5403 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5404 userId); 5405 } 5406 } 5407 scheduleStartProfilesLocked(); 5408 } 5409 } 5410 } 5411 5412 final void ensureBootCompleted() { 5413 boolean booting; 5414 boolean enableScreen; 5415 synchronized (this) { 5416 booting = mBooting; 5417 mBooting = false; 5418 enableScreen = !mBooted; 5419 mBooted = true; 5420 } 5421 5422 if (booting) { 5423 finishBooting(); 5424 } 5425 5426 if (enableScreen) { 5427 enableScreenAfterBoot(); 5428 } 5429 } 5430 5431 @Override 5432 public final void activityResumed(IBinder token) { 5433 final long origId = Binder.clearCallingIdentity(); 5434 synchronized(this) { 5435 ActivityStack stack = ActivityRecord.getStackLocked(token); 5436 if (stack != null) { 5437 ActivityRecord.activityResumedLocked(token); 5438 } 5439 } 5440 Binder.restoreCallingIdentity(origId); 5441 } 5442 5443 @Override 5444 public final void activityPaused(IBinder token) { 5445 final long origId = Binder.clearCallingIdentity(); 5446 synchronized(this) { 5447 ActivityStack stack = ActivityRecord.getStackLocked(token); 5448 if (stack != null) { 5449 stack.activityPausedLocked(token, false); 5450 } 5451 } 5452 Binder.restoreCallingIdentity(origId); 5453 } 5454 5455 @Override 5456 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5457 CharSequence description) { 5458 if (localLOGV) Slog.v( 5459 TAG, "Activity stopped: token=" + token); 5460 5461 // Refuse possible leaked file descriptors 5462 if (icicle != null && icicle.hasFileDescriptors()) { 5463 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5464 } 5465 5466 final long origId = Binder.clearCallingIdentity(); 5467 5468 synchronized (this) { 5469 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5470 if (r != null) { 5471 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5472 } 5473 } 5474 5475 trimApplications(); 5476 5477 Binder.restoreCallingIdentity(origId); 5478 } 5479 5480 @Override 5481 public final void activityDestroyed(IBinder token) { 5482 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5483 synchronized (this) { 5484 ActivityStack stack = ActivityRecord.getStackLocked(token); 5485 if (stack != null) { 5486 stack.activityDestroyedLocked(token); 5487 } 5488 } 5489 } 5490 5491 @Override 5492 public String getCallingPackage(IBinder token) { 5493 synchronized (this) { 5494 ActivityRecord r = getCallingRecordLocked(token); 5495 return r != null ? r.info.packageName : null; 5496 } 5497 } 5498 5499 @Override 5500 public ComponentName getCallingActivity(IBinder token) { 5501 synchronized (this) { 5502 ActivityRecord r = getCallingRecordLocked(token); 5503 return r != null ? r.intent.getComponent() : null; 5504 } 5505 } 5506 5507 private ActivityRecord getCallingRecordLocked(IBinder token) { 5508 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5509 if (r == null) { 5510 return null; 5511 } 5512 return r.resultTo; 5513 } 5514 5515 @Override 5516 public ComponentName getActivityClassForToken(IBinder token) { 5517 synchronized(this) { 5518 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5519 if (r == null) { 5520 return null; 5521 } 5522 return r.intent.getComponent(); 5523 } 5524 } 5525 5526 @Override 5527 public String getPackageForToken(IBinder token) { 5528 synchronized(this) { 5529 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5530 if (r == null) { 5531 return null; 5532 } 5533 return r.packageName; 5534 } 5535 } 5536 5537 @Override 5538 public IIntentSender getIntentSender(int type, 5539 String packageName, IBinder token, String resultWho, 5540 int requestCode, Intent[] intents, String[] resolvedTypes, 5541 int flags, Bundle options, int userId) { 5542 enforceNotIsolatedCaller("getIntentSender"); 5543 // Refuse possible leaked file descriptors 5544 if (intents != null) { 5545 if (intents.length < 1) { 5546 throw new IllegalArgumentException("Intents array length must be >= 1"); 5547 } 5548 for (int i=0; i<intents.length; i++) { 5549 Intent intent = intents[i]; 5550 if (intent != null) { 5551 if (intent.hasFileDescriptors()) { 5552 throw new IllegalArgumentException("File descriptors passed in Intent"); 5553 } 5554 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5555 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5556 throw new IllegalArgumentException( 5557 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5558 } 5559 intents[i] = new Intent(intent); 5560 } 5561 } 5562 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5563 throw new IllegalArgumentException( 5564 "Intent array length does not match resolvedTypes length"); 5565 } 5566 } 5567 if (options != null) { 5568 if (options.hasFileDescriptors()) { 5569 throw new IllegalArgumentException("File descriptors passed in options"); 5570 } 5571 } 5572 5573 synchronized(this) { 5574 int callingUid = Binder.getCallingUid(); 5575 int origUserId = userId; 5576 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5577 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5578 "getIntentSender", null); 5579 if (origUserId == UserHandle.USER_CURRENT) { 5580 // We don't want to evaluate this until the pending intent is 5581 // actually executed. However, we do want to always do the 5582 // security checking for it above. 5583 userId = UserHandle.USER_CURRENT; 5584 } 5585 try { 5586 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5587 int uid = AppGlobals.getPackageManager() 5588 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5589 if (!UserHandle.isSameApp(callingUid, uid)) { 5590 String msg = "Permission Denial: getIntentSender() from pid=" 5591 + Binder.getCallingPid() 5592 + ", uid=" + Binder.getCallingUid() 5593 + ", (need uid=" + uid + ")" 5594 + " is not allowed to send as package " + packageName; 5595 Slog.w(TAG, msg); 5596 throw new SecurityException(msg); 5597 } 5598 } 5599 5600 return getIntentSenderLocked(type, packageName, callingUid, userId, 5601 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5602 5603 } catch (RemoteException e) { 5604 throw new SecurityException(e); 5605 } 5606 } 5607 } 5608 5609 IIntentSender getIntentSenderLocked(int type, String packageName, 5610 int callingUid, int userId, IBinder token, String resultWho, 5611 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5612 Bundle options) { 5613 if (DEBUG_MU) 5614 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5615 ActivityRecord activity = null; 5616 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5617 activity = ActivityRecord.isInStackLocked(token); 5618 if (activity == null) { 5619 return null; 5620 } 5621 if (activity.finishing) { 5622 return null; 5623 } 5624 } 5625 5626 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5627 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5628 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5629 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5630 |PendingIntent.FLAG_UPDATE_CURRENT); 5631 5632 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5633 type, packageName, activity, resultWho, 5634 requestCode, intents, resolvedTypes, flags, options, userId); 5635 WeakReference<PendingIntentRecord> ref; 5636 ref = mIntentSenderRecords.get(key); 5637 PendingIntentRecord rec = ref != null ? ref.get() : null; 5638 if (rec != null) { 5639 if (!cancelCurrent) { 5640 if (updateCurrent) { 5641 if (rec.key.requestIntent != null) { 5642 rec.key.requestIntent.replaceExtras(intents != null ? 5643 intents[intents.length - 1] : null); 5644 } 5645 if (intents != null) { 5646 intents[intents.length-1] = rec.key.requestIntent; 5647 rec.key.allIntents = intents; 5648 rec.key.allResolvedTypes = resolvedTypes; 5649 } else { 5650 rec.key.allIntents = null; 5651 rec.key.allResolvedTypes = null; 5652 } 5653 } 5654 return rec; 5655 } 5656 rec.canceled = true; 5657 mIntentSenderRecords.remove(key); 5658 } 5659 if (noCreate) { 5660 return rec; 5661 } 5662 rec = new PendingIntentRecord(this, key, callingUid); 5663 mIntentSenderRecords.put(key, rec.ref); 5664 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5665 if (activity.pendingResults == null) { 5666 activity.pendingResults 5667 = new HashSet<WeakReference<PendingIntentRecord>>(); 5668 } 5669 activity.pendingResults.add(rec.ref); 5670 } 5671 return rec; 5672 } 5673 5674 @Override 5675 public void cancelIntentSender(IIntentSender sender) { 5676 if (!(sender instanceof PendingIntentRecord)) { 5677 return; 5678 } 5679 synchronized(this) { 5680 PendingIntentRecord rec = (PendingIntentRecord)sender; 5681 try { 5682 int uid = AppGlobals.getPackageManager() 5683 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5684 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5685 String msg = "Permission Denial: cancelIntentSender() from pid=" 5686 + Binder.getCallingPid() 5687 + ", uid=" + Binder.getCallingUid() 5688 + " is not allowed to cancel packges " 5689 + rec.key.packageName; 5690 Slog.w(TAG, msg); 5691 throw new SecurityException(msg); 5692 } 5693 } catch (RemoteException e) { 5694 throw new SecurityException(e); 5695 } 5696 cancelIntentSenderLocked(rec, true); 5697 } 5698 } 5699 5700 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5701 rec.canceled = true; 5702 mIntentSenderRecords.remove(rec.key); 5703 if (cleanActivity && rec.key.activity != null) { 5704 rec.key.activity.pendingResults.remove(rec.ref); 5705 } 5706 } 5707 5708 @Override 5709 public String getPackageForIntentSender(IIntentSender pendingResult) { 5710 if (!(pendingResult instanceof PendingIntentRecord)) { 5711 return null; 5712 } 5713 try { 5714 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5715 return res.key.packageName; 5716 } catch (ClassCastException e) { 5717 } 5718 return null; 5719 } 5720 5721 @Override 5722 public int getUidForIntentSender(IIntentSender sender) { 5723 if (sender instanceof PendingIntentRecord) { 5724 try { 5725 PendingIntentRecord res = (PendingIntentRecord)sender; 5726 return res.uid; 5727 } catch (ClassCastException e) { 5728 } 5729 } 5730 return -1; 5731 } 5732 5733 @Override 5734 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5735 if (!(pendingResult instanceof PendingIntentRecord)) { 5736 return false; 5737 } 5738 try { 5739 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5740 if (res.key.allIntents == null) { 5741 return false; 5742 } 5743 for (int i=0; i<res.key.allIntents.length; i++) { 5744 Intent intent = res.key.allIntents[i]; 5745 if (intent.getPackage() != null && intent.getComponent() != null) { 5746 return false; 5747 } 5748 } 5749 return true; 5750 } catch (ClassCastException e) { 5751 } 5752 return false; 5753 } 5754 5755 @Override 5756 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5757 if (!(pendingResult instanceof PendingIntentRecord)) { 5758 return false; 5759 } 5760 try { 5761 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5762 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5763 return true; 5764 } 5765 return false; 5766 } catch (ClassCastException e) { 5767 } 5768 return false; 5769 } 5770 5771 @Override 5772 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5773 if (!(pendingResult instanceof PendingIntentRecord)) { 5774 return null; 5775 } 5776 try { 5777 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5778 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5779 } catch (ClassCastException e) { 5780 } 5781 return null; 5782 } 5783 5784 @Override 5785 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5786 if (!(pendingResult instanceof PendingIntentRecord)) { 5787 return null; 5788 } 5789 try { 5790 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5791 Intent intent = res.key.requestIntent; 5792 if (intent != null) { 5793 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5794 || res.lastTagPrefix.equals(prefix))) { 5795 return res.lastTag; 5796 } 5797 res.lastTagPrefix = prefix; 5798 StringBuilder sb = new StringBuilder(128); 5799 if (prefix != null) { 5800 sb.append(prefix); 5801 } 5802 if (intent.getAction() != null) { 5803 sb.append(intent.getAction()); 5804 } else if (intent.getComponent() != null) { 5805 intent.getComponent().appendShortString(sb); 5806 } else { 5807 sb.append("?"); 5808 } 5809 return res.lastTag = sb.toString(); 5810 } 5811 } catch (ClassCastException e) { 5812 } 5813 return null; 5814 } 5815 5816 @Override 5817 public void setProcessLimit(int max) { 5818 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5819 "setProcessLimit()"); 5820 synchronized (this) { 5821 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5822 mProcessLimitOverride = max; 5823 } 5824 trimApplications(); 5825 } 5826 5827 @Override 5828 public int getProcessLimit() { 5829 synchronized (this) { 5830 return mProcessLimitOverride; 5831 } 5832 } 5833 5834 void foregroundTokenDied(ForegroundToken token) { 5835 synchronized (ActivityManagerService.this) { 5836 synchronized (mPidsSelfLocked) { 5837 ForegroundToken cur 5838 = mForegroundProcesses.get(token.pid); 5839 if (cur != token) { 5840 return; 5841 } 5842 mForegroundProcesses.remove(token.pid); 5843 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5844 if (pr == null) { 5845 return; 5846 } 5847 pr.forcingToForeground = null; 5848 updateProcessForegroundLocked(pr, false, false); 5849 } 5850 updateOomAdjLocked(); 5851 } 5852 } 5853 5854 @Override 5855 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5856 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5857 "setProcessForeground()"); 5858 synchronized(this) { 5859 boolean changed = false; 5860 5861 synchronized (mPidsSelfLocked) { 5862 ProcessRecord pr = mPidsSelfLocked.get(pid); 5863 if (pr == null && isForeground) { 5864 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5865 return; 5866 } 5867 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5868 if (oldToken != null) { 5869 oldToken.token.unlinkToDeath(oldToken, 0); 5870 mForegroundProcesses.remove(pid); 5871 if (pr != null) { 5872 pr.forcingToForeground = null; 5873 } 5874 changed = true; 5875 } 5876 if (isForeground && token != null) { 5877 ForegroundToken newToken = new ForegroundToken() { 5878 @Override 5879 public void binderDied() { 5880 foregroundTokenDied(this); 5881 } 5882 }; 5883 newToken.pid = pid; 5884 newToken.token = token; 5885 try { 5886 token.linkToDeath(newToken, 0); 5887 mForegroundProcesses.put(pid, newToken); 5888 pr.forcingToForeground = token; 5889 changed = true; 5890 } catch (RemoteException e) { 5891 // If the process died while doing this, we will later 5892 // do the cleanup with the process death link. 5893 } 5894 } 5895 } 5896 5897 if (changed) { 5898 updateOomAdjLocked(); 5899 } 5900 } 5901 } 5902 5903 // ========================================================= 5904 // PERMISSIONS 5905 // ========================================================= 5906 5907 static class PermissionController extends IPermissionController.Stub { 5908 ActivityManagerService mActivityManagerService; 5909 PermissionController(ActivityManagerService activityManagerService) { 5910 mActivityManagerService = activityManagerService; 5911 } 5912 5913 @Override 5914 public boolean checkPermission(String permission, int pid, int uid) { 5915 return mActivityManagerService.checkPermission(permission, pid, 5916 uid) == PackageManager.PERMISSION_GRANTED; 5917 } 5918 } 5919 5920 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5921 @Override 5922 public int checkComponentPermission(String permission, int pid, int uid, 5923 int owningUid, boolean exported) { 5924 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5925 owningUid, exported); 5926 } 5927 5928 @Override 5929 public Object getAMSLock() { 5930 return ActivityManagerService.this; 5931 } 5932 } 5933 5934 /** 5935 * This can be called with or without the global lock held. 5936 */ 5937 int checkComponentPermission(String permission, int pid, int uid, 5938 int owningUid, boolean exported) { 5939 // We might be performing an operation on behalf of an indirect binder 5940 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5941 // client identity accordingly before proceeding. 5942 Identity tlsIdentity = sCallerIdentity.get(); 5943 if (tlsIdentity != null) { 5944 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5945 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5946 uid = tlsIdentity.uid; 5947 pid = tlsIdentity.pid; 5948 } 5949 5950 if (pid == MY_PID) { 5951 return PackageManager.PERMISSION_GRANTED; 5952 } 5953 5954 return ActivityManager.checkComponentPermission(permission, uid, 5955 owningUid, exported); 5956 } 5957 5958 /** 5959 * As the only public entry point for permissions checking, this method 5960 * can enforce the semantic that requesting a check on a null global 5961 * permission is automatically denied. (Internally a null permission 5962 * string is used when calling {@link #checkComponentPermission} in cases 5963 * when only uid-based security is needed.) 5964 * 5965 * This can be called with or without the global lock held. 5966 */ 5967 @Override 5968 public int checkPermission(String permission, int pid, int uid) { 5969 if (permission == null) { 5970 return PackageManager.PERMISSION_DENIED; 5971 } 5972 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5973 } 5974 5975 /** 5976 * Binder IPC calls go through the public entry point. 5977 * This can be called with or without the global lock held. 5978 */ 5979 int checkCallingPermission(String permission) { 5980 return checkPermission(permission, 5981 Binder.getCallingPid(), 5982 UserHandle.getAppId(Binder.getCallingUid())); 5983 } 5984 5985 /** 5986 * This can be called with or without the global lock held. 5987 */ 5988 void enforceCallingPermission(String permission, String func) { 5989 if (checkCallingPermission(permission) 5990 == PackageManager.PERMISSION_GRANTED) { 5991 return; 5992 } 5993 5994 String msg = "Permission Denial: " + func + " from pid=" 5995 + Binder.getCallingPid() 5996 + ", uid=" + Binder.getCallingUid() 5997 + " requires " + permission; 5998 Slog.w(TAG, msg); 5999 throw new SecurityException(msg); 6000 } 6001 6002 /** 6003 * Determine if UID is holding permissions required to access {@link Uri} in 6004 * the given {@link ProviderInfo}. Final permission checking is always done 6005 * in {@link ContentProvider}. 6006 */ 6007 private final boolean checkHoldingPermissionsLocked( 6008 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6009 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6010 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6011 6012 if (pi.applicationInfo.uid == uid) { 6013 return true; 6014 } else if (!pi.exported) { 6015 return false; 6016 } 6017 6018 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6019 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6020 try { 6021 // check if target holds top-level <provider> permissions 6022 if (!readMet && pi.readPermission != null 6023 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6024 readMet = true; 6025 } 6026 if (!writeMet && pi.writePermission != null 6027 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6028 writeMet = true; 6029 } 6030 6031 // track if unprotected read/write is allowed; any denied 6032 // <path-permission> below removes this ability 6033 boolean allowDefaultRead = pi.readPermission == null; 6034 boolean allowDefaultWrite = pi.writePermission == null; 6035 6036 // check if target holds any <path-permission> that match uri 6037 final PathPermission[] pps = pi.pathPermissions; 6038 if (pps != null) { 6039 final String path = grantUri.uri.getPath(); 6040 int i = pps.length; 6041 while (i > 0 && (!readMet || !writeMet)) { 6042 i--; 6043 PathPermission pp = pps[i]; 6044 if (pp.match(path)) { 6045 if (!readMet) { 6046 final String pprperm = pp.getReadPermission(); 6047 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6048 + pprperm + " for " + pp.getPath() 6049 + ": match=" + pp.match(path) 6050 + " check=" + pm.checkUidPermission(pprperm, uid)); 6051 if (pprperm != null) { 6052 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6053 readMet = true; 6054 } else { 6055 allowDefaultRead = false; 6056 } 6057 } 6058 } 6059 if (!writeMet) { 6060 final String ppwperm = pp.getWritePermission(); 6061 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6062 + ppwperm + " for " + pp.getPath() 6063 + ": match=" + pp.match(path) 6064 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6065 if (ppwperm != null) { 6066 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6067 writeMet = true; 6068 } else { 6069 allowDefaultWrite = false; 6070 } 6071 } 6072 } 6073 } 6074 } 6075 } 6076 6077 // grant unprotected <provider> read/write, if not blocked by 6078 // <path-permission> above 6079 if (allowDefaultRead) readMet = true; 6080 if (allowDefaultWrite) writeMet = true; 6081 6082 } catch (RemoteException e) { 6083 return false; 6084 } 6085 6086 return readMet && writeMet; 6087 } 6088 6089 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6090 ProviderInfo pi = null; 6091 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6092 if (cpr != null) { 6093 pi = cpr.info; 6094 } else { 6095 try { 6096 pi = AppGlobals.getPackageManager().resolveContentProvider( 6097 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6098 } catch (RemoteException ex) { 6099 } 6100 } 6101 return pi; 6102 } 6103 6104 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6105 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6106 if (targetUris != null) { 6107 return targetUris.get(grantUri); 6108 } 6109 return null; 6110 } 6111 6112 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6113 String targetPkg, int targetUid, GrantUri grantUri) { 6114 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6115 if (targetUris == null) { 6116 targetUris = Maps.newArrayMap(); 6117 mGrantedUriPermissions.put(targetUid, targetUris); 6118 } 6119 6120 UriPermission perm = targetUris.get(grantUri); 6121 if (perm == null) { 6122 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6123 targetUris.put(grantUri, perm); 6124 } 6125 6126 return perm; 6127 } 6128 6129 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6130 final int modeFlags) { 6131 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6132 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6133 : UriPermission.STRENGTH_OWNED; 6134 6135 // Root gets to do everything. 6136 if (uid == 0) { 6137 return true; 6138 } 6139 6140 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6141 if (perms == null) return false; 6142 6143 // First look for exact match 6144 final UriPermission exactPerm = perms.get(grantUri); 6145 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6146 return true; 6147 } 6148 6149 // No exact match, look for prefixes 6150 final int N = perms.size(); 6151 for (int i = 0; i < N; i++) { 6152 final UriPermission perm = perms.valueAt(i); 6153 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6154 && perm.getStrength(modeFlags) >= minStrength) { 6155 return true; 6156 } 6157 } 6158 6159 return false; 6160 } 6161 6162 @Override 6163 public int checkUriPermission(Uri uri, int pid, int uid, 6164 final int modeFlags, int userId) { 6165 enforceNotIsolatedCaller("checkUriPermission"); 6166 6167 // Another redirected-binder-call permissions check as in 6168 // {@link checkComponentPermission}. 6169 Identity tlsIdentity = sCallerIdentity.get(); 6170 if (tlsIdentity != null) { 6171 uid = tlsIdentity.uid; 6172 pid = tlsIdentity.pid; 6173 } 6174 6175 // Our own process gets to do everything. 6176 if (pid == MY_PID) { 6177 return PackageManager.PERMISSION_GRANTED; 6178 } 6179 synchronized (this) { 6180 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6181 ? PackageManager.PERMISSION_GRANTED 6182 : PackageManager.PERMISSION_DENIED; 6183 } 6184 } 6185 6186 /** 6187 * Check if the targetPkg can be granted permission to access uri by 6188 * the callingUid using the given modeFlags. Throws a security exception 6189 * if callingUid is not allowed to do this. Returns the uid of the target 6190 * if the URI permission grant should be performed; returns -1 if it is not 6191 * needed (for example targetPkg already has permission to access the URI). 6192 * If you already know the uid of the target, you can supply it in 6193 * lastTargetUid else set that to -1. 6194 */ 6195 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6196 final int modeFlags, int lastTargetUid) { 6197 if (!Intent.isAccessUriMode(modeFlags)) { 6198 return -1; 6199 } 6200 6201 if (targetPkg != null) { 6202 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6203 "Checking grant " + targetPkg + " permission to " + grantUri); 6204 } 6205 6206 final IPackageManager pm = AppGlobals.getPackageManager(); 6207 6208 // If this is not a content: uri, we can't do anything with it. 6209 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6211 "Can't grant URI permission for non-content URI: " + grantUri); 6212 return -1; 6213 } 6214 6215 final String authority = grantUri.uri.getAuthority(); 6216 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6217 if (pi == null) { 6218 Slog.w(TAG, "No content provider found for permission check: " + 6219 grantUri.uri.toSafeString()); 6220 return -1; 6221 } 6222 6223 int targetUid = lastTargetUid; 6224 if (targetUid < 0 && targetPkg != null) { 6225 try { 6226 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6227 if (targetUid < 0) { 6228 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6229 "Can't grant URI permission no uid for: " + targetPkg); 6230 return -1; 6231 } 6232 } catch (RemoteException ex) { 6233 return -1; 6234 } 6235 } 6236 6237 if (targetUid >= 0) { 6238 // First... does the target actually need this permission? 6239 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6240 // No need to grant the target this permission. 6241 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6242 "Target " + targetPkg + " already has full permission to " + grantUri); 6243 return -1; 6244 } 6245 } else { 6246 // First... there is no target package, so can anyone access it? 6247 boolean allowed = pi.exported; 6248 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6249 if (pi.readPermission != null) { 6250 allowed = false; 6251 } 6252 } 6253 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6254 if (pi.writePermission != null) { 6255 allowed = false; 6256 } 6257 } 6258 if (allowed) { 6259 return -1; 6260 } 6261 } 6262 6263 // Second... is the provider allowing granting of URI permissions? 6264 if (!pi.grantUriPermissions) { 6265 throw new SecurityException("Provider " + pi.packageName 6266 + "/" + pi.name 6267 + " does not allow granting of Uri permissions (uri " 6268 + grantUri + ")"); 6269 } 6270 if (pi.uriPermissionPatterns != null) { 6271 final int N = pi.uriPermissionPatterns.length; 6272 boolean allowed = false; 6273 for (int i=0; i<N; i++) { 6274 if (pi.uriPermissionPatterns[i] != null 6275 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6276 allowed = true; 6277 break; 6278 } 6279 } 6280 if (!allowed) { 6281 throw new SecurityException("Provider " + pi.packageName 6282 + "/" + pi.name 6283 + " does not allow granting of permission to path of Uri " 6284 + grantUri); 6285 } 6286 } 6287 6288 // Third... does the caller itself have permission to access 6289 // this uri? 6290 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6291 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6292 // Require they hold a strong enough Uri permission 6293 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6294 throw new SecurityException("Uid " + callingUid 6295 + " does not have permission to uri " + grantUri); 6296 } 6297 } 6298 } 6299 return targetUid; 6300 } 6301 6302 @Override 6303 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6304 final int modeFlags, int userId) { 6305 enforceNotIsolatedCaller("checkGrantUriPermission"); 6306 synchronized(this) { 6307 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6308 new GrantUri(userId, uri, false), modeFlags, -1); 6309 } 6310 } 6311 6312 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6313 final int modeFlags, UriPermissionOwner owner) { 6314 if (!Intent.isAccessUriMode(modeFlags)) { 6315 return; 6316 } 6317 6318 // So here we are: the caller has the assumed permission 6319 // to the uri, and the target doesn't. Let's now give this to 6320 // the target. 6321 6322 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6323 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6324 6325 final String authority = grantUri.uri.getAuthority(); 6326 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6327 if (pi == null) { 6328 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6329 return; 6330 } 6331 6332 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6333 grantUri.prefix = true; 6334 } 6335 final UriPermission perm = findOrCreateUriPermissionLocked( 6336 pi.packageName, targetPkg, targetUid, grantUri); 6337 perm.grantModes(modeFlags, owner); 6338 } 6339 6340 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6341 final int modeFlags, UriPermissionOwner owner) { 6342 if (targetPkg == null) { 6343 throw new NullPointerException("targetPkg"); 6344 } 6345 6346 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6347 -1); 6348 if (targetUid < 0) { 6349 return; 6350 } 6351 6352 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6353 owner); 6354 } 6355 6356 static class NeededUriGrants extends ArrayList<GrantUri> { 6357 final String targetPkg; 6358 final int targetUid; 6359 final int flags; 6360 6361 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6362 this.targetPkg = targetPkg; 6363 this.targetUid = targetUid; 6364 this.flags = flags; 6365 } 6366 } 6367 6368 /** 6369 * Like checkGrantUriPermissionLocked, but takes an Intent. 6370 */ 6371 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6372 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6373 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6374 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6375 + " clip=" + (intent != null ? intent.getClipData() : null) 6376 + " from " + intent + "; flags=0x" 6377 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6378 6379 if (targetPkg == null) { 6380 throw new NullPointerException("targetPkg"); 6381 } 6382 6383 if (intent == null) { 6384 return null; 6385 } 6386 Uri data = intent.getData(); 6387 ClipData clip = intent.getClipData(); 6388 if (data == null && clip == null) { 6389 return null; 6390 } 6391 6392 if (data != null) { 6393 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6394 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6395 needed != null ? needed.targetUid : -1); 6396 if (targetUid > 0) { 6397 if (needed == null) { 6398 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6399 } 6400 needed.add(grantUri); 6401 } 6402 } 6403 if (clip != null) { 6404 for (int i=0; i<clip.getItemCount(); i++) { 6405 Uri uri = clip.getItemAt(i).getUri(); 6406 if (uri != null) { 6407 int targetUid = -1; 6408 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6409 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6410 needed != null ? needed.targetUid : -1); 6411 if (targetUid > 0) { 6412 if (needed == null) { 6413 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6414 } 6415 needed.add(grantUri); 6416 } 6417 } else { 6418 Intent clipIntent = clip.getItemAt(i).getIntent(); 6419 if (clipIntent != null) { 6420 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6421 callingUid, targetPkg, clipIntent, mode, needed); 6422 if (newNeeded != null) { 6423 needed = newNeeded; 6424 } 6425 } 6426 } 6427 } 6428 } 6429 6430 return needed; 6431 } 6432 6433 /** 6434 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6435 */ 6436 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6437 UriPermissionOwner owner) { 6438 if (needed != null) { 6439 for (int i=0; i<needed.size(); i++) { 6440 GrantUri grantUri = needed.get(i); 6441 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6442 grantUri, needed.flags, owner); 6443 } 6444 } 6445 } 6446 6447 void grantUriPermissionFromIntentLocked(int callingUid, 6448 String targetPkg, Intent intent, UriPermissionOwner owner) { 6449 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6450 intent, intent != null ? intent.getFlags() : 0, null); 6451 if (needed == null) { 6452 return; 6453 } 6454 6455 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6456 } 6457 6458 @Override 6459 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6460 final int modeFlags, int userId) { 6461 enforceNotIsolatedCaller("grantUriPermission"); 6462 GrantUri grantUri = new GrantUri(userId, uri, false); 6463 synchronized(this) { 6464 final ProcessRecord r = getRecordForAppLocked(caller); 6465 if (r == null) { 6466 throw new SecurityException("Unable to find app for caller " 6467 + caller 6468 + " when granting permission to uri " + grantUri); 6469 } 6470 if (targetPkg == null) { 6471 throw new IllegalArgumentException("null target"); 6472 } 6473 if (grantUri == null) { 6474 throw new IllegalArgumentException("null uri"); 6475 } 6476 6477 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6478 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6479 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6480 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6481 6482 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6483 } 6484 } 6485 6486 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6487 if (perm.modeFlags == 0) { 6488 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6489 perm.targetUid); 6490 if (perms != null) { 6491 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6492 "Removing " + perm.targetUid + " permission to " + perm.uri); 6493 6494 perms.remove(perm.uri); 6495 if (perms.isEmpty()) { 6496 mGrantedUriPermissions.remove(perm.targetUid); 6497 } 6498 } 6499 } 6500 } 6501 6502 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6503 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6504 6505 final IPackageManager pm = AppGlobals.getPackageManager(); 6506 final String authority = grantUri.uri.getAuthority(); 6507 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6508 if (pi == null) { 6509 Slog.w(TAG, "No content provider found for permission revoke: " 6510 + grantUri.toSafeString()); 6511 return; 6512 } 6513 6514 // Does the caller have this permission on the URI? 6515 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6516 // Right now, if you are not the original owner of the permission, 6517 // you are not allowed to revoke it. 6518 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6519 throw new SecurityException("Uid " + callingUid 6520 + " does not have permission to uri " + grantUri); 6521 //} 6522 } 6523 6524 boolean persistChanged = false; 6525 6526 // Go through all of the permissions and remove any that match. 6527 int N = mGrantedUriPermissions.size(); 6528 for (int i = 0; i < N; i++) { 6529 final int targetUid = mGrantedUriPermissions.keyAt(i); 6530 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6531 6532 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6533 final UriPermission perm = it.next(); 6534 if (perm.uri.sourceUserId == grantUri.sourceUserId 6535 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6536 if (DEBUG_URI_PERMISSION) 6537 Slog.v(TAG, 6538 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6539 persistChanged |= perm.revokeModes( 6540 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6541 if (perm.modeFlags == 0) { 6542 it.remove(); 6543 } 6544 } 6545 } 6546 6547 if (perms.isEmpty()) { 6548 mGrantedUriPermissions.remove(targetUid); 6549 N--; 6550 i--; 6551 } 6552 } 6553 6554 if (persistChanged) { 6555 schedulePersistUriGrants(); 6556 } 6557 } 6558 6559 @Override 6560 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6561 int userId) { 6562 enforceNotIsolatedCaller("revokeUriPermission"); 6563 synchronized(this) { 6564 final ProcessRecord r = getRecordForAppLocked(caller); 6565 if (r == null) { 6566 throw new SecurityException("Unable to find app for caller " 6567 + caller 6568 + " when revoking permission to uri " + uri); 6569 } 6570 if (uri == null) { 6571 Slog.w(TAG, "revokeUriPermission: null uri"); 6572 return; 6573 } 6574 6575 if (!Intent.isAccessUriMode(modeFlags)) { 6576 return; 6577 } 6578 6579 final IPackageManager pm = AppGlobals.getPackageManager(); 6580 final String authority = uri.getAuthority(); 6581 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6582 if (pi == null) { 6583 Slog.w(TAG, "No content provider found for permission revoke: " 6584 + uri.toSafeString()); 6585 return; 6586 } 6587 6588 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6589 } 6590 } 6591 6592 /** 6593 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6594 * given package. 6595 * 6596 * @param packageName Package name to match, or {@code null} to apply to all 6597 * packages. 6598 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6599 * to all users. 6600 * @param persistable If persistable grants should be removed. 6601 */ 6602 private void removeUriPermissionsForPackageLocked( 6603 String packageName, int userHandle, boolean persistable) { 6604 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6605 throw new IllegalArgumentException("Must narrow by either package or user"); 6606 } 6607 6608 boolean persistChanged = false; 6609 6610 int N = mGrantedUriPermissions.size(); 6611 for (int i = 0; i < N; i++) { 6612 final int targetUid = mGrantedUriPermissions.keyAt(i); 6613 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6614 6615 // Only inspect grants matching user 6616 if (userHandle == UserHandle.USER_ALL 6617 || userHandle == UserHandle.getUserId(targetUid)) { 6618 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6619 final UriPermission perm = it.next(); 6620 6621 // Only inspect grants matching package 6622 if (packageName == null || perm.sourcePkg.equals(packageName) 6623 || perm.targetPkg.equals(packageName)) { 6624 persistChanged |= perm.revokeModes( 6625 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6626 6627 // Only remove when no modes remain; any persisted grants 6628 // will keep this alive. 6629 if (perm.modeFlags == 0) { 6630 it.remove(); 6631 } 6632 } 6633 } 6634 6635 if (perms.isEmpty()) { 6636 mGrantedUriPermissions.remove(targetUid); 6637 N--; 6638 i--; 6639 } 6640 } 6641 } 6642 6643 if (persistChanged) { 6644 schedulePersistUriGrants(); 6645 } 6646 } 6647 6648 @Override 6649 public IBinder newUriPermissionOwner(String name) { 6650 enforceNotIsolatedCaller("newUriPermissionOwner"); 6651 synchronized(this) { 6652 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6653 return owner.getExternalTokenLocked(); 6654 } 6655 } 6656 6657 @Override 6658 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6659 final int modeFlags, int userId) { 6660 synchronized(this) { 6661 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6662 if (owner == null) { 6663 throw new IllegalArgumentException("Unknown owner: " + token); 6664 } 6665 if (fromUid != Binder.getCallingUid()) { 6666 if (Binder.getCallingUid() != Process.myUid()) { 6667 // Only system code can grant URI permissions on behalf 6668 // of other users. 6669 throw new SecurityException("nice try"); 6670 } 6671 } 6672 if (targetPkg == null) { 6673 throw new IllegalArgumentException("null target"); 6674 } 6675 if (uri == null) { 6676 throw new IllegalArgumentException("null uri"); 6677 } 6678 6679 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6680 modeFlags, owner); 6681 } 6682 } 6683 6684 @Override 6685 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6686 synchronized(this) { 6687 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6688 if (owner == null) { 6689 throw new IllegalArgumentException("Unknown owner: " + token); 6690 } 6691 6692 if (uri == null) { 6693 owner.removeUriPermissionsLocked(mode); 6694 } else { 6695 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6696 } 6697 } 6698 } 6699 6700 private void schedulePersistUriGrants() { 6701 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6702 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6703 10 * DateUtils.SECOND_IN_MILLIS); 6704 } 6705 } 6706 6707 private void writeGrantedUriPermissions() { 6708 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6709 6710 // Snapshot permissions so we can persist without lock 6711 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6712 synchronized (this) { 6713 final int size = mGrantedUriPermissions.size(); 6714 for (int i = 0; i < size; i++) { 6715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6716 for (UriPermission perm : perms.values()) { 6717 if (perm.persistedModeFlags != 0) { 6718 persist.add(perm.snapshot()); 6719 } 6720 } 6721 } 6722 } 6723 6724 FileOutputStream fos = null; 6725 try { 6726 fos = mGrantFile.startWrite(); 6727 6728 XmlSerializer out = new FastXmlSerializer(); 6729 out.setOutput(fos, "utf-8"); 6730 out.startDocument(null, true); 6731 out.startTag(null, TAG_URI_GRANTS); 6732 for (UriPermission.Snapshot perm : persist) { 6733 out.startTag(null, TAG_URI_GRANT); 6734 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6735 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6736 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6737 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6738 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6739 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6740 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6741 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6742 out.endTag(null, TAG_URI_GRANT); 6743 } 6744 out.endTag(null, TAG_URI_GRANTS); 6745 out.endDocument(); 6746 6747 mGrantFile.finishWrite(fos); 6748 } catch (IOException e) { 6749 if (fos != null) { 6750 mGrantFile.failWrite(fos); 6751 } 6752 } 6753 } 6754 6755 private void readGrantedUriPermissionsLocked() { 6756 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6757 6758 final long now = System.currentTimeMillis(); 6759 6760 FileInputStream fis = null; 6761 try { 6762 fis = mGrantFile.openRead(); 6763 final XmlPullParser in = Xml.newPullParser(); 6764 in.setInput(fis, null); 6765 6766 int type; 6767 while ((type = in.next()) != END_DOCUMENT) { 6768 final String tag = in.getName(); 6769 if (type == START_TAG) { 6770 if (TAG_URI_GRANT.equals(tag)) { 6771 final int sourceUserId; 6772 final int targetUserId; 6773 final int userHandle = readIntAttribute(in, 6774 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6775 if (userHandle != UserHandle.USER_NULL) { 6776 // For backwards compatibility. 6777 sourceUserId = userHandle; 6778 targetUserId = userHandle; 6779 } else { 6780 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6781 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6782 } 6783 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6784 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6785 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6786 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6787 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6788 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6789 6790 // Sanity check that provider still belongs to source package 6791 final ProviderInfo pi = getProviderInfoLocked( 6792 uri.getAuthority(), sourceUserId); 6793 if (pi != null && sourcePkg.equals(pi.packageName)) { 6794 int targetUid = -1; 6795 try { 6796 targetUid = AppGlobals.getPackageManager() 6797 .getPackageUid(targetPkg, targetUserId); 6798 } catch (RemoteException e) { 6799 } 6800 if (targetUid != -1) { 6801 final UriPermission perm = findOrCreateUriPermissionLocked( 6802 sourcePkg, targetPkg, targetUid, 6803 new GrantUri(sourceUserId, uri, prefix)); 6804 perm.initPersistedModes(modeFlags, createdTime); 6805 } 6806 } else { 6807 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6808 + " but instead found " + pi); 6809 } 6810 } 6811 } 6812 } 6813 } catch (FileNotFoundException e) { 6814 // Missing grants is okay 6815 } catch (IOException e) { 6816 Log.wtf(TAG, "Failed reading Uri grants", e); 6817 } catch (XmlPullParserException e) { 6818 Log.wtf(TAG, "Failed reading Uri grants", e); 6819 } finally { 6820 IoUtils.closeQuietly(fis); 6821 } 6822 } 6823 6824 @Override 6825 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6826 enforceNotIsolatedCaller("takePersistableUriPermission"); 6827 6828 Preconditions.checkFlagsArgument(modeFlags, 6829 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6830 6831 synchronized (this) { 6832 final int callingUid = Binder.getCallingUid(); 6833 boolean persistChanged = false; 6834 GrantUri grantUri = new GrantUri(userId, uri, false); 6835 6836 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6837 new GrantUri(userId, uri, false)); 6838 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6839 new GrantUri(userId, uri, true)); 6840 6841 final boolean exactValid = (exactPerm != null) 6842 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6843 final boolean prefixValid = (prefixPerm != null) 6844 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6845 6846 if (!(exactValid || prefixValid)) { 6847 throw new SecurityException("No persistable permission grants found for UID " 6848 + callingUid + " and Uri " + grantUri.toSafeString()); 6849 } 6850 6851 if (exactValid) { 6852 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6853 } 6854 if (prefixValid) { 6855 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6856 } 6857 6858 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6859 6860 if (persistChanged) { 6861 schedulePersistUriGrants(); 6862 } 6863 } 6864 } 6865 6866 @Override 6867 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6868 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6869 6870 Preconditions.checkFlagsArgument(modeFlags, 6871 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6872 6873 synchronized (this) { 6874 final int callingUid = Binder.getCallingUid(); 6875 boolean persistChanged = false; 6876 6877 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6878 new GrantUri(userId, uri, false)); 6879 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6880 new GrantUri(userId, uri, true)); 6881 if (exactPerm == null && prefixPerm == null) { 6882 throw new SecurityException("No permission grants found for UID " + callingUid 6883 + " and Uri " + uri.toSafeString()); 6884 } 6885 6886 if (exactPerm != null) { 6887 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6888 removeUriPermissionIfNeededLocked(exactPerm); 6889 } 6890 if (prefixPerm != null) { 6891 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6892 removeUriPermissionIfNeededLocked(prefixPerm); 6893 } 6894 6895 if (persistChanged) { 6896 schedulePersistUriGrants(); 6897 } 6898 } 6899 } 6900 6901 /** 6902 * Prune any older {@link UriPermission} for the given UID until outstanding 6903 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6904 * 6905 * @return if any mutations occured that require persisting. 6906 */ 6907 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6908 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6909 if (perms == null) return false; 6910 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6911 6912 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6913 for (UriPermission perm : perms.values()) { 6914 if (perm.persistedModeFlags != 0) { 6915 persisted.add(perm); 6916 } 6917 } 6918 6919 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6920 if (trimCount <= 0) return false; 6921 6922 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6923 for (int i = 0; i < trimCount; i++) { 6924 final UriPermission perm = persisted.get(i); 6925 6926 if (DEBUG_URI_PERMISSION) { 6927 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6928 } 6929 6930 perm.releasePersistableModes(~0); 6931 removeUriPermissionIfNeededLocked(perm); 6932 } 6933 6934 return true; 6935 } 6936 6937 @Override 6938 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6939 String packageName, boolean incoming) { 6940 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6941 Preconditions.checkNotNull(packageName, "packageName"); 6942 6943 final int callingUid = Binder.getCallingUid(); 6944 final IPackageManager pm = AppGlobals.getPackageManager(); 6945 try { 6946 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6947 if (packageUid != callingUid) { 6948 throw new SecurityException( 6949 "Package " + packageName + " does not belong to calling UID " + callingUid); 6950 } 6951 } catch (RemoteException e) { 6952 throw new SecurityException("Failed to verify package name ownership"); 6953 } 6954 6955 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6956 synchronized (this) { 6957 if (incoming) { 6958 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6959 callingUid); 6960 if (perms == null) { 6961 Slog.w(TAG, "No permission grants found for " + packageName); 6962 } else { 6963 for (UriPermission perm : perms.values()) { 6964 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6965 result.add(perm.buildPersistedPublicApiObject()); 6966 } 6967 } 6968 } 6969 } else { 6970 final int size = mGrantedUriPermissions.size(); 6971 for (int i = 0; i < size; i++) { 6972 final ArrayMap<GrantUri, UriPermission> perms = 6973 mGrantedUriPermissions.valueAt(i); 6974 for (UriPermission perm : perms.values()) { 6975 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6976 result.add(perm.buildPersistedPublicApiObject()); 6977 } 6978 } 6979 } 6980 } 6981 } 6982 return new ParceledListSlice<android.content.UriPermission>(result); 6983 } 6984 6985 @Override 6986 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6987 synchronized (this) { 6988 ProcessRecord app = 6989 who != null ? getRecordForAppLocked(who) : null; 6990 if (app == null) return; 6991 6992 Message msg = Message.obtain(); 6993 msg.what = WAIT_FOR_DEBUGGER_MSG; 6994 msg.obj = app; 6995 msg.arg1 = waiting ? 1 : 0; 6996 mHandler.sendMessage(msg); 6997 } 6998 } 6999 7000 @Override 7001 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7002 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7003 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7004 outInfo.availMem = Process.getFreeMemory(); 7005 outInfo.totalMem = Process.getTotalMemory(); 7006 outInfo.threshold = homeAppMem; 7007 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7008 outInfo.hiddenAppThreshold = cachedAppMem; 7009 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7010 ProcessList.SERVICE_ADJ); 7011 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7012 ProcessList.VISIBLE_APP_ADJ); 7013 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7014 ProcessList.FOREGROUND_APP_ADJ); 7015 } 7016 7017 // ========================================================= 7018 // TASK MANAGEMENT 7019 // ========================================================= 7020 7021 @Override 7022 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7023 final int callingUid = Binder.getCallingUid(); 7024 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7025 7026 synchronized(this) { 7027 if (localLOGV) Slog.v( 7028 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7029 7030 final boolean allowed = checkCallingPermission( 7031 android.Manifest.permission.GET_TASKS) 7032 == PackageManager.PERMISSION_GRANTED; 7033 if (!allowed) { 7034 Slog.w(TAG, "getTasks: caller " + callingUid 7035 + " does not hold GET_TASKS; limiting output"); 7036 } 7037 7038 // TODO: Improve with MRU list from all ActivityStacks. 7039 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7040 } 7041 7042 return list; 7043 } 7044 7045 TaskRecord getMostRecentTask() { 7046 return mRecentTasks.get(0); 7047 } 7048 7049 @Override 7050 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7051 int flags, int userId) { 7052 final int callingUid = Binder.getCallingUid(); 7053 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7054 false, true, "getRecentTasks", null); 7055 7056 synchronized (this) { 7057 final boolean allowed = checkCallingPermission( 7058 android.Manifest.permission.GET_TASKS) 7059 == PackageManager.PERMISSION_GRANTED; 7060 if (!allowed) { 7061 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7062 + " does not hold GET_TASKS; limiting output"); 7063 } 7064 final boolean detailed = checkCallingPermission( 7065 android.Manifest.permission.GET_DETAILED_TASKS) 7066 == PackageManager.PERMISSION_GRANTED; 7067 7068 IPackageManager pm = AppGlobals.getPackageManager(); 7069 7070 final int N = mRecentTasks.size(); 7071 ArrayList<ActivityManager.RecentTaskInfo> res 7072 = new ArrayList<ActivityManager.RecentTaskInfo>( 7073 maxNum < N ? maxNum : N); 7074 7075 final Set<Integer> includedUsers; 7076 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7077 includedUsers = getProfileIdsLocked(userId); 7078 } else { 7079 includedUsers = new HashSet<Integer>(); 7080 } 7081 includedUsers.add(Integer.valueOf(userId)); 7082 for (int i=0; i<N && maxNum > 0; i++) { 7083 TaskRecord tr = mRecentTasks.get(i); 7084 // Only add calling user or related users recent tasks 7085 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7086 7087 // Return the entry if desired by the caller. We always return 7088 // the first entry, because callers always expect this to be the 7089 // foreground app. We may filter others if the caller has 7090 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7091 // we should exclude the entry. 7092 7093 if (i == 0 7094 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7095 || (tr.intent == null) 7096 || ((tr.intent.getFlags() 7097 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7098 if (!allowed) { 7099 // If the caller doesn't have the GET_TASKS permission, then only 7100 // allow them to see a small subset of tasks -- their own and home. 7101 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7102 continue; 7103 } 7104 } 7105 ActivityManager.RecentTaskInfo rti 7106 = new ActivityManager.RecentTaskInfo(); 7107 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7108 rti.persistentId = tr.taskId; 7109 rti.baseIntent = new Intent( 7110 tr.intent != null ? tr.intent : tr.affinityIntent); 7111 if (!detailed) { 7112 rti.baseIntent.replaceExtras((Bundle)null); 7113 } 7114 rti.origActivity = tr.origActivity; 7115 rti.description = tr.lastDescription; 7116 rti.stackId = tr.stack.mStackId; 7117 rti.userId = tr.userId; 7118 7119 // Traverse upwards looking for any break between main task activities and 7120 // utility activities. 7121 final ArrayList<ActivityRecord> activities = tr.mActivities; 7122 int activityNdx; 7123 final int numActivities = activities.size(); 7124 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7125 ++activityNdx) { 7126 final ActivityRecord r = activities.get(activityNdx); 7127 if (r.intent != null && 7128 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7129 != 0) { 7130 break; 7131 } 7132 } 7133 if (activityNdx > 0) { 7134 // Traverse downwards starting below break looking for set label, icon. 7135 // Note that if there are activities in the task but none of them set the 7136 // recent activity values, then we do not fall back to the last set 7137 // values in the TaskRecord. 7138 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7139 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7140 final ActivityRecord r = activities.get(activityNdx); 7141 if (r.activityValues != null) { 7142 if (rti.activityValues.label == null) { 7143 rti.activityValues.label = r.activityValues.label; 7144 tr.lastActivityValues.label = r.activityValues.label; 7145 } 7146 if (rti.activityValues.icon == null) { 7147 rti.activityValues.icon = r.activityValues.icon; 7148 tr.lastActivityValues.icon = r.activityValues.icon; 7149 } 7150 if (rti.activityValues.colorPrimary == 0) { 7151 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7152 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7153 } 7154 } 7155 } 7156 } else { 7157 // If there are no activity records in this task, then we use the last 7158 // resolved values 7159 rti.activityValues = 7160 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7161 } 7162 7163 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7164 // Check whether this activity is currently available. 7165 try { 7166 if (rti.origActivity != null) { 7167 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7168 == null) { 7169 continue; 7170 } 7171 } else if (rti.baseIntent != null) { 7172 if (pm.queryIntentActivities(rti.baseIntent, 7173 null, 0, userId) == null) { 7174 continue; 7175 } 7176 } 7177 } catch (RemoteException e) { 7178 // Will never happen. 7179 } 7180 } 7181 7182 res.add(rti); 7183 maxNum--; 7184 } 7185 } 7186 return res; 7187 } 7188 } 7189 7190 private TaskRecord recentTaskForIdLocked(int id) { 7191 final int N = mRecentTasks.size(); 7192 for (int i=0; i<N; i++) { 7193 TaskRecord tr = mRecentTasks.get(i); 7194 if (tr.taskId == id) { 7195 return tr; 7196 } 7197 } 7198 return null; 7199 } 7200 7201 @Override 7202 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7203 synchronized (this) { 7204 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7205 "getTaskThumbnails()"); 7206 TaskRecord tr = recentTaskForIdLocked(id); 7207 if (tr != null) { 7208 return tr.getTaskThumbnailsLocked(); 7209 } 7210 } 7211 return null; 7212 } 7213 7214 @Override 7215 public Bitmap getTaskTopThumbnail(int id) { 7216 synchronized (this) { 7217 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7218 "getTaskTopThumbnail()"); 7219 TaskRecord tr = recentTaskForIdLocked(id); 7220 if (tr != null) { 7221 return tr.getTaskTopThumbnailLocked(); 7222 } 7223 } 7224 return null; 7225 } 7226 7227 @Override 7228 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7229 synchronized (this) { 7230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7231 if (r != null) { 7232 r.activityValues = rav; 7233 } 7234 } 7235 } 7236 7237 @Override 7238 public boolean removeSubTask(int taskId, int subTaskIndex) { 7239 synchronized (this) { 7240 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7241 "removeSubTask()"); 7242 long ident = Binder.clearCallingIdentity(); 7243 try { 7244 TaskRecord tr = recentTaskForIdLocked(taskId); 7245 if (tr != null) { 7246 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7247 } 7248 return false; 7249 } finally { 7250 Binder.restoreCallingIdentity(ident); 7251 } 7252 } 7253 } 7254 7255 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7256 if (!pr.killedByAm) { 7257 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7258 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7259 pr.processName, pr.setAdj, reason); 7260 pr.killedByAm = true; 7261 Process.killProcessQuiet(pr.pid); 7262 } 7263 } 7264 7265 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7266 tr.disposeThumbnail(); 7267 mRecentTasks.remove(tr); 7268 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7269 Intent baseIntent = new Intent( 7270 tr.intent != null ? tr.intent : tr.affinityIntent); 7271 ComponentName component = baseIntent.getComponent(); 7272 if (component == null) { 7273 Slog.w(TAG, "Now component for base intent of task: " + tr); 7274 return; 7275 } 7276 7277 // Find any running services associated with this app. 7278 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7279 7280 if (killProcesses) { 7281 // Find any running processes associated with this app. 7282 final String pkg = component.getPackageName(); 7283 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7284 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7285 for (int i=0; i<pmap.size(); i++) { 7286 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7287 for (int j=0; j<uids.size(); j++) { 7288 ProcessRecord proc = uids.valueAt(j); 7289 if (proc.userId != tr.userId) { 7290 continue; 7291 } 7292 if (!proc.pkgList.containsKey(pkg)) { 7293 continue; 7294 } 7295 procs.add(proc); 7296 } 7297 } 7298 7299 // Kill the running processes. 7300 for (int i=0; i<procs.size(); i++) { 7301 ProcessRecord pr = procs.get(i); 7302 if (pr == mHomeProcess) { 7303 // Don't kill the home process along with tasks from the same package. 7304 continue; 7305 } 7306 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7307 killUnneededProcessLocked(pr, "remove task"); 7308 } else { 7309 pr.waitingToKill = "remove task"; 7310 } 7311 } 7312 } 7313 } 7314 7315 /** 7316 * Removes the task with the specified task id. 7317 * 7318 * @param taskId Identifier of the task to be removed. 7319 * @param flags Additional operational flags. May be 0 or 7320 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7321 * @return Returns true if the given task was found and removed. 7322 */ 7323 private boolean removeTaskByIdLocked(int taskId, int flags) { 7324 TaskRecord tr = recentTaskForIdLocked(taskId); 7325 if (tr != null) { 7326 tr.removeTaskActivitiesLocked(-1, false); 7327 cleanUpRemovedTaskLocked(tr, flags); 7328 return true; 7329 } 7330 return false; 7331 } 7332 7333 @Override 7334 public boolean removeTask(int taskId, int flags) { 7335 synchronized (this) { 7336 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7337 "removeTask()"); 7338 long ident = Binder.clearCallingIdentity(); 7339 try { 7340 return removeTaskByIdLocked(taskId, flags); 7341 } finally { 7342 Binder.restoreCallingIdentity(ident); 7343 } 7344 } 7345 } 7346 7347 /** 7348 * TODO: Add mController hook 7349 */ 7350 @Override 7351 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7352 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7353 "moveTaskToFront()"); 7354 7355 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7356 synchronized(this) { 7357 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7358 Binder.getCallingUid(), "Task to front")) { 7359 ActivityOptions.abort(options); 7360 return; 7361 } 7362 final long origId = Binder.clearCallingIdentity(); 7363 try { 7364 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7365 if (task == null) { 7366 return; 7367 } 7368 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7369 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7370 return; 7371 } 7372 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7373 } finally { 7374 Binder.restoreCallingIdentity(origId); 7375 } 7376 ActivityOptions.abort(options); 7377 } 7378 } 7379 7380 @Override 7381 public void moveTaskToBack(int taskId) { 7382 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7383 "moveTaskToBack()"); 7384 7385 synchronized(this) { 7386 TaskRecord tr = recentTaskForIdLocked(taskId); 7387 if (tr != null) { 7388 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7389 ActivityStack stack = tr.stack; 7390 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7391 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7392 Binder.getCallingUid(), "Task to back")) { 7393 return; 7394 } 7395 } 7396 final long origId = Binder.clearCallingIdentity(); 7397 try { 7398 stack.moveTaskToBackLocked(taskId, null); 7399 } finally { 7400 Binder.restoreCallingIdentity(origId); 7401 } 7402 } 7403 } 7404 } 7405 7406 /** 7407 * Moves an activity, and all of the other activities within the same task, to the bottom 7408 * of the history stack. The activity's order within the task is unchanged. 7409 * 7410 * @param token A reference to the activity we wish to move 7411 * @param nonRoot If false then this only works if the activity is the root 7412 * of a task; if true it will work for any activity in a task. 7413 * @return Returns true if the move completed, false if not. 7414 */ 7415 @Override 7416 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7417 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7418 synchronized(this) { 7419 final long origId = Binder.clearCallingIdentity(); 7420 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7421 if (taskId >= 0) { 7422 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7423 } 7424 Binder.restoreCallingIdentity(origId); 7425 } 7426 return false; 7427 } 7428 7429 @Override 7430 public void moveTaskBackwards(int task) { 7431 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7432 "moveTaskBackwards()"); 7433 7434 synchronized(this) { 7435 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7436 Binder.getCallingUid(), "Task backwards")) { 7437 return; 7438 } 7439 final long origId = Binder.clearCallingIdentity(); 7440 moveTaskBackwardsLocked(task); 7441 Binder.restoreCallingIdentity(origId); 7442 } 7443 } 7444 7445 private final void moveTaskBackwardsLocked(int task) { 7446 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7447 } 7448 7449 @Override 7450 public IBinder getHomeActivityToken() throws RemoteException { 7451 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7452 "getHomeActivityToken()"); 7453 synchronized (this) { 7454 return mStackSupervisor.getHomeActivityToken(); 7455 } 7456 } 7457 7458 @Override 7459 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7460 IActivityContainerCallback callback) throws RemoteException { 7461 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7462 "createActivityContainer()"); 7463 synchronized (this) { 7464 if (parentActivityToken == null) { 7465 throw new IllegalArgumentException("parent token must not be null"); 7466 } 7467 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7468 if (r == null) { 7469 return null; 7470 } 7471 if (callback == null) { 7472 throw new IllegalArgumentException("callback must not be null"); 7473 } 7474 return mStackSupervisor.createActivityContainer(r, callback); 7475 } 7476 } 7477 7478 @Override 7479 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7480 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7481 "deleteActivityContainer()"); 7482 synchronized (this) { 7483 mStackSupervisor.deleteActivityContainer(container); 7484 } 7485 } 7486 7487 @Override 7488 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7489 throws RemoteException { 7490 synchronized (this) { 7491 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7492 if (stack != null) { 7493 return stack.mActivityContainer; 7494 } 7495 return null; 7496 } 7497 } 7498 7499 @Override 7500 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7501 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7502 "moveTaskToStack()"); 7503 if (stackId == HOME_STACK_ID) { 7504 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7505 new RuntimeException("here").fillInStackTrace()); 7506 } 7507 synchronized (this) { 7508 long ident = Binder.clearCallingIdentity(); 7509 try { 7510 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7511 + stackId + " toTop=" + toTop); 7512 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7513 } finally { 7514 Binder.restoreCallingIdentity(ident); 7515 } 7516 } 7517 } 7518 7519 @Override 7520 public void resizeStack(int stackBoxId, Rect bounds) { 7521 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7522 "resizeStackBox()"); 7523 long ident = Binder.clearCallingIdentity(); 7524 try { 7525 mWindowManager.resizeStack(stackBoxId, bounds); 7526 } finally { 7527 Binder.restoreCallingIdentity(ident); 7528 } 7529 } 7530 7531 @Override 7532 public List<StackInfo> getAllStackInfos() { 7533 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7534 "getAllStackInfos()"); 7535 long ident = Binder.clearCallingIdentity(); 7536 try { 7537 synchronized (this) { 7538 return mStackSupervisor.getAllStackInfosLocked(); 7539 } 7540 } finally { 7541 Binder.restoreCallingIdentity(ident); 7542 } 7543 } 7544 7545 @Override 7546 public StackInfo getStackInfo(int stackId) { 7547 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7548 "getStackInfo()"); 7549 long ident = Binder.clearCallingIdentity(); 7550 try { 7551 synchronized (this) { 7552 return mStackSupervisor.getStackInfoLocked(stackId); 7553 } 7554 } finally { 7555 Binder.restoreCallingIdentity(ident); 7556 } 7557 } 7558 7559 @Override 7560 public boolean isInHomeStack(int taskId) { 7561 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7562 "getStackInfo()"); 7563 long ident = Binder.clearCallingIdentity(); 7564 try { 7565 synchronized (this) { 7566 TaskRecord tr = recentTaskForIdLocked(taskId); 7567 if (tr != null) { 7568 return tr.stack.isHomeStack(); 7569 } 7570 } 7571 } finally { 7572 Binder.restoreCallingIdentity(ident); 7573 } 7574 return false; 7575 } 7576 7577 @Override 7578 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7579 synchronized(this) { 7580 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7581 } 7582 } 7583 7584 private boolean isLockTaskAuthorized(ComponentName name) { 7585// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7586// "startLockTaskMode()"); 7587// DevicePolicyManager dpm = (DevicePolicyManager) 7588// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7589// return dpm != null && dpm.isLockTaskPermitted(name); 7590 return true; 7591 } 7592 7593 private void startLockTaskMode(TaskRecord task) { 7594 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7595 return; 7596 } 7597 long ident = Binder.clearCallingIdentity(); 7598 try { 7599 synchronized (this) { 7600 // Since we lost lock on task, make sure it is still there. 7601 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7602 if (task != null) { 7603 mStackSupervisor.setLockTaskModeLocked(task); 7604 } 7605 } 7606 } finally { 7607 Binder.restoreCallingIdentity(ident); 7608 } 7609 } 7610 7611 @Override 7612 public void startLockTaskMode(int taskId) { 7613 long ident = Binder.clearCallingIdentity(); 7614 try { 7615 final TaskRecord task; 7616 synchronized (this) { 7617 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7618 } 7619 if (task != null) { 7620 startLockTaskMode(task); 7621 } 7622 } finally { 7623 Binder.restoreCallingIdentity(ident); 7624 } 7625 } 7626 7627 @Override 7628 public void startLockTaskMode(IBinder token) { 7629 long ident = Binder.clearCallingIdentity(); 7630 try { 7631 final TaskRecord task; 7632 synchronized (this) { 7633 final ActivityRecord r = ActivityRecord.forToken(token); 7634 if (r == null) { 7635 return; 7636 } 7637 task = r.task; 7638 } 7639 if (task != null) { 7640 startLockTaskMode(task); 7641 } 7642 } finally { 7643 Binder.restoreCallingIdentity(ident); 7644 } 7645 } 7646 7647 @Override 7648 public void stopLockTaskMode() { 7649// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7650// "stopLockTaskMode()"); 7651 synchronized (this) { 7652 mStackSupervisor.setLockTaskModeLocked(null); 7653 } 7654 } 7655 7656 @Override 7657 public boolean isInLockTaskMode() { 7658 synchronized (this) { 7659 return mStackSupervisor.isInLockTaskMode(); 7660 } 7661 } 7662 7663 // ========================================================= 7664 // CONTENT PROVIDERS 7665 // ========================================================= 7666 7667 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7668 List<ProviderInfo> providers = null; 7669 try { 7670 providers = AppGlobals.getPackageManager(). 7671 queryContentProviders(app.processName, app.uid, 7672 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7673 } catch (RemoteException ex) { 7674 } 7675 if (DEBUG_MU) 7676 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7677 int userId = app.userId; 7678 if (providers != null) { 7679 int N = providers.size(); 7680 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7681 for (int i=0; i<N; i++) { 7682 ProviderInfo cpi = 7683 (ProviderInfo)providers.get(i); 7684 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7685 cpi.name, cpi.flags); 7686 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7687 // This is a singleton provider, but a user besides the 7688 // default user is asking to initialize a process it runs 7689 // in... well, no, it doesn't actually run in this process, 7690 // it runs in the process of the default user. Get rid of it. 7691 providers.remove(i); 7692 N--; 7693 i--; 7694 continue; 7695 } 7696 7697 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7698 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7699 if (cpr == null) { 7700 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7701 mProviderMap.putProviderByClass(comp, cpr); 7702 } 7703 if (DEBUG_MU) 7704 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7705 app.pubProviders.put(cpi.name, cpr); 7706 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7707 // Don't add this if it is a platform component that is marked 7708 // to run in multiple processes, because this is actually 7709 // part of the framework so doesn't make sense to track as a 7710 // separate apk in the process. 7711 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7712 } 7713 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7714 } 7715 } 7716 return providers; 7717 } 7718 7719 /** 7720 * Check if {@link ProcessRecord} has a possible chance at accessing the 7721 * given {@link ProviderInfo}. Final permission checking is always done 7722 * in {@link ContentProvider}. 7723 */ 7724 private final String checkContentProviderPermissionLocked( 7725 ProviderInfo cpi, ProcessRecord r, int userId) { 7726 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7727 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7728 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7729 // Looking for cross-user grants before to enforce the typical cross-users permissions 7730 if (userId != UserHandle.getUserId(callingUid)) { 7731 if (perms != null) { 7732 for (GrantUri grantUri : perms.keySet()) { 7733 if (grantUri.sourceUserId == userId) { 7734 String authority = grantUri.uri.getAuthority(); 7735 if (authority.equals(cpi.authority)) { 7736 return null; 7737 } 7738 } 7739 } 7740 } 7741 } 7742 userId = handleIncomingUser(callingPid, callingUid, userId, 7743 false, true, "checkContentProviderPermissionLocked", null); 7744 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7745 cpi.applicationInfo.uid, cpi.exported) 7746 == PackageManager.PERMISSION_GRANTED) { 7747 return null; 7748 } 7749 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7750 cpi.applicationInfo.uid, cpi.exported) 7751 == PackageManager.PERMISSION_GRANTED) { 7752 return null; 7753 } 7754 7755 PathPermission[] pps = cpi.pathPermissions; 7756 if (pps != null) { 7757 int i = pps.length; 7758 while (i > 0) { 7759 i--; 7760 PathPermission pp = pps[i]; 7761 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7762 cpi.applicationInfo.uid, cpi.exported) 7763 == PackageManager.PERMISSION_GRANTED) { 7764 return null; 7765 } 7766 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7767 cpi.applicationInfo.uid, cpi.exported) 7768 == PackageManager.PERMISSION_GRANTED) { 7769 return null; 7770 } 7771 } 7772 } 7773 7774 if (perms != null) { 7775 for (GrantUri grantUri : perms.keySet()) { 7776 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7777 return null; 7778 } 7779 } 7780 } 7781 7782 String msg; 7783 if (!cpi.exported) { 7784 msg = "Permission Denial: opening provider " + cpi.name 7785 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7786 + ", uid=" + callingUid + ") that is not exported from uid " 7787 + cpi.applicationInfo.uid; 7788 } else { 7789 msg = "Permission Denial: opening provider " + cpi.name 7790 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7791 + ", uid=" + callingUid + ") requires " 7792 + cpi.readPermission + " or " + cpi.writePermission; 7793 } 7794 Slog.w(TAG, msg); 7795 return msg; 7796 } 7797 7798 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7799 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7800 if (r != null) { 7801 for (int i=0; i<r.conProviders.size(); i++) { 7802 ContentProviderConnection conn = r.conProviders.get(i); 7803 if (conn.provider == cpr) { 7804 if (DEBUG_PROVIDER) Slog.v(TAG, 7805 "Adding provider requested by " 7806 + r.processName + " from process " 7807 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7808 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7809 if (stable) { 7810 conn.stableCount++; 7811 conn.numStableIncs++; 7812 } else { 7813 conn.unstableCount++; 7814 conn.numUnstableIncs++; 7815 } 7816 return conn; 7817 } 7818 } 7819 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7820 if (stable) { 7821 conn.stableCount = 1; 7822 conn.numStableIncs = 1; 7823 } else { 7824 conn.unstableCount = 1; 7825 conn.numUnstableIncs = 1; 7826 } 7827 cpr.connections.add(conn); 7828 r.conProviders.add(conn); 7829 return conn; 7830 } 7831 cpr.addExternalProcessHandleLocked(externalProcessToken); 7832 return null; 7833 } 7834 7835 boolean decProviderCountLocked(ContentProviderConnection conn, 7836 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7837 if (conn != null) { 7838 cpr = conn.provider; 7839 if (DEBUG_PROVIDER) Slog.v(TAG, 7840 "Removing provider requested by " 7841 + conn.client.processName + " from process " 7842 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7843 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7844 if (stable) { 7845 conn.stableCount--; 7846 } else { 7847 conn.unstableCount--; 7848 } 7849 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7850 cpr.connections.remove(conn); 7851 conn.client.conProviders.remove(conn); 7852 return true; 7853 } 7854 return false; 7855 } 7856 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7857 return false; 7858 } 7859 7860 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7861 String name, IBinder token, boolean stable, int userId) { 7862 ContentProviderRecord cpr; 7863 ContentProviderConnection conn = null; 7864 ProviderInfo cpi = null; 7865 7866 synchronized(this) { 7867 ProcessRecord r = null; 7868 if (caller != null) { 7869 r = getRecordForAppLocked(caller); 7870 if (r == null) { 7871 throw new SecurityException( 7872 "Unable to find app for caller " + caller 7873 + " (pid=" + Binder.getCallingPid() 7874 + ") when getting content provider " + name); 7875 } 7876 } 7877 7878 // First check if this content provider has been published... 7879 cpr = mProviderMap.getProviderByName(name, userId); 7880 boolean providerRunning = cpr != null; 7881 if (providerRunning) { 7882 cpi = cpr.info; 7883 String msg; 7884 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7885 throw new SecurityException(msg); 7886 } 7887 7888 if (r != null && cpr.canRunHere(r)) { 7889 // This provider has been published or is in the process 7890 // of being published... but it is also allowed to run 7891 // in the caller's process, so don't make a connection 7892 // and just let the caller instantiate its own instance. 7893 ContentProviderHolder holder = cpr.newHolder(null); 7894 // don't give caller the provider object, it needs 7895 // to make its own. 7896 holder.provider = null; 7897 return holder; 7898 } 7899 7900 final long origId = Binder.clearCallingIdentity(); 7901 7902 // In this case the provider instance already exists, so we can 7903 // return it right away. 7904 conn = incProviderCountLocked(r, cpr, token, stable); 7905 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7906 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7907 // If this is a perceptible app accessing the provider, 7908 // make sure to count it as being accessed and thus 7909 // back up on the LRU list. This is good because 7910 // content providers are often expensive to start. 7911 updateLruProcessLocked(cpr.proc, false, null); 7912 } 7913 } 7914 7915 if (cpr.proc != null) { 7916 if (false) { 7917 if (cpr.name.flattenToShortString().equals( 7918 "com.android.providers.calendar/.CalendarProvider2")) { 7919 Slog.v(TAG, "****************** KILLING " 7920 + cpr.name.flattenToShortString()); 7921 Process.killProcess(cpr.proc.pid); 7922 } 7923 } 7924 boolean success = updateOomAdjLocked(cpr.proc); 7925 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7926 // NOTE: there is still a race here where a signal could be 7927 // pending on the process even though we managed to update its 7928 // adj level. Not sure what to do about this, but at least 7929 // the race is now smaller. 7930 if (!success) { 7931 // Uh oh... it looks like the provider's process 7932 // has been killed on us. We need to wait for a new 7933 // process to be started, and make sure its death 7934 // doesn't kill our process. 7935 Slog.i(TAG, 7936 "Existing provider " + cpr.name.flattenToShortString() 7937 + " is crashing; detaching " + r); 7938 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7939 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7940 if (!lastRef) { 7941 // This wasn't the last ref our process had on 7942 // the provider... we have now been killed, bail. 7943 return null; 7944 } 7945 providerRunning = false; 7946 conn = null; 7947 } 7948 } 7949 7950 Binder.restoreCallingIdentity(origId); 7951 } 7952 7953 boolean singleton; 7954 if (!providerRunning) { 7955 try { 7956 cpi = AppGlobals.getPackageManager(). 7957 resolveContentProvider(name, 7958 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7959 } catch (RemoteException ex) { 7960 } 7961 if (cpi == null) { 7962 return null; 7963 } 7964 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7965 cpi.name, cpi.flags); 7966 if (singleton) { 7967 userId = 0; 7968 } 7969 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7970 7971 String msg; 7972 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7973 throw new SecurityException(msg); 7974 } 7975 7976 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7977 && !cpi.processName.equals("system")) { 7978 // If this content provider does not run in the system 7979 // process, and the system is not yet ready to run other 7980 // processes, then fail fast instead of hanging. 7981 throw new IllegalArgumentException( 7982 "Attempt to launch content provider before system ready"); 7983 } 7984 7985 // Make sure that the user who owns this provider is started. If not, 7986 // we don't want to allow it to run. 7987 if (mStartedUsers.get(userId) == null) { 7988 Slog.w(TAG, "Unable to launch app " 7989 + cpi.applicationInfo.packageName + "/" 7990 + cpi.applicationInfo.uid + " for provider " 7991 + name + ": user " + userId + " is stopped"); 7992 return null; 7993 } 7994 7995 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7996 cpr = mProviderMap.getProviderByClass(comp, userId); 7997 final boolean firstClass = cpr == null; 7998 if (firstClass) { 7999 try { 8000 ApplicationInfo ai = 8001 AppGlobals.getPackageManager(). 8002 getApplicationInfo( 8003 cpi.applicationInfo.packageName, 8004 STOCK_PM_FLAGS, userId); 8005 if (ai == null) { 8006 Slog.w(TAG, "No package info for content provider " 8007 + cpi.name); 8008 return null; 8009 } 8010 ai = getAppInfoForUser(ai, userId); 8011 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8012 } catch (RemoteException ex) { 8013 // pm is in same process, this will never happen. 8014 } 8015 } 8016 8017 if (r != null && cpr.canRunHere(r)) { 8018 // If this is a multiprocess provider, then just return its 8019 // info and allow the caller to instantiate it. Only do 8020 // this if the provider is the same user as the caller's 8021 // process, or can run as root (so can be in any process). 8022 return cpr.newHolder(null); 8023 } 8024 8025 if (DEBUG_PROVIDER) { 8026 RuntimeException e = new RuntimeException("here"); 8027 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8028 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8029 } 8030 8031 // This is single process, and our app is now connecting to it. 8032 // See if we are already in the process of launching this 8033 // provider. 8034 final int N = mLaunchingProviders.size(); 8035 int i; 8036 for (i=0; i<N; i++) { 8037 if (mLaunchingProviders.get(i) == cpr) { 8038 break; 8039 } 8040 } 8041 8042 // If the provider is not already being launched, then get it 8043 // started. 8044 if (i >= N) { 8045 final long origId = Binder.clearCallingIdentity(); 8046 8047 try { 8048 // Content provider is now in use, its package can't be stopped. 8049 try { 8050 AppGlobals.getPackageManager().setPackageStoppedState( 8051 cpr.appInfo.packageName, false, userId); 8052 } catch (RemoteException e) { 8053 } catch (IllegalArgumentException e) { 8054 Slog.w(TAG, "Failed trying to unstop package " 8055 + cpr.appInfo.packageName + ": " + e); 8056 } 8057 8058 // Use existing process if already started 8059 ProcessRecord proc = getProcessRecordLocked( 8060 cpi.processName, cpr.appInfo.uid, false); 8061 if (proc != null && proc.thread != null) { 8062 if (DEBUG_PROVIDER) { 8063 Slog.d(TAG, "Installing in existing process " + proc); 8064 } 8065 proc.pubProviders.put(cpi.name, cpr); 8066 try { 8067 proc.thread.scheduleInstallProvider(cpi); 8068 } catch (RemoteException e) { 8069 } 8070 } else { 8071 proc = startProcessLocked(cpi.processName, 8072 cpr.appInfo, false, 0, "content provider", 8073 new ComponentName(cpi.applicationInfo.packageName, 8074 cpi.name), false, false, false); 8075 if (proc == null) { 8076 Slog.w(TAG, "Unable to launch app " 8077 + cpi.applicationInfo.packageName + "/" 8078 + cpi.applicationInfo.uid + " for provider " 8079 + name + ": process is bad"); 8080 return null; 8081 } 8082 } 8083 cpr.launchingApp = proc; 8084 mLaunchingProviders.add(cpr); 8085 } finally { 8086 Binder.restoreCallingIdentity(origId); 8087 } 8088 } 8089 8090 // Make sure the provider is published (the same provider class 8091 // may be published under multiple names). 8092 if (firstClass) { 8093 mProviderMap.putProviderByClass(comp, cpr); 8094 } 8095 8096 mProviderMap.putProviderByName(name, cpr); 8097 conn = incProviderCountLocked(r, cpr, token, stable); 8098 if (conn != null) { 8099 conn.waiting = true; 8100 } 8101 } 8102 } 8103 8104 // Wait for the provider to be published... 8105 synchronized (cpr) { 8106 while (cpr.provider == null) { 8107 if (cpr.launchingApp == null) { 8108 Slog.w(TAG, "Unable to launch app " 8109 + cpi.applicationInfo.packageName + "/" 8110 + cpi.applicationInfo.uid + " for provider " 8111 + name + ": launching app became null"); 8112 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8113 UserHandle.getUserId(cpi.applicationInfo.uid), 8114 cpi.applicationInfo.packageName, 8115 cpi.applicationInfo.uid, name); 8116 return null; 8117 } 8118 try { 8119 if (DEBUG_MU) { 8120 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8121 + cpr.launchingApp); 8122 } 8123 if (conn != null) { 8124 conn.waiting = true; 8125 } 8126 cpr.wait(); 8127 } catch (InterruptedException ex) { 8128 } finally { 8129 if (conn != null) { 8130 conn.waiting = false; 8131 } 8132 } 8133 } 8134 } 8135 return cpr != null ? cpr.newHolder(conn) : null; 8136 } 8137 8138 @Override 8139 public final ContentProviderHolder getContentProvider( 8140 IApplicationThread caller, String name, int userId, boolean stable) { 8141 enforceNotIsolatedCaller("getContentProvider"); 8142 if (caller == null) { 8143 String msg = "null IApplicationThread when getting content provider " 8144 + name; 8145 Slog.w(TAG, msg); 8146 throw new SecurityException(msg); 8147 } 8148 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8149 // with cross-user grant. 8150 return getContentProviderImpl(caller, name, null, stable, userId); 8151 } 8152 8153 public ContentProviderHolder getContentProviderExternal( 8154 String name, int userId, IBinder token) { 8155 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8156 "Do not have permission in call getContentProviderExternal()"); 8157 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8158 false, true, "getContentProvider", null); 8159 return getContentProviderExternalUnchecked(name, token, userId); 8160 } 8161 8162 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8163 IBinder token, int userId) { 8164 return getContentProviderImpl(null, name, token, true, userId); 8165 } 8166 8167 /** 8168 * Drop a content provider from a ProcessRecord's bookkeeping 8169 */ 8170 public void removeContentProvider(IBinder connection, boolean stable) { 8171 enforceNotIsolatedCaller("removeContentProvider"); 8172 long ident = Binder.clearCallingIdentity(); 8173 try { 8174 synchronized (this) { 8175 ContentProviderConnection conn; 8176 try { 8177 conn = (ContentProviderConnection)connection; 8178 } catch (ClassCastException e) { 8179 String msg ="removeContentProvider: " + connection 8180 + " not a ContentProviderConnection"; 8181 Slog.w(TAG, msg); 8182 throw new IllegalArgumentException(msg); 8183 } 8184 if (conn == null) { 8185 throw new NullPointerException("connection is null"); 8186 } 8187 if (decProviderCountLocked(conn, null, null, stable)) { 8188 updateOomAdjLocked(); 8189 } 8190 } 8191 } finally { 8192 Binder.restoreCallingIdentity(ident); 8193 } 8194 } 8195 8196 public void removeContentProviderExternal(String name, IBinder token) { 8197 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8198 "Do not have permission in call removeContentProviderExternal()"); 8199 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8200 } 8201 8202 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8203 synchronized (this) { 8204 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8205 if(cpr == null) { 8206 //remove from mProvidersByClass 8207 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8208 return; 8209 } 8210 8211 //update content provider record entry info 8212 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8213 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8214 if (localCpr.hasExternalProcessHandles()) { 8215 if (localCpr.removeExternalProcessHandleLocked(token)) { 8216 updateOomAdjLocked(); 8217 } else { 8218 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8219 + " with no external reference for token: " 8220 + token + "."); 8221 } 8222 } else { 8223 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8224 + " with no external references."); 8225 } 8226 } 8227 } 8228 8229 public final void publishContentProviders(IApplicationThread caller, 8230 List<ContentProviderHolder> providers) { 8231 if (providers == null) { 8232 return; 8233 } 8234 8235 enforceNotIsolatedCaller("publishContentProviders"); 8236 synchronized (this) { 8237 final ProcessRecord r = getRecordForAppLocked(caller); 8238 if (DEBUG_MU) 8239 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8240 if (r == null) { 8241 throw new SecurityException( 8242 "Unable to find app for caller " + caller 8243 + " (pid=" + Binder.getCallingPid() 8244 + ") when publishing content providers"); 8245 } 8246 8247 final long origId = Binder.clearCallingIdentity(); 8248 8249 final int N = providers.size(); 8250 for (int i=0; i<N; i++) { 8251 ContentProviderHolder src = providers.get(i); 8252 if (src == null || src.info == null || src.provider == null) { 8253 continue; 8254 } 8255 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8256 if (DEBUG_MU) 8257 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8258 if (dst != null) { 8259 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8260 mProviderMap.putProviderByClass(comp, dst); 8261 String names[] = dst.info.authority.split(";"); 8262 for (int j = 0; j < names.length; j++) { 8263 mProviderMap.putProviderByName(names[j], dst); 8264 } 8265 8266 int NL = mLaunchingProviders.size(); 8267 int j; 8268 for (j=0; j<NL; j++) { 8269 if (mLaunchingProviders.get(j) == dst) { 8270 mLaunchingProviders.remove(j); 8271 j--; 8272 NL--; 8273 } 8274 } 8275 synchronized (dst) { 8276 dst.provider = src.provider; 8277 dst.proc = r; 8278 dst.notifyAll(); 8279 } 8280 updateOomAdjLocked(r); 8281 } 8282 } 8283 8284 Binder.restoreCallingIdentity(origId); 8285 } 8286 } 8287 8288 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8289 ContentProviderConnection conn; 8290 try { 8291 conn = (ContentProviderConnection)connection; 8292 } catch (ClassCastException e) { 8293 String msg ="refContentProvider: " + connection 8294 + " not a ContentProviderConnection"; 8295 Slog.w(TAG, msg); 8296 throw new IllegalArgumentException(msg); 8297 } 8298 if (conn == null) { 8299 throw new NullPointerException("connection is null"); 8300 } 8301 8302 synchronized (this) { 8303 if (stable > 0) { 8304 conn.numStableIncs += stable; 8305 } 8306 stable = conn.stableCount + stable; 8307 if (stable < 0) { 8308 throw new IllegalStateException("stableCount < 0: " + stable); 8309 } 8310 8311 if (unstable > 0) { 8312 conn.numUnstableIncs += unstable; 8313 } 8314 unstable = conn.unstableCount + unstable; 8315 if (unstable < 0) { 8316 throw new IllegalStateException("unstableCount < 0: " + unstable); 8317 } 8318 8319 if ((stable+unstable) <= 0) { 8320 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8321 + stable + " unstable=" + unstable); 8322 } 8323 conn.stableCount = stable; 8324 conn.unstableCount = unstable; 8325 return !conn.dead; 8326 } 8327 } 8328 8329 public void unstableProviderDied(IBinder connection) { 8330 ContentProviderConnection conn; 8331 try { 8332 conn = (ContentProviderConnection)connection; 8333 } catch (ClassCastException e) { 8334 String msg ="refContentProvider: " + connection 8335 + " not a ContentProviderConnection"; 8336 Slog.w(TAG, msg); 8337 throw new IllegalArgumentException(msg); 8338 } 8339 if (conn == null) { 8340 throw new NullPointerException("connection is null"); 8341 } 8342 8343 // Safely retrieve the content provider associated with the connection. 8344 IContentProvider provider; 8345 synchronized (this) { 8346 provider = conn.provider.provider; 8347 } 8348 8349 if (provider == null) { 8350 // Um, yeah, we're way ahead of you. 8351 return; 8352 } 8353 8354 // Make sure the caller is being honest with us. 8355 if (provider.asBinder().pingBinder()) { 8356 // Er, no, still looks good to us. 8357 synchronized (this) { 8358 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8359 + " says " + conn + " died, but we don't agree"); 8360 return; 8361 } 8362 } 8363 8364 // Well look at that! It's dead! 8365 synchronized (this) { 8366 if (conn.provider.provider != provider) { 8367 // But something changed... good enough. 8368 return; 8369 } 8370 8371 ProcessRecord proc = conn.provider.proc; 8372 if (proc == null || proc.thread == null) { 8373 // Seems like the process is already cleaned up. 8374 return; 8375 } 8376 8377 // As far as we're concerned, this is just like receiving a 8378 // death notification... just a bit prematurely. 8379 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8380 + ") early provider death"); 8381 final long ident = Binder.clearCallingIdentity(); 8382 try { 8383 appDiedLocked(proc, proc.pid, proc.thread); 8384 } finally { 8385 Binder.restoreCallingIdentity(ident); 8386 } 8387 } 8388 } 8389 8390 @Override 8391 public void appNotRespondingViaProvider(IBinder connection) { 8392 enforceCallingPermission( 8393 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8394 8395 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8396 if (conn == null) { 8397 Slog.w(TAG, "ContentProviderConnection is null"); 8398 return; 8399 } 8400 8401 final ProcessRecord host = conn.provider.proc; 8402 if (host == null) { 8403 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8404 return; 8405 } 8406 8407 final long token = Binder.clearCallingIdentity(); 8408 try { 8409 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8410 } finally { 8411 Binder.restoreCallingIdentity(token); 8412 } 8413 } 8414 8415 public final void installSystemProviders() { 8416 List<ProviderInfo> providers; 8417 synchronized (this) { 8418 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8419 providers = generateApplicationProvidersLocked(app); 8420 if (providers != null) { 8421 for (int i=providers.size()-1; i>=0; i--) { 8422 ProviderInfo pi = (ProviderInfo)providers.get(i); 8423 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8424 Slog.w(TAG, "Not installing system proc provider " + pi.name 8425 + ": not system .apk"); 8426 providers.remove(i); 8427 } 8428 } 8429 } 8430 } 8431 if (providers != null) { 8432 mSystemThread.installSystemProviders(providers); 8433 } 8434 8435 mCoreSettingsObserver = new CoreSettingsObserver(this); 8436 8437 mUsageStatsService.monitorPackages(); 8438 } 8439 8440 /** 8441 * Allows app to retrieve the MIME type of a URI without having permission 8442 * to access its content provider. 8443 * 8444 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8445 * 8446 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8447 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8448 */ 8449 public String getProviderMimeType(Uri uri, int userId) { 8450 enforceNotIsolatedCaller("getProviderMimeType"); 8451 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8452 userId, false, true, "getProviderMimeType", null); 8453 final String name = uri.getAuthority(); 8454 final long ident = Binder.clearCallingIdentity(); 8455 ContentProviderHolder holder = null; 8456 8457 try { 8458 holder = getContentProviderExternalUnchecked(name, null, userId); 8459 if (holder != null) { 8460 return holder.provider.getType(uri); 8461 } 8462 } catch (RemoteException e) { 8463 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8464 return null; 8465 } finally { 8466 if (holder != null) { 8467 removeContentProviderExternalUnchecked(name, null, userId); 8468 } 8469 Binder.restoreCallingIdentity(ident); 8470 } 8471 8472 return null; 8473 } 8474 8475 // ========================================================= 8476 // GLOBAL MANAGEMENT 8477 // ========================================================= 8478 8479 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8480 boolean isolated) { 8481 String proc = customProcess != null ? customProcess : info.processName; 8482 BatteryStatsImpl.Uid.Proc ps = null; 8483 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8484 int uid = info.uid; 8485 if (isolated) { 8486 int userId = UserHandle.getUserId(uid); 8487 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8488 while (true) { 8489 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8490 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8491 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8492 } 8493 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8494 mNextIsolatedProcessUid++; 8495 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8496 // No process for this uid, use it. 8497 break; 8498 } 8499 stepsLeft--; 8500 if (stepsLeft <= 0) { 8501 return null; 8502 } 8503 } 8504 } 8505 return new ProcessRecord(stats, info, proc, uid); 8506 } 8507 8508 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8509 ProcessRecord app; 8510 if (!isolated) { 8511 app = getProcessRecordLocked(info.processName, info.uid, true); 8512 } else { 8513 app = null; 8514 } 8515 8516 if (app == null) { 8517 app = newProcessRecordLocked(info, null, isolated); 8518 mProcessNames.put(info.processName, app.uid, app); 8519 if (isolated) { 8520 mIsolatedProcesses.put(app.uid, app); 8521 } 8522 updateLruProcessLocked(app, false, null); 8523 updateOomAdjLocked(); 8524 } 8525 8526 // This package really, really can not be stopped. 8527 try { 8528 AppGlobals.getPackageManager().setPackageStoppedState( 8529 info.packageName, false, UserHandle.getUserId(app.uid)); 8530 } catch (RemoteException e) { 8531 } catch (IllegalArgumentException e) { 8532 Slog.w(TAG, "Failed trying to unstop package " 8533 + info.packageName + ": " + e); 8534 } 8535 8536 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8537 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8538 app.persistent = true; 8539 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8540 } 8541 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8542 mPersistentStartingProcesses.add(app); 8543 startProcessLocked(app, "added application", app.processName); 8544 } 8545 8546 return app; 8547 } 8548 8549 public void unhandledBack() { 8550 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8551 "unhandledBack()"); 8552 8553 synchronized(this) { 8554 final long origId = Binder.clearCallingIdentity(); 8555 try { 8556 getFocusedStack().unhandledBackLocked(); 8557 } finally { 8558 Binder.restoreCallingIdentity(origId); 8559 } 8560 } 8561 } 8562 8563 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8564 enforceNotIsolatedCaller("openContentUri"); 8565 final int userId = UserHandle.getCallingUserId(); 8566 String name = uri.getAuthority(); 8567 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8568 ParcelFileDescriptor pfd = null; 8569 if (cph != null) { 8570 // We record the binder invoker's uid in thread-local storage before 8571 // going to the content provider to open the file. Later, in the code 8572 // that handles all permissions checks, we look for this uid and use 8573 // that rather than the Activity Manager's own uid. The effect is that 8574 // we do the check against the caller's permissions even though it looks 8575 // to the content provider like the Activity Manager itself is making 8576 // the request. 8577 sCallerIdentity.set(new Identity( 8578 Binder.getCallingPid(), Binder.getCallingUid())); 8579 try { 8580 pfd = cph.provider.openFile(null, uri, "r", null); 8581 } catch (FileNotFoundException e) { 8582 // do nothing; pfd will be returned null 8583 } finally { 8584 // Ensure that whatever happens, we clean up the identity state 8585 sCallerIdentity.remove(); 8586 } 8587 8588 // We've got the fd now, so we're done with the provider. 8589 removeContentProviderExternalUnchecked(name, null, userId); 8590 } else { 8591 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8592 } 8593 return pfd; 8594 } 8595 8596 // Actually is sleeping or shutting down or whatever else in the future 8597 // is an inactive state. 8598 public boolean isSleepingOrShuttingDown() { 8599 return mSleeping || mShuttingDown; 8600 } 8601 8602 public boolean isSleeping() { 8603 return mSleeping; 8604 } 8605 8606 void goingToSleep() { 8607 synchronized(this) { 8608 mWentToSleep = true; 8609 updateEventDispatchingLocked(); 8610 goToSleepIfNeededLocked(); 8611 } 8612 } 8613 8614 void finishRunningVoiceLocked() { 8615 if (mRunningVoice) { 8616 mRunningVoice = false; 8617 goToSleepIfNeededLocked(); 8618 } 8619 } 8620 8621 void goToSleepIfNeededLocked() { 8622 if (mWentToSleep && !mRunningVoice) { 8623 if (!mSleeping) { 8624 mSleeping = true; 8625 mStackSupervisor.goingToSleepLocked(); 8626 8627 // Initialize the wake times of all processes. 8628 checkExcessivePowerUsageLocked(false); 8629 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8630 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8631 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8632 } 8633 } 8634 } 8635 8636 @Override 8637 public boolean shutdown(int timeout) { 8638 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8639 != PackageManager.PERMISSION_GRANTED) { 8640 throw new SecurityException("Requires permission " 8641 + android.Manifest.permission.SHUTDOWN); 8642 } 8643 8644 boolean timedout = false; 8645 8646 synchronized(this) { 8647 mShuttingDown = true; 8648 updateEventDispatchingLocked(); 8649 timedout = mStackSupervisor.shutdownLocked(timeout); 8650 } 8651 8652 mAppOpsService.shutdown(); 8653 mUsageStatsService.shutdown(); 8654 mBatteryStatsService.shutdown(); 8655 synchronized (this) { 8656 mProcessStats.shutdownLocked(); 8657 } 8658 8659 return timedout; 8660 } 8661 8662 public final void activitySlept(IBinder token) { 8663 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8664 8665 final long origId = Binder.clearCallingIdentity(); 8666 8667 synchronized (this) { 8668 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8669 if (r != null) { 8670 mStackSupervisor.activitySleptLocked(r); 8671 } 8672 } 8673 8674 Binder.restoreCallingIdentity(origId); 8675 } 8676 8677 void logLockScreen(String msg) { 8678 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8679 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8680 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8681 mStackSupervisor.mDismissKeyguardOnNextActivity); 8682 } 8683 8684 private void comeOutOfSleepIfNeededLocked() { 8685 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8686 if (mSleeping) { 8687 mSleeping = false; 8688 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8689 } 8690 } 8691 } 8692 8693 void wakingUp() { 8694 synchronized(this) { 8695 mWentToSleep = false; 8696 updateEventDispatchingLocked(); 8697 comeOutOfSleepIfNeededLocked(); 8698 } 8699 } 8700 8701 void startRunningVoiceLocked() { 8702 if (!mRunningVoice) { 8703 mRunningVoice = true; 8704 comeOutOfSleepIfNeededLocked(); 8705 } 8706 } 8707 8708 private void updateEventDispatchingLocked() { 8709 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8710 } 8711 8712 public void setLockScreenShown(boolean shown) { 8713 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8714 != PackageManager.PERMISSION_GRANTED) { 8715 throw new SecurityException("Requires permission " 8716 + android.Manifest.permission.DEVICE_POWER); 8717 } 8718 8719 synchronized(this) { 8720 long ident = Binder.clearCallingIdentity(); 8721 try { 8722 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8723 mLockScreenShown = shown; 8724 comeOutOfSleepIfNeededLocked(); 8725 } finally { 8726 Binder.restoreCallingIdentity(ident); 8727 } 8728 } 8729 } 8730 8731 public void stopAppSwitches() { 8732 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8733 != PackageManager.PERMISSION_GRANTED) { 8734 throw new SecurityException("Requires permission " 8735 + android.Manifest.permission.STOP_APP_SWITCHES); 8736 } 8737 8738 synchronized(this) { 8739 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8740 + APP_SWITCH_DELAY_TIME; 8741 mDidAppSwitch = false; 8742 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8743 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8744 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8745 } 8746 } 8747 8748 public void resumeAppSwitches() { 8749 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8750 != PackageManager.PERMISSION_GRANTED) { 8751 throw new SecurityException("Requires permission " 8752 + android.Manifest.permission.STOP_APP_SWITCHES); 8753 } 8754 8755 synchronized(this) { 8756 // Note that we don't execute any pending app switches... we will 8757 // let those wait until either the timeout, or the next start 8758 // activity request. 8759 mAppSwitchesAllowedTime = 0; 8760 } 8761 } 8762 8763 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8764 String name) { 8765 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8766 return true; 8767 } 8768 8769 final int perm = checkComponentPermission( 8770 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8771 callingUid, -1, true); 8772 if (perm == PackageManager.PERMISSION_GRANTED) { 8773 return true; 8774 } 8775 8776 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8777 return false; 8778 } 8779 8780 public void setDebugApp(String packageName, boolean waitForDebugger, 8781 boolean persistent) { 8782 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8783 "setDebugApp()"); 8784 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 // Note that this is not really thread safe if there are multiple 8788 // callers into it at the same time, but that's not a situation we 8789 // care about. 8790 if (persistent) { 8791 final ContentResolver resolver = mContext.getContentResolver(); 8792 Settings.Global.putString( 8793 resolver, Settings.Global.DEBUG_APP, 8794 packageName); 8795 Settings.Global.putInt( 8796 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8797 waitForDebugger ? 1 : 0); 8798 } 8799 8800 synchronized (this) { 8801 if (!persistent) { 8802 mOrigDebugApp = mDebugApp; 8803 mOrigWaitForDebugger = mWaitForDebugger; 8804 } 8805 mDebugApp = packageName; 8806 mWaitForDebugger = waitForDebugger; 8807 mDebugTransient = !persistent; 8808 if (packageName != null) { 8809 forceStopPackageLocked(packageName, -1, false, false, true, true, 8810 false, UserHandle.USER_ALL, "set debug app"); 8811 } 8812 } 8813 } finally { 8814 Binder.restoreCallingIdentity(ident); 8815 } 8816 } 8817 8818 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8819 synchronized (this) { 8820 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8821 if (!isDebuggable) { 8822 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8823 throw new SecurityException("Process not debuggable: " + app.packageName); 8824 } 8825 } 8826 8827 mOpenGlTraceApp = processName; 8828 } 8829 } 8830 8831 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8832 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8833 synchronized (this) { 8834 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8835 if (!isDebuggable) { 8836 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8837 throw new SecurityException("Process not debuggable: " + app.packageName); 8838 } 8839 } 8840 mProfileApp = processName; 8841 mProfileFile = profileFile; 8842 if (mProfileFd != null) { 8843 try { 8844 mProfileFd.close(); 8845 } catch (IOException e) { 8846 } 8847 mProfileFd = null; 8848 } 8849 mProfileFd = profileFd; 8850 mProfileType = 0; 8851 mAutoStopProfiler = autoStopProfiler; 8852 } 8853 } 8854 8855 @Override 8856 public void setAlwaysFinish(boolean enabled) { 8857 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8858 "setAlwaysFinish()"); 8859 8860 Settings.Global.putInt( 8861 mContext.getContentResolver(), 8862 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8863 8864 synchronized (this) { 8865 mAlwaysFinishActivities = enabled; 8866 } 8867 } 8868 8869 @Override 8870 public void setActivityController(IActivityController controller) { 8871 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8872 "setActivityController()"); 8873 synchronized (this) { 8874 mController = controller; 8875 Watchdog.getInstance().setActivityController(controller); 8876 } 8877 } 8878 8879 @Override 8880 public void setUserIsMonkey(boolean userIsMonkey) { 8881 synchronized (this) { 8882 synchronized (mPidsSelfLocked) { 8883 final int callingPid = Binder.getCallingPid(); 8884 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8885 if (precessRecord == null) { 8886 throw new SecurityException("Unknown process: " + callingPid); 8887 } 8888 if (precessRecord.instrumentationUiAutomationConnection == null) { 8889 throw new SecurityException("Only an instrumentation process " 8890 + "with a UiAutomation can call setUserIsMonkey"); 8891 } 8892 } 8893 mUserIsMonkey = userIsMonkey; 8894 } 8895 } 8896 8897 @Override 8898 public boolean isUserAMonkey() { 8899 synchronized (this) { 8900 // If there is a controller also implies the user is a monkey. 8901 return (mUserIsMonkey || mController != null); 8902 } 8903 } 8904 8905 public void requestBugReport() { 8906 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8907 SystemProperties.set("ctl.start", "bugreport"); 8908 } 8909 8910 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8911 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8912 } 8913 8914 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8915 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8916 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8917 } 8918 return KEY_DISPATCHING_TIMEOUT; 8919 } 8920 8921 @Override 8922 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8923 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8924 != PackageManager.PERMISSION_GRANTED) { 8925 throw new SecurityException("Requires permission " 8926 + android.Manifest.permission.FILTER_EVENTS); 8927 } 8928 ProcessRecord proc; 8929 long timeout; 8930 synchronized (this) { 8931 synchronized (mPidsSelfLocked) { 8932 proc = mPidsSelfLocked.get(pid); 8933 } 8934 timeout = getInputDispatchingTimeoutLocked(proc); 8935 } 8936 8937 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8938 return -1; 8939 } 8940 8941 return timeout; 8942 } 8943 8944 /** 8945 * Handle input dispatching timeouts. 8946 * Returns whether input dispatching should be aborted or not. 8947 */ 8948 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8949 final ActivityRecord activity, final ActivityRecord parent, 8950 final boolean aboveSystem, String reason) { 8951 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8952 != PackageManager.PERMISSION_GRANTED) { 8953 throw new SecurityException("Requires permission " 8954 + android.Manifest.permission.FILTER_EVENTS); 8955 } 8956 8957 final String annotation; 8958 if (reason == null) { 8959 annotation = "Input dispatching timed out"; 8960 } else { 8961 annotation = "Input dispatching timed out (" + reason + ")"; 8962 } 8963 8964 if (proc != null) { 8965 synchronized (this) { 8966 if (proc.debugging) { 8967 return false; 8968 } 8969 8970 if (mDidDexOpt) { 8971 // Give more time since we were dexopting. 8972 mDidDexOpt = false; 8973 return false; 8974 } 8975 8976 if (proc.instrumentationClass != null) { 8977 Bundle info = new Bundle(); 8978 info.putString("shortMsg", "keyDispatchingTimedOut"); 8979 info.putString("longMsg", annotation); 8980 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8981 return true; 8982 } 8983 } 8984 mHandler.post(new Runnable() { 8985 @Override 8986 public void run() { 8987 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8988 } 8989 }); 8990 } 8991 8992 return true; 8993 } 8994 8995 public Bundle getAssistContextExtras(int requestType) { 8996 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8997 "getAssistContextExtras()"); 8998 PendingAssistExtras pae; 8999 Bundle extras = new Bundle(); 9000 synchronized (this) { 9001 ActivityRecord activity = getFocusedStack().mResumedActivity; 9002 if (activity == null) { 9003 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9004 return null; 9005 } 9006 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9007 if (activity.app == null || activity.app.thread == null) { 9008 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9009 return extras; 9010 } 9011 if (activity.app.pid == Binder.getCallingPid()) { 9012 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9013 return extras; 9014 } 9015 pae = new PendingAssistExtras(activity); 9016 try { 9017 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9018 requestType); 9019 mPendingAssistExtras.add(pae); 9020 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9021 } catch (RemoteException e) { 9022 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9023 return extras; 9024 } 9025 } 9026 synchronized (pae) { 9027 while (!pae.haveResult) { 9028 try { 9029 pae.wait(); 9030 } catch (InterruptedException e) { 9031 } 9032 } 9033 if (pae.result != null) { 9034 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9035 } 9036 } 9037 synchronized (this) { 9038 mPendingAssistExtras.remove(pae); 9039 mHandler.removeCallbacks(pae); 9040 } 9041 return extras; 9042 } 9043 9044 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9045 PendingAssistExtras pae = (PendingAssistExtras)token; 9046 synchronized (pae) { 9047 pae.result = extras; 9048 pae.haveResult = true; 9049 pae.notifyAll(); 9050 } 9051 } 9052 9053 public void registerProcessObserver(IProcessObserver observer) { 9054 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9055 "registerProcessObserver()"); 9056 synchronized (this) { 9057 mProcessObservers.register(observer); 9058 } 9059 } 9060 9061 @Override 9062 public void unregisterProcessObserver(IProcessObserver observer) { 9063 synchronized (this) { 9064 mProcessObservers.unregister(observer); 9065 } 9066 } 9067 9068 @Override 9069 public boolean convertFromTranslucent(IBinder token) { 9070 final long origId = Binder.clearCallingIdentity(); 9071 try { 9072 synchronized (this) { 9073 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9074 if (r == null) { 9075 return false; 9076 } 9077 if (r.changeWindowTranslucency(true)) { 9078 mWindowManager.setAppFullscreen(token, true); 9079 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9080 return true; 9081 } 9082 return false; 9083 } 9084 } finally { 9085 Binder.restoreCallingIdentity(origId); 9086 } 9087 } 9088 9089 @Override 9090 public boolean convertToTranslucent(IBinder token) { 9091 final long origId = Binder.clearCallingIdentity(); 9092 try { 9093 synchronized (this) { 9094 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9095 if (r == null) { 9096 return false; 9097 } 9098 if (r.changeWindowTranslucency(false)) { 9099 r.task.stack.convertToTranslucent(r); 9100 mWindowManager.setAppFullscreen(token, false); 9101 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9102 return true; 9103 } 9104 return false; 9105 } 9106 } finally { 9107 Binder.restoreCallingIdentity(origId); 9108 } 9109 } 9110 9111 @Override 9112 public void setImmersive(IBinder token, boolean immersive) { 9113 synchronized(this) { 9114 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9115 if (r == null) { 9116 throw new IllegalArgumentException(); 9117 } 9118 r.immersive = immersive; 9119 9120 // update associated state if we're frontmost 9121 if (r == mFocusedActivity) { 9122 if (DEBUG_IMMERSIVE) { 9123 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9124 } 9125 applyUpdateLockStateLocked(r); 9126 } 9127 } 9128 } 9129 9130 @Override 9131 public boolean isImmersive(IBinder token) { 9132 synchronized (this) { 9133 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9134 if (r == null) { 9135 throw new IllegalArgumentException(); 9136 } 9137 return r.immersive; 9138 } 9139 } 9140 9141 public boolean isTopActivityImmersive() { 9142 enforceNotIsolatedCaller("startActivity"); 9143 synchronized (this) { 9144 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9145 return (r != null) ? r.immersive : false; 9146 } 9147 } 9148 9149 public final void enterSafeMode() { 9150 synchronized(this) { 9151 // It only makes sense to do this before the system is ready 9152 // and started launching other packages. 9153 if (!mSystemReady) { 9154 try { 9155 AppGlobals.getPackageManager().enterSafeMode(); 9156 } catch (RemoteException e) { 9157 } 9158 } 9159 9160 mSafeMode = true; 9161 } 9162 } 9163 9164 public final void showSafeModeOverlay() { 9165 View v = LayoutInflater.from(mContext).inflate( 9166 com.android.internal.R.layout.safe_mode, null); 9167 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9168 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9169 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9170 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9171 lp.gravity = Gravity.BOTTOM | Gravity.START; 9172 lp.format = v.getBackground().getOpacity(); 9173 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9174 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9175 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9176 ((WindowManager)mContext.getSystemService( 9177 Context.WINDOW_SERVICE)).addView(v, lp); 9178 } 9179 9180 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9181 if (!(sender instanceof PendingIntentRecord)) { 9182 return; 9183 } 9184 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9185 synchronized (stats) { 9186 if (mBatteryStatsService.isOnBattery()) { 9187 mBatteryStatsService.enforceCallingPermission(); 9188 PendingIntentRecord rec = (PendingIntentRecord)sender; 9189 int MY_UID = Binder.getCallingUid(); 9190 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9191 BatteryStatsImpl.Uid.Pkg pkg = 9192 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9193 sourcePkg != null ? sourcePkg : rec.key.packageName); 9194 pkg.incWakeupsLocked(); 9195 } 9196 } 9197 } 9198 9199 public boolean killPids(int[] pids, String pReason, boolean secure) { 9200 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9201 throw new SecurityException("killPids only available to the system"); 9202 } 9203 String reason = (pReason == null) ? "Unknown" : pReason; 9204 // XXX Note: don't acquire main activity lock here, because the window 9205 // manager calls in with its locks held. 9206 9207 boolean killed = false; 9208 synchronized (mPidsSelfLocked) { 9209 int[] types = new int[pids.length]; 9210 int worstType = 0; 9211 for (int i=0; i<pids.length; i++) { 9212 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9213 if (proc != null) { 9214 int type = proc.setAdj; 9215 types[i] = type; 9216 if (type > worstType) { 9217 worstType = type; 9218 } 9219 } 9220 } 9221 9222 // If the worst oom_adj is somewhere in the cached proc LRU range, 9223 // then constrain it so we will kill all cached procs. 9224 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9225 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9226 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9227 } 9228 9229 // If this is not a secure call, don't let it kill processes that 9230 // are important. 9231 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9232 worstType = ProcessList.SERVICE_ADJ; 9233 } 9234 9235 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9236 for (int i=0; i<pids.length; i++) { 9237 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9238 if (proc == null) { 9239 continue; 9240 } 9241 int adj = proc.setAdj; 9242 if (adj >= worstType && !proc.killedByAm) { 9243 killUnneededProcessLocked(proc, reason); 9244 killed = true; 9245 } 9246 } 9247 } 9248 return killed; 9249 } 9250 9251 @Override 9252 public void killUid(int uid, String reason) { 9253 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9254 throw new SecurityException("killUid only available to the system"); 9255 } 9256 synchronized (this) { 9257 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9258 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9259 reason != null ? reason : "kill uid"); 9260 } 9261 } 9262 9263 @Override 9264 public boolean killProcessesBelowForeground(String reason) { 9265 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9266 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9267 } 9268 9269 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9270 } 9271 9272 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9273 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9274 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9275 } 9276 9277 boolean killed = false; 9278 synchronized (mPidsSelfLocked) { 9279 final int size = mPidsSelfLocked.size(); 9280 for (int i = 0; i < size; i++) { 9281 final int pid = mPidsSelfLocked.keyAt(i); 9282 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9283 if (proc == null) continue; 9284 9285 final int adj = proc.setAdj; 9286 if (adj > belowAdj && !proc.killedByAm) { 9287 killUnneededProcessLocked(proc, reason); 9288 killed = true; 9289 } 9290 } 9291 } 9292 return killed; 9293 } 9294 9295 @Override 9296 public void hang(final IBinder who, boolean allowRestart) { 9297 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9298 != PackageManager.PERMISSION_GRANTED) { 9299 throw new SecurityException("Requires permission " 9300 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9301 } 9302 9303 final IBinder.DeathRecipient death = new DeathRecipient() { 9304 @Override 9305 public void binderDied() { 9306 synchronized (this) { 9307 notifyAll(); 9308 } 9309 } 9310 }; 9311 9312 try { 9313 who.linkToDeath(death, 0); 9314 } catch (RemoteException e) { 9315 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9316 return; 9317 } 9318 9319 synchronized (this) { 9320 Watchdog.getInstance().setAllowRestart(allowRestart); 9321 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9322 synchronized (death) { 9323 while (who.isBinderAlive()) { 9324 try { 9325 death.wait(); 9326 } catch (InterruptedException e) { 9327 } 9328 } 9329 } 9330 Watchdog.getInstance().setAllowRestart(true); 9331 } 9332 } 9333 9334 @Override 9335 public void restart() { 9336 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9337 != PackageManager.PERMISSION_GRANTED) { 9338 throw new SecurityException("Requires permission " 9339 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9340 } 9341 9342 Log.i(TAG, "Sending shutdown broadcast..."); 9343 9344 BroadcastReceiver br = new BroadcastReceiver() { 9345 @Override public void onReceive(Context context, Intent intent) { 9346 // Now the broadcast is done, finish up the low-level shutdown. 9347 Log.i(TAG, "Shutting down activity manager..."); 9348 shutdown(10000); 9349 Log.i(TAG, "Shutdown complete, restarting!"); 9350 Process.killProcess(Process.myPid()); 9351 System.exit(10); 9352 } 9353 }; 9354 9355 // First send the high-level shut down broadcast. 9356 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9357 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9358 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9359 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9360 mContext.sendOrderedBroadcastAsUser(intent, 9361 UserHandle.ALL, null, br, mHandler, 0, null, null); 9362 */ 9363 br.onReceive(mContext, intent); 9364 } 9365 9366 private long getLowRamTimeSinceIdle(long now) { 9367 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9368 } 9369 9370 @Override 9371 public void performIdleMaintenance() { 9372 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9373 != PackageManager.PERMISSION_GRANTED) { 9374 throw new SecurityException("Requires permission " 9375 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9376 } 9377 9378 synchronized (this) { 9379 final long now = SystemClock.uptimeMillis(); 9380 final long timeSinceLastIdle = now - mLastIdleTime; 9381 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9382 mLastIdleTime = now; 9383 mLowRamTimeSinceLastIdle = 0; 9384 if (mLowRamStartTime != 0) { 9385 mLowRamStartTime = now; 9386 } 9387 9388 StringBuilder sb = new StringBuilder(128); 9389 sb.append("Idle maintenance over "); 9390 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9391 sb.append(" low RAM for "); 9392 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9393 Slog.i(TAG, sb.toString()); 9394 9395 // If at least 1/3 of our time since the last idle period has been spent 9396 // with RAM low, then we want to kill processes. 9397 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9398 9399 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9400 ProcessRecord proc = mLruProcesses.get(i); 9401 if (proc.notCachedSinceIdle) { 9402 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9403 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9404 if (doKilling && proc.initialIdlePss != 0 9405 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9406 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9407 + " from " + proc.initialIdlePss + ")"); 9408 } 9409 } 9410 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9411 proc.notCachedSinceIdle = true; 9412 proc.initialIdlePss = 0; 9413 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9414 isSleeping(), now); 9415 } 9416 } 9417 9418 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9419 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9420 } 9421 } 9422 9423 private void retrieveSettings() { 9424 final ContentResolver resolver = mContext.getContentResolver(); 9425 String debugApp = Settings.Global.getString( 9426 resolver, Settings.Global.DEBUG_APP); 9427 boolean waitForDebugger = Settings.Global.getInt( 9428 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9429 boolean alwaysFinishActivities = Settings.Global.getInt( 9430 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9431 boolean forceRtl = Settings.Global.getInt( 9432 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9433 // Transfer any global setting for forcing RTL layout, into a System Property 9434 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9435 9436 Configuration configuration = new Configuration(); 9437 Settings.System.getConfiguration(resolver, configuration); 9438 if (forceRtl) { 9439 // This will take care of setting the correct layout direction flags 9440 configuration.setLayoutDirection(configuration.locale); 9441 } 9442 9443 synchronized (this) { 9444 mDebugApp = mOrigDebugApp = debugApp; 9445 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9446 mAlwaysFinishActivities = alwaysFinishActivities; 9447 // This happens before any activities are started, so we can 9448 // change mConfiguration in-place. 9449 updateConfigurationLocked(configuration, null, false, true); 9450 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9451 } 9452 } 9453 9454 public boolean testIsSystemReady() { 9455 // no need to synchronize(this) just to read & return the value 9456 return mSystemReady; 9457 } 9458 9459 private static File getCalledPreBootReceiversFile() { 9460 File dataDir = Environment.getDataDirectory(); 9461 File systemDir = new File(dataDir, "system"); 9462 File fname = new File(systemDir, "called_pre_boots.dat"); 9463 return fname; 9464 } 9465 9466 static final int LAST_DONE_VERSION = 10000; 9467 9468 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9469 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9470 File file = getCalledPreBootReceiversFile(); 9471 FileInputStream fis = null; 9472 try { 9473 fis = new FileInputStream(file); 9474 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9475 int fvers = dis.readInt(); 9476 if (fvers == LAST_DONE_VERSION) { 9477 String vers = dis.readUTF(); 9478 String codename = dis.readUTF(); 9479 String build = dis.readUTF(); 9480 if (android.os.Build.VERSION.RELEASE.equals(vers) 9481 && android.os.Build.VERSION.CODENAME.equals(codename) 9482 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9483 int num = dis.readInt(); 9484 while (num > 0) { 9485 num--; 9486 String pkg = dis.readUTF(); 9487 String cls = dis.readUTF(); 9488 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9489 } 9490 } 9491 } 9492 } catch (FileNotFoundException e) { 9493 } catch (IOException e) { 9494 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9495 } finally { 9496 if (fis != null) { 9497 try { 9498 fis.close(); 9499 } catch (IOException e) { 9500 } 9501 } 9502 } 9503 return lastDoneReceivers; 9504 } 9505 9506 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9507 File file = getCalledPreBootReceiversFile(); 9508 FileOutputStream fos = null; 9509 DataOutputStream dos = null; 9510 try { 9511 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9512 fos = new FileOutputStream(file); 9513 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9514 dos.writeInt(LAST_DONE_VERSION); 9515 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9516 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9517 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9518 dos.writeInt(list.size()); 9519 for (int i=0; i<list.size(); i++) { 9520 dos.writeUTF(list.get(i).getPackageName()); 9521 dos.writeUTF(list.get(i).getClassName()); 9522 } 9523 } catch (IOException e) { 9524 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9525 file.delete(); 9526 } finally { 9527 FileUtils.sync(fos); 9528 if (dos != null) { 9529 try { 9530 dos.close(); 9531 } catch (IOException e) { 9532 // TODO Auto-generated catch block 9533 e.printStackTrace(); 9534 } 9535 } 9536 } 9537 } 9538 9539 public void systemReady(final Runnable goingCallback) { 9540 synchronized(this) { 9541 if (mSystemReady) { 9542 if (goingCallback != null) goingCallback.run(); 9543 return; 9544 } 9545 9546 // Check to see if there are any update receivers to run. 9547 if (!mDidUpdate) { 9548 if (mWaitingUpdate) { 9549 return; 9550 } 9551 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9552 List<ResolveInfo> ris = null; 9553 try { 9554 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9555 intent, null, 0, 0); 9556 } catch (RemoteException e) { 9557 } 9558 if (ris != null) { 9559 for (int i=ris.size()-1; i>=0; i--) { 9560 if ((ris.get(i).activityInfo.applicationInfo.flags 9561 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9562 ris.remove(i); 9563 } 9564 } 9565 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9566 9567 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9568 9569 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9570 for (int i=0; i<ris.size(); i++) { 9571 ActivityInfo ai = ris.get(i).activityInfo; 9572 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9573 if (lastDoneReceivers.contains(comp)) { 9574 // We already did the pre boot receiver for this app with the current 9575 // platform version, so don't do it again... 9576 ris.remove(i); 9577 i--; 9578 // ...however, do keep it as one that has been done, so we don't 9579 // forget about it when rewriting the file of last done receivers. 9580 doneReceivers.add(comp); 9581 } 9582 } 9583 9584 final int[] users = getUsersLocked(); 9585 for (int i=0; i<ris.size(); i++) { 9586 ActivityInfo ai = ris.get(i).activityInfo; 9587 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9588 doneReceivers.add(comp); 9589 intent.setComponent(comp); 9590 for (int j=0; j<users.length; j++) { 9591 IIntentReceiver finisher = null; 9592 if (i == ris.size()-1 && j == users.length-1) { 9593 finisher = new IIntentReceiver.Stub() { 9594 public void performReceive(Intent intent, int resultCode, 9595 String data, Bundle extras, boolean ordered, 9596 boolean sticky, int sendingUser) { 9597 // The raw IIntentReceiver interface is called 9598 // with the AM lock held, so redispatch to 9599 // execute our code without the lock. 9600 mHandler.post(new Runnable() { 9601 public void run() { 9602 synchronized (ActivityManagerService.this) { 9603 mDidUpdate = true; 9604 } 9605 writeLastDonePreBootReceivers(doneReceivers); 9606 showBootMessage(mContext.getText( 9607 R.string.android_upgrading_complete), 9608 false); 9609 systemReady(goingCallback); 9610 } 9611 }); 9612 } 9613 }; 9614 } 9615 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9616 + " for user " + users[j]); 9617 broadcastIntentLocked(null, null, intent, null, finisher, 9618 0, null, null, null, AppOpsManager.OP_NONE, 9619 true, false, MY_PID, Process.SYSTEM_UID, 9620 users[j]); 9621 if (finisher != null) { 9622 mWaitingUpdate = true; 9623 } 9624 } 9625 } 9626 } 9627 if (mWaitingUpdate) { 9628 return; 9629 } 9630 mDidUpdate = true; 9631 } 9632 9633 mAppOpsService.systemReady(); 9634 mUsageStatsService.systemReady(); 9635 mSystemReady = true; 9636 } 9637 9638 ArrayList<ProcessRecord> procsToKill = null; 9639 synchronized(mPidsSelfLocked) { 9640 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9641 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9642 if (!isAllowedWhileBooting(proc.info)){ 9643 if (procsToKill == null) { 9644 procsToKill = new ArrayList<ProcessRecord>(); 9645 } 9646 procsToKill.add(proc); 9647 } 9648 } 9649 } 9650 9651 synchronized(this) { 9652 if (procsToKill != null) { 9653 for (int i=procsToKill.size()-1; i>=0; i--) { 9654 ProcessRecord proc = procsToKill.get(i); 9655 Slog.i(TAG, "Removing system update proc: " + proc); 9656 removeProcessLocked(proc, true, false, "system update done"); 9657 } 9658 } 9659 9660 // Now that we have cleaned up any update processes, we 9661 // are ready to start launching real processes and know that 9662 // we won't trample on them any more. 9663 mProcessesReady = true; 9664 } 9665 9666 Slog.i(TAG, "System now ready"); 9667 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9668 SystemClock.uptimeMillis()); 9669 9670 synchronized(this) { 9671 // Make sure we have no pre-ready processes sitting around. 9672 9673 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9674 ResolveInfo ri = mContext.getPackageManager() 9675 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9676 STOCK_PM_FLAGS); 9677 CharSequence errorMsg = null; 9678 if (ri != null) { 9679 ActivityInfo ai = ri.activityInfo; 9680 ApplicationInfo app = ai.applicationInfo; 9681 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9682 mTopAction = Intent.ACTION_FACTORY_TEST; 9683 mTopData = null; 9684 mTopComponent = new ComponentName(app.packageName, 9685 ai.name); 9686 } else { 9687 errorMsg = mContext.getResources().getText( 9688 com.android.internal.R.string.factorytest_not_system); 9689 } 9690 } else { 9691 errorMsg = mContext.getResources().getText( 9692 com.android.internal.R.string.factorytest_no_action); 9693 } 9694 if (errorMsg != null) { 9695 mTopAction = null; 9696 mTopData = null; 9697 mTopComponent = null; 9698 Message msg = Message.obtain(); 9699 msg.what = SHOW_FACTORY_ERROR_MSG; 9700 msg.getData().putCharSequence("msg", errorMsg); 9701 mHandler.sendMessage(msg); 9702 } 9703 } 9704 } 9705 9706 retrieveSettings(); 9707 9708 synchronized (this) { 9709 readGrantedUriPermissionsLocked(); 9710 } 9711 9712 if (goingCallback != null) goingCallback.run(); 9713 9714 mSystemServiceManager.startUser(mCurrentUserId); 9715 9716 synchronized (this) { 9717 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9718 try { 9719 List apps = AppGlobals.getPackageManager(). 9720 getPersistentApplications(STOCK_PM_FLAGS); 9721 if (apps != null) { 9722 int N = apps.size(); 9723 int i; 9724 for (i=0; i<N; i++) { 9725 ApplicationInfo info 9726 = (ApplicationInfo)apps.get(i); 9727 if (info != null && 9728 !info.packageName.equals("android")) { 9729 addAppLocked(info, false); 9730 } 9731 } 9732 } 9733 } catch (RemoteException ex) { 9734 // pm is in same process, this will never happen. 9735 } 9736 } 9737 9738 // Start up initial activity. 9739 mBooting = true; 9740 9741 try { 9742 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9743 Message msg = Message.obtain(); 9744 msg.what = SHOW_UID_ERROR_MSG; 9745 mHandler.sendMessage(msg); 9746 } 9747 } catch (RemoteException e) { 9748 } 9749 9750 long ident = Binder.clearCallingIdentity(); 9751 try { 9752 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9753 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9754 | Intent.FLAG_RECEIVER_FOREGROUND); 9755 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9756 broadcastIntentLocked(null, null, intent, 9757 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9758 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9759 intent = new Intent(Intent.ACTION_USER_STARTING); 9760 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9761 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9762 broadcastIntentLocked(null, null, intent, 9763 null, new IIntentReceiver.Stub() { 9764 @Override 9765 public void performReceive(Intent intent, int resultCode, String data, 9766 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9767 throws RemoteException { 9768 } 9769 }, 0, null, null, 9770 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9771 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9772 } catch (Throwable t) { 9773 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9774 } finally { 9775 Binder.restoreCallingIdentity(ident); 9776 } 9777 mStackSupervisor.resumeTopActivitiesLocked(); 9778 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9779 } 9780 } 9781 9782 private boolean makeAppCrashingLocked(ProcessRecord app, 9783 String shortMsg, String longMsg, String stackTrace) { 9784 app.crashing = true; 9785 app.crashingReport = generateProcessError(app, 9786 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9787 startAppProblemLocked(app); 9788 app.stopFreezingAllLocked(); 9789 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9790 } 9791 9792 private void makeAppNotRespondingLocked(ProcessRecord app, 9793 String activity, String shortMsg, String longMsg) { 9794 app.notResponding = true; 9795 app.notRespondingReport = generateProcessError(app, 9796 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9797 activity, shortMsg, longMsg, null); 9798 startAppProblemLocked(app); 9799 app.stopFreezingAllLocked(); 9800 } 9801 9802 /** 9803 * Generate a process error record, suitable for attachment to a ProcessRecord. 9804 * 9805 * @param app The ProcessRecord in which the error occurred. 9806 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9807 * ActivityManager.AppErrorStateInfo 9808 * @param activity The activity associated with the crash, if known. 9809 * @param shortMsg Short message describing the crash. 9810 * @param longMsg Long message describing the crash. 9811 * @param stackTrace Full crash stack trace, may be null. 9812 * 9813 * @return Returns a fully-formed AppErrorStateInfo record. 9814 */ 9815 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9816 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9817 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9818 9819 report.condition = condition; 9820 report.processName = app.processName; 9821 report.pid = app.pid; 9822 report.uid = app.info.uid; 9823 report.tag = activity; 9824 report.shortMsg = shortMsg; 9825 report.longMsg = longMsg; 9826 report.stackTrace = stackTrace; 9827 9828 return report; 9829 } 9830 9831 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9832 synchronized (this) { 9833 app.crashing = false; 9834 app.crashingReport = null; 9835 app.notResponding = false; 9836 app.notRespondingReport = null; 9837 if (app.anrDialog == fromDialog) { 9838 app.anrDialog = null; 9839 } 9840 if (app.waitDialog == fromDialog) { 9841 app.waitDialog = null; 9842 } 9843 if (app.pid > 0 && app.pid != MY_PID) { 9844 handleAppCrashLocked(app, null, null, null); 9845 killUnneededProcessLocked(app, "user request after error"); 9846 } 9847 } 9848 } 9849 9850 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9851 String stackTrace) { 9852 long now = SystemClock.uptimeMillis(); 9853 9854 Long crashTime; 9855 if (!app.isolated) { 9856 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9857 } else { 9858 crashTime = null; 9859 } 9860 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9861 // This process loses! 9862 Slog.w(TAG, "Process " + app.info.processName 9863 + " has crashed too many times: killing!"); 9864 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9865 app.userId, app.info.processName, app.uid); 9866 mStackSupervisor.handleAppCrashLocked(app); 9867 if (!app.persistent) { 9868 // We don't want to start this process again until the user 9869 // explicitly does so... but for persistent process, we really 9870 // need to keep it running. If a persistent process is actually 9871 // repeatedly crashing, then badness for everyone. 9872 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9873 app.info.processName); 9874 if (!app.isolated) { 9875 // XXX We don't have a way to mark isolated processes 9876 // as bad, since they don't have a peristent identity. 9877 mBadProcesses.put(app.info.processName, app.uid, 9878 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9879 mProcessCrashTimes.remove(app.info.processName, app.uid); 9880 } 9881 app.bad = true; 9882 app.removed = true; 9883 // Don't let services in this process be restarted and potentially 9884 // annoy the user repeatedly. Unless it is persistent, since those 9885 // processes run critical code. 9886 removeProcessLocked(app, false, false, "crash"); 9887 mStackSupervisor.resumeTopActivitiesLocked(); 9888 return false; 9889 } 9890 mStackSupervisor.resumeTopActivitiesLocked(); 9891 } else { 9892 mStackSupervisor.finishTopRunningActivityLocked(app); 9893 } 9894 9895 // Bump up the crash count of any services currently running in the proc. 9896 for (int i=app.services.size()-1; i>=0; i--) { 9897 // Any services running in the application need to be placed 9898 // back in the pending list. 9899 ServiceRecord sr = app.services.valueAt(i); 9900 sr.crashCount++; 9901 } 9902 9903 // If the crashing process is what we consider to be the "home process" and it has been 9904 // replaced by a third-party app, clear the package preferred activities from packages 9905 // with a home activity running in the process to prevent a repeatedly crashing app 9906 // from blocking the user to manually clear the list. 9907 final ArrayList<ActivityRecord> activities = app.activities; 9908 if (app == mHomeProcess && activities.size() > 0 9909 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9910 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9911 final ActivityRecord r = activities.get(activityNdx); 9912 if (r.isHomeActivity()) { 9913 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9914 try { 9915 ActivityThread.getPackageManager() 9916 .clearPackagePreferredActivities(r.packageName); 9917 } catch (RemoteException c) { 9918 // pm is in same process, this will never happen. 9919 } 9920 } 9921 } 9922 } 9923 9924 if (!app.isolated) { 9925 // XXX Can't keep track of crash times for isolated processes, 9926 // because they don't have a perisistent identity. 9927 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9928 } 9929 9930 return true; 9931 } 9932 9933 void startAppProblemLocked(ProcessRecord app) { 9934 if (app.userId == mCurrentUserId) { 9935 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9936 mContext, app.info.packageName, app.info.flags); 9937 } else { 9938 // If this app is not running under the current user, then we 9939 // can't give it a report button because that would require 9940 // launching the report UI under a different user. 9941 app.errorReportReceiver = null; 9942 } 9943 skipCurrentReceiverLocked(app); 9944 } 9945 9946 void skipCurrentReceiverLocked(ProcessRecord app) { 9947 for (BroadcastQueue queue : mBroadcastQueues) { 9948 queue.skipCurrentReceiverLocked(app); 9949 } 9950 } 9951 9952 /** 9953 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9954 * The application process will exit immediately after this call returns. 9955 * @param app object of the crashing app, null for the system server 9956 * @param crashInfo describing the exception 9957 */ 9958 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9959 ProcessRecord r = findAppProcess(app, "Crash"); 9960 final String processName = app == null ? "system_server" 9961 : (r == null ? "unknown" : r.processName); 9962 9963 handleApplicationCrashInner("crash", r, processName, crashInfo); 9964 } 9965 9966 /* Native crash reporting uses this inner version because it needs to be somewhat 9967 * decoupled from the AM-managed cleanup lifecycle 9968 */ 9969 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9970 ApplicationErrorReport.CrashInfo crashInfo) { 9971 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9972 UserHandle.getUserId(Binder.getCallingUid()), processName, 9973 r == null ? -1 : r.info.flags, 9974 crashInfo.exceptionClassName, 9975 crashInfo.exceptionMessage, 9976 crashInfo.throwFileName, 9977 crashInfo.throwLineNumber); 9978 9979 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9980 9981 crashApplication(r, crashInfo); 9982 } 9983 9984 public void handleApplicationStrictModeViolation( 9985 IBinder app, 9986 int violationMask, 9987 StrictMode.ViolationInfo info) { 9988 ProcessRecord r = findAppProcess(app, "StrictMode"); 9989 if (r == null) { 9990 return; 9991 } 9992 9993 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9994 Integer stackFingerprint = info.hashCode(); 9995 boolean logIt = true; 9996 synchronized (mAlreadyLoggedViolatedStacks) { 9997 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9998 logIt = false; 9999 // TODO: sub-sample into EventLog for these, with 10000 // the info.durationMillis? Then we'd get 10001 // the relative pain numbers, without logging all 10002 // the stack traces repeatedly. We'd want to do 10003 // likewise in the client code, which also does 10004 // dup suppression, before the Binder call. 10005 } else { 10006 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10007 mAlreadyLoggedViolatedStacks.clear(); 10008 } 10009 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10010 } 10011 } 10012 if (logIt) { 10013 logStrictModeViolationToDropBox(r, info); 10014 } 10015 } 10016 10017 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10018 AppErrorResult result = new AppErrorResult(); 10019 synchronized (this) { 10020 final long origId = Binder.clearCallingIdentity(); 10021 10022 Message msg = Message.obtain(); 10023 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10024 HashMap<String, Object> data = new HashMap<String, Object>(); 10025 data.put("result", result); 10026 data.put("app", r); 10027 data.put("violationMask", violationMask); 10028 data.put("info", info); 10029 msg.obj = data; 10030 mHandler.sendMessage(msg); 10031 10032 Binder.restoreCallingIdentity(origId); 10033 } 10034 int res = result.get(); 10035 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10036 } 10037 } 10038 10039 // Depending on the policy in effect, there could be a bunch of 10040 // these in quick succession so we try to batch these together to 10041 // minimize disk writes, number of dropbox entries, and maximize 10042 // compression, by having more fewer, larger records. 10043 private void logStrictModeViolationToDropBox( 10044 ProcessRecord process, 10045 StrictMode.ViolationInfo info) { 10046 if (info == null) { 10047 return; 10048 } 10049 final boolean isSystemApp = process == null || 10050 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10051 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10052 final String processName = process == null ? "unknown" : process.processName; 10053 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10054 final DropBoxManager dbox = (DropBoxManager) 10055 mContext.getSystemService(Context.DROPBOX_SERVICE); 10056 10057 // Exit early if the dropbox isn't configured to accept this report type. 10058 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10059 10060 boolean bufferWasEmpty; 10061 boolean needsFlush; 10062 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10063 synchronized (sb) { 10064 bufferWasEmpty = sb.length() == 0; 10065 appendDropBoxProcessHeaders(process, processName, sb); 10066 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10067 sb.append("System-App: ").append(isSystemApp).append("\n"); 10068 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10069 if (info.violationNumThisLoop != 0) { 10070 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10071 } 10072 if (info.numAnimationsRunning != 0) { 10073 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10074 } 10075 if (info.broadcastIntentAction != null) { 10076 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10077 } 10078 if (info.durationMillis != -1) { 10079 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10080 } 10081 if (info.numInstances != -1) { 10082 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10083 } 10084 if (info.tags != null) { 10085 for (String tag : info.tags) { 10086 sb.append("Span-Tag: ").append(tag).append("\n"); 10087 } 10088 } 10089 sb.append("\n"); 10090 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10091 sb.append(info.crashInfo.stackTrace); 10092 } 10093 sb.append("\n"); 10094 10095 // Only buffer up to ~64k. Various logging bits truncate 10096 // things at 128k. 10097 needsFlush = (sb.length() > 64 * 1024); 10098 } 10099 10100 // Flush immediately if the buffer's grown too large, or this 10101 // is a non-system app. Non-system apps are isolated with a 10102 // different tag & policy and not batched. 10103 // 10104 // Batching is useful during internal testing with 10105 // StrictMode settings turned up high. Without batching, 10106 // thousands of separate files could be created on boot. 10107 if (!isSystemApp || needsFlush) { 10108 new Thread("Error dump: " + dropboxTag) { 10109 @Override 10110 public void run() { 10111 String report; 10112 synchronized (sb) { 10113 report = sb.toString(); 10114 sb.delete(0, sb.length()); 10115 sb.trimToSize(); 10116 } 10117 if (report.length() != 0) { 10118 dbox.addText(dropboxTag, report); 10119 } 10120 } 10121 }.start(); 10122 return; 10123 } 10124 10125 // System app batching: 10126 if (!bufferWasEmpty) { 10127 // An existing dropbox-writing thread is outstanding, so 10128 // we don't need to start it up. The existing thread will 10129 // catch the buffer appends we just did. 10130 return; 10131 } 10132 10133 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10134 // (After this point, we shouldn't access AMS internal data structures.) 10135 new Thread("Error dump: " + dropboxTag) { 10136 @Override 10137 public void run() { 10138 // 5 second sleep to let stacks arrive and be batched together 10139 try { 10140 Thread.sleep(5000); // 5 seconds 10141 } catch (InterruptedException e) {} 10142 10143 String errorReport; 10144 synchronized (mStrictModeBuffer) { 10145 errorReport = mStrictModeBuffer.toString(); 10146 if (errorReport.length() == 0) { 10147 return; 10148 } 10149 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10150 mStrictModeBuffer.trimToSize(); 10151 } 10152 dbox.addText(dropboxTag, errorReport); 10153 } 10154 }.start(); 10155 } 10156 10157 /** 10158 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10159 * @param app object of the crashing app, null for the system server 10160 * @param tag reported by the caller 10161 * @param crashInfo describing the context of the error 10162 * @return true if the process should exit immediately (WTF is fatal) 10163 */ 10164 public boolean handleApplicationWtf(IBinder app, String tag, 10165 ApplicationErrorReport.CrashInfo crashInfo) { 10166 ProcessRecord r = findAppProcess(app, "WTF"); 10167 final String processName = app == null ? "system_server" 10168 : (r == null ? "unknown" : r.processName); 10169 10170 EventLog.writeEvent(EventLogTags.AM_WTF, 10171 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10172 processName, 10173 r == null ? -1 : r.info.flags, 10174 tag, crashInfo.exceptionMessage); 10175 10176 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10177 10178 if (r != null && r.pid != Process.myPid() && 10179 Settings.Global.getInt(mContext.getContentResolver(), 10180 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10181 crashApplication(r, crashInfo); 10182 return true; 10183 } else { 10184 return false; 10185 } 10186 } 10187 10188 /** 10189 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10190 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10191 */ 10192 private ProcessRecord findAppProcess(IBinder app, String reason) { 10193 if (app == null) { 10194 return null; 10195 } 10196 10197 synchronized (this) { 10198 final int NP = mProcessNames.getMap().size(); 10199 for (int ip=0; ip<NP; ip++) { 10200 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10201 final int NA = apps.size(); 10202 for (int ia=0; ia<NA; ia++) { 10203 ProcessRecord p = apps.valueAt(ia); 10204 if (p.thread != null && p.thread.asBinder() == app) { 10205 return p; 10206 } 10207 } 10208 } 10209 10210 Slog.w(TAG, "Can't find mystery application for " + reason 10211 + " from pid=" + Binder.getCallingPid() 10212 + " uid=" + Binder.getCallingUid() + ": " + app); 10213 return null; 10214 } 10215 } 10216 10217 /** 10218 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10219 * to append various headers to the dropbox log text. 10220 */ 10221 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10222 StringBuilder sb) { 10223 // Watchdog thread ends up invoking this function (with 10224 // a null ProcessRecord) to add the stack file to dropbox. 10225 // Do not acquire a lock on this (am) in such cases, as it 10226 // could cause a potential deadlock, if and when watchdog 10227 // is invoked due to unavailability of lock on am and it 10228 // would prevent watchdog from killing system_server. 10229 if (process == null) { 10230 sb.append("Process: ").append(processName).append("\n"); 10231 return; 10232 } 10233 // Note: ProcessRecord 'process' is guarded by the service 10234 // instance. (notably process.pkgList, which could otherwise change 10235 // concurrently during execution of this method) 10236 synchronized (this) { 10237 sb.append("Process: ").append(processName).append("\n"); 10238 int flags = process.info.flags; 10239 IPackageManager pm = AppGlobals.getPackageManager(); 10240 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10241 for (int ip=0; ip<process.pkgList.size(); ip++) { 10242 String pkg = process.pkgList.keyAt(ip); 10243 sb.append("Package: ").append(pkg); 10244 try { 10245 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10246 if (pi != null) { 10247 sb.append(" v").append(pi.versionCode); 10248 if (pi.versionName != null) { 10249 sb.append(" (").append(pi.versionName).append(")"); 10250 } 10251 } 10252 } catch (RemoteException e) { 10253 Slog.e(TAG, "Error getting package info: " + pkg, e); 10254 } 10255 sb.append("\n"); 10256 } 10257 } 10258 } 10259 10260 private static String processClass(ProcessRecord process) { 10261 if (process == null || process.pid == MY_PID) { 10262 return "system_server"; 10263 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10264 return "system_app"; 10265 } else { 10266 return "data_app"; 10267 } 10268 } 10269 10270 /** 10271 * Write a description of an error (crash, WTF, ANR) to the drop box. 10272 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10273 * @param process which caused the error, null means the system server 10274 * @param activity which triggered the error, null if unknown 10275 * @param parent activity related to the error, null if unknown 10276 * @param subject line related to the error, null if absent 10277 * @param report in long form describing the error, null if absent 10278 * @param logFile to include in the report, null if none 10279 * @param crashInfo giving an application stack trace, null if absent 10280 */ 10281 public void addErrorToDropBox(String eventType, 10282 ProcessRecord process, String processName, ActivityRecord activity, 10283 ActivityRecord parent, String subject, 10284 final String report, final File logFile, 10285 final ApplicationErrorReport.CrashInfo crashInfo) { 10286 // NOTE -- this must never acquire the ActivityManagerService lock, 10287 // otherwise the watchdog may be prevented from resetting the system. 10288 10289 final String dropboxTag = processClass(process) + "_" + eventType; 10290 final DropBoxManager dbox = (DropBoxManager) 10291 mContext.getSystemService(Context.DROPBOX_SERVICE); 10292 10293 // Exit early if the dropbox isn't configured to accept this report type. 10294 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10295 10296 final StringBuilder sb = new StringBuilder(1024); 10297 appendDropBoxProcessHeaders(process, processName, sb); 10298 if (activity != null) { 10299 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10300 } 10301 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10302 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10303 } 10304 if (parent != null && parent != activity) { 10305 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10306 } 10307 if (subject != null) { 10308 sb.append("Subject: ").append(subject).append("\n"); 10309 } 10310 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10311 if (Debug.isDebuggerConnected()) { 10312 sb.append("Debugger: Connected\n"); 10313 } 10314 sb.append("\n"); 10315 10316 // Do the rest in a worker thread to avoid blocking the caller on I/O 10317 // (After this point, we shouldn't access AMS internal data structures.) 10318 Thread worker = new Thread("Error dump: " + dropboxTag) { 10319 @Override 10320 public void run() { 10321 if (report != null) { 10322 sb.append(report); 10323 } 10324 if (logFile != null) { 10325 try { 10326 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10327 "\n\n[[TRUNCATED]]")); 10328 } catch (IOException e) { 10329 Slog.e(TAG, "Error reading " + logFile, e); 10330 } 10331 } 10332 if (crashInfo != null && crashInfo.stackTrace != null) { 10333 sb.append(crashInfo.stackTrace); 10334 } 10335 10336 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10337 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10338 if (lines > 0) { 10339 sb.append("\n"); 10340 10341 // Merge several logcat streams, and take the last N lines 10342 InputStreamReader input = null; 10343 try { 10344 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10345 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10346 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10347 10348 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10349 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10350 input = new InputStreamReader(logcat.getInputStream()); 10351 10352 int num; 10353 char[] buf = new char[8192]; 10354 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10355 } catch (IOException e) { 10356 Slog.e(TAG, "Error running logcat", e); 10357 } finally { 10358 if (input != null) try { input.close(); } catch (IOException e) {} 10359 } 10360 } 10361 10362 dbox.addText(dropboxTag, sb.toString()); 10363 } 10364 }; 10365 10366 if (process == null) { 10367 // If process is null, we are being called from some internal code 10368 // and may be about to die -- run this synchronously. 10369 worker.run(); 10370 } else { 10371 worker.start(); 10372 } 10373 } 10374 10375 /** 10376 * Bring up the "unexpected error" dialog box for a crashing app. 10377 * Deal with edge cases (intercepts from instrumented applications, 10378 * ActivityController, error intent receivers, that sort of thing). 10379 * @param r the application crashing 10380 * @param crashInfo describing the failure 10381 */ 10382 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10383 long timeMillis = System.currentTimeMillis(); 10384 String shortMsg = crashInfo.exceptionClassName; 10385 String longMsg = crashInfo.exceptionMessage; 10386 String stackTrace = crashInfo.stackTrace; 10387 if (shortMsg != null && longMsg != null) { 10388 longMsg = shortMsg + ": " + longMsg; 10389 } else if (shortMsg != null) { 10390 longMsg = shortMsg; 10391 } 10392 10393 AppErrorResult result = new AppErrorResult(); 10394 synchronized (this) { 10395 if (mController != null) { 10396 try { 10397 String name = r != null ? r.processName : null; 10398 int pid = r != null ? r.pid : Binder.getCallingPid(); 10399 if (!mController.appCrashed(name, pid, 10400 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10401 Slog.w(TAG, "Force-killing crashed app " + name 10402 + " at watcher's request"); 10403 Process.killProcess(pid); 10404 return; 10405 } 10406 } catch (RemoteException e) { 10407 mController = null; 10408 Watchdog.getInstance().setActivityController(null); 10409 } 10410 } 10411 10412 final long origId = Binder.clearCallingIdentity(); 10413 10414 // If this process is running instrumentation, finish it. 10415 if (r != null && r.instrumentationClass != null) { 10416 Slog.w(TAG, "Error in app " + r.processName 10417 + " running instrumentation " + r.instrumentationClass + ":"); 10418 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10419 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10420 Bundle info = new Bundle(); 10421 info.putString("shortMsg", shortMsg); 10422 info.putString("longMsg", longMsg); 10423 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10424 Binder.restoreCallingIdentity(origId); 10425 return; 10426 } 10427 10428 // If we can't identify the process or it's already exceeded its crash quota, 10429 // quit right away without showing a crash dialog. 10430 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10431 Binder.restoreCallingIdentity(origId); 10432 return; 10433 } 10434 10435 Message msg = Message.obtain(); 10436 msg.what = SHOW_ERROR_MSG; 10437 HashMap data = new HashMap(); 10438 data.put("result", result); 10439 data.put("app", r); 10440 msg.obj = data; 10441 mHandler.sendMessage(msg); 10442 10443 Binder.restoreCallingIdentity(origId); 10444 } 10445 10446 int res = result.get(); 10447 10448 Intent appErrorIntent = null; 10449 synchronized (this) { 10450 if (r != null && !r.isolated) { 10451 // XXX Can't keep track of crash time for isolated processes, 10452 // since they don't have a persistent identity. 10453 mProcessCrashTimes.put(r.info.processName, r.uid, 10454 SystemClock.uptimeMillis()); 10455 } 10456 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10457 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10458 } 10459 } 10460 10461 if (appErrorIntent != null) { 10462 try { 10463 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10464 } catch (ActivityNotFoundException e) { 10465 Slog.w(TAG, "bug report receiver dissappeared", e); 10466 } 10467 } 10468 } 10469 10470 Intent createAppErrorIntentLocked(ProcessRecord r, 10471 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10472 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10473 if (report == null) { 10474 return null; 10475 } 10476 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10477 result.setComponent(r.errorReportReceiver); 10478 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10479 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10480 return result; 10481 } 10482 10483 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10484 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10485 if (r.errorReportReceiver == null) { 10486 return null; 10487 } 10488 10489 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10490 return null; 10491 } 10492 10493 ApplicationErrorReport report = new ApplicationErrorReport(); 10494 report.packageName = r.info.packageName; 10495 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10496 report.processName = r.processName; 10497 report.time = timeMillis; 10498 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10499 10500 if (r.crashing || r.forceCrashReport) { 10501 report.type = ApplicationErrorReport.TYPE_CRASH; 10502 report.crashInfo = crashInfo; 10503 } else if (r.notResponding) { 10504 report.type = ApplicationErrorReport.TYPE_ANR; 10505 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10506 10507 report.anrInfo.activity = r.notRespondingReport.tag; 10508 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10509 report.anrInfo.info = r.notRespondingReport.longMsg; 10510 } 10511 10512 return report; 10513 } 10514 10515 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10516 enforceNotIsolatedCaller("getProcessesInErrorState"); 10517 // assume our apps are happy - lazy create the list 10518 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10519 10520 final boolean allUsers = ActivityManager.checkUidPermission( 10521 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10522 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10523 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10524 10525 synchronized (this) { 10526 10527 // iterate across all processes 10528 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10529 ProcessRecord app = mLruProcesses.get(i); 10530 if (!allUsers && app.userId != userId) { 10531 continue; 10532 } 10533 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10534 // This one's in trouble, so we'll generate a report for it 10535 // crashes are higher priority (in case there's a crash *and* an anr) 10536 ActivityManager.ProcessErrorStateInfo report = null; 10537 if (app.crashing) { 10538 report = app.crashingReport; 10539 } else if (app.notResponding) { 10540 report = app.notRespondingReport; 10541 } 10542 10543 if (report != null) { 10544 if (errList == null) { 10545 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10546 } 10547 errList.add(report); 10548 } else { 10549 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10550 " crashing = " + app.crashing + 10551 " notResponding = " + app.notResponding); 10552 } 10553 } 10554 } 10555 } 10556 10557 return errList; 10558 } 10559 10560 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10561 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10562 if (currApp != null) { 10563 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10564 } 10565 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10566 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10567 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10568 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10569 if (currApp != null) { 10570 currApp.lru = 0; 10571 } 10572 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10573 } else if (adj >= ProcessList.SERVICE_ADJ) { 10574 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10575 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10576 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10577 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10578 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10579 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10580 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10581 } else { 10582 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10583 } 10584 } 10585 10586 private void fillInProcMemInfo(ProcessRecord app, 10587 ActivityManager.RunningAppProcessInfo outInfo) { 10588 outInfo.pid = app.pid; 10589 outInfo.uid = app.info.uid; 10590 if (mHeavyWeightProcess == app) { 10591 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10592 } 10593 if (app.persistent) { 10594 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10595 } 10596 if (app.activities.size() > 0) { 10597 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10598 } 10599 outInfo.lastTrimLevel = app.trimMemoryLevel; 10600 int adj = app.curAdj; 10601 outInfo.importance = oomAdjToImportance(adj, outInfo); 10602 outInfo.importanceReasonCode = app.adjTypeCode; 10603 outInfo.processState = app.curProcState; 10604 } 10605 10606 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10607 enforceNotIsolatedCaller("getRunningAppProcesses"); 10608 // Lazy instantiation of list 10609 List<ActivityManager.RunningAppProcessInfo> runList = null; 10610 final boolean allUsers = ActivityManager.checkUidPermission( 10611 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10612 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10613 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10614 synchronized (this) { 10615 // Iterate across all processes 10616 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10617 ProcessRecord app = mLruProcesses.get(i); 10618 if (!allUsers && app.userId != userId) { 10619 continue; 10620 } 10621 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10622 // Generate process state info for running application 10623 ActivityManager.RunningAppProcessInfo currApp = 10624 new ActivityManager.RunningAppProcessInfo(app.processName, 10625 app.pid, app.getPackageList()); 10626 fillInProcMemInfo(app, currApp); 10627 if (app.adjSource instanceof ProcessRecord) { 10628 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10629 currApp.importanceReasonImportance = oomAdjToImportance( 10630 app.adjSourceOom, null); 10631 } else if (app.adjSource instanceof ActivityRecord) { 10632 ActivityRecord r = (ActivityRecord)app.adjSource; 10633 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10634 } 10635 if (app.adjTarget instanceof ComponentName) { 10636 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10637 } 10638 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10639 // + " lru=" + currApp.lru); 10640 if (runList == null) { 10641 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10642 } 10643 runList.add(currApp); 10644 } 10645 } 10646 } 10647 return runList; 10648 } 10649 10650 public List<ApplicationInfo> getRunningExternalApplications() { 10651 enforceNotIsolatedCaller("getRunningExternalApplications"); 10652 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10653 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10654 if (runningApps != null && runningApps.size() > 0) { 10655 Set<String> extList = new HashSet<String>(); 10656 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10657 if (app.pkgList != null) { 10658 for (String pkg : app.pkgList) { 10659 extList.add(pkg); 10660 } 10661 } 10662 } 10663 IPackageManager pm = AppGlobals.getPackageManager(); 10664 for (String pkg : extList) { 10665 try { 10666 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10667 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10668 retList.add(info); 10669 } 10670 } catch (RemoteException e) { 10671 } 10672 } 10673 } 10674 return retList; 10675 } 10676 10677 @Override 10678 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10679 enforceNotIsolatedCaller("getMyMemoryState"); 10680 synchronized (this) { 10681 ProcessRecord proc; 10682 synchronized (mPidsSelfLocked) { 10683 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10684 } 10685 fillInProcMemInfo(proc, outInfo); 10686 } 10687 } 10688 10689 @Override 10690 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10691 if (checkCallingPermission(android.Manifest.permission.DUMP) 10692 != PackageManager.PERMISSION_GRANTED) { 10693 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10694 + Binder.getCallingPid() 10695 + ", uid=" + Binder.getCallingUid() 10696 + " without permission " 10697 + android.Manifest.permission.DUMP); 10698 return; 10699 } 10700 10701 boolean dumpAll = false; 10702 boolean dumpClient = false; 10703 String dumpPackage = null; 10704 10705 int opti = 0; 10706 while (opti < args.length) { 10707 String opt = args[opti]; 10708 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10709 break; 10710 } 10711 opti++; 10712 if ("-a".equals(opt)) { 10713 dumpAll = true; 10714 } else if ("-c".equals(opt)) { 10715 dumpClient = true; 10716 } else if ("-h".equals(opt)) { 10717 pw.println("Activity manager dump options:"); 10718 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10719 pw.println(" cmd may be one of:"); 10720 pw.println(" a[ctivities]: activity stack state"); 10721 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10722 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10723 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10724 pw.println(" o[om]: out of memory management"); 10725 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10726 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10727 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10728 pw.println(" service [COMP_SPEC]: service client-side state"); 10729 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10730 pw.println(" all: dump all activities"); 10731 pw.println(" top: dump the top activity"); 10732 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10733 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10734 pw.println(" a partial substring in a component name, a"); 10735 pw.println(" hex object identifier."); 10736 pw.println(" -a: include all available server state."); 10737 pw.println(" -c: include client state."); 10738 return; 10739 } else { 10740 pw.println("Unknown argument: " + opt + "; use -h for help"); 10741 } 10742 } 10743 10744 long origId = Binder.clearCallingIdentity(); 10745 boolean more = false; 10746 // Is the caller requesting to dump a particular piece of data? 10747 if (opti < args.length) { 10748 String cmd = args[opti]; 10749 opti++; 10750 if ("activities".equals(cmd) || "a".equals(cmd)) { 10751 synchronized (this) { 10752 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10753 } 10754 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10755 String[] newArgs; 10756 String name; 10757 if (opti >= args.length) { 10758 name = null; 10759 newArgs = EMPTY_STRING_ARRAY; 10760 } else { 10761 name = args[opti]; 10762 opti++; 10763 newArgs = new String[args.length - opti]; 10764 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10765 args.length - opti); 10766 } 10767 synchronized (this) { 10768 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10769 } 10770 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10771 String[] newArgs; 10772 String name; 10773 if (opti >= args.length) { 10774 name = null; 10775 newArgs = EMPTY_STRING_ARRAY; 10776 } else { 10777 name = args[opti]; 10778 opti++; 10779 newArgs = new String[args.length - opti]; 10780 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10781 args.length - opti); 10782 } 10783 synchronized (this) { 10784 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10785 } 10786 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10787 String[] newArgs; 10788 String name; 10789 if (opti >= args.length) { 10790 name = null; 10791 newArgs = EMPTY_STRING_ARRAY; 10792 } else { 10793 name = args[opti]; 10794 opti++; 10795 newArgs = new String[args.length - opti]; 10796 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10797 args.length - opti); 10798 } 10799 synchronized (this) { 10800 dumpProcessesLocked(fd, pw, args, opti, true, name); 10801 } 10802 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10803 synchronized (this) { 10804 dumpOomLocked(fd, pw, args, opti, true); 10805 } 10806 } else if ("provider".equals(cmd)) { 10807 String[] newArgs; 10808 String name; 10809 if (opti >= args.length) { 10810 name = null; 10811 newArgs = EMPTY_STRING_ARRAY; 10812 } else { 10813 name = args[opti]; 10814 opti++; 10815 newArgs = new String[args.length - opti]; 10816 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10817 } 10818 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10819 pw.println("No providers match: " + name); 10820 pw.println("Use -h for help."); 10821 } 10822 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10823 synchronized (this) { 10824 dumpProvidersLocked(fd, pw, args, opti, true, null); 10825 } 10826 } else if ("service".equals(cmd)) { 10827 String[] newArgs; 10828 String name; 10829 if (opti >= args.length) { 10830 name = null; 10831 newArgs = EMPTY_STRING_ARRAY; 10832 } else { 10833 name = args[opti]; 10834 opti++; 10835 newArgs = new String[args.length - opti]; 10836 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10837 args.length - opti); 10838 } 10839 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10840 pw.println("No services match: " + name); 10841 pw.println("Use -h for help."); 10842 } 10843 } else if ("package".equals(cmd)) { 10844 String[] newArgs; 10845 if (opti >= args.length) { 10846 pw.println("package: no package name specified"); 10847 pw.println("Use -h for help."); 10848 } else { 10849 dumpPackage = args[opti]; 10850 opti++; 10851 newArgs = new String[args.length - opti]; 10852 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10853 args.length - opti); 10854 args = newArgs; 10855 opti = 0; 10856 more = true; 10857 } 10858 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10859 synchronized (this) { 10860 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10861 } 10862 } else { 10863 // Dumping a single activity? 10864 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10865 pw.println("Bad activity command, or no activities match: " + cmd); 10866 pw.println("Use -h for help."); 10867 } 10868 } 10869 if (!more) { 10870 Binder.restoreCallingIdentity(origId); 10871 return; 10872 } 10873 } 10874 10875 // No piece of data specified, dump everything. 10876 synchronized (this) { 10877 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10878 pw.println(); 10879 if (dumpAll) { 10880 pw.println("-------------------------------------------------------------------------------"); 10881 } 10882 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10883 pw.println(); 10884 if (dumpAll) { 10885 pw.println("-------------------------------------------------------------------------------"); 10886 } 10887 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10888 pw.println(); 10889 if (dumpAll) { 10890 pw.println("-------------------------------------------------------------------------------"); 10891 } 10892 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10893 pw.println(); 10894 if (dumpAll) { 10895 pw.println("-------------------------------------------------------------------------------"); 10896 } 10897 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10898 pw.println(); 10899 if (dumpAll) { 10900 pw.println("-------------------------------------------------------------------------------"); 10901 } 10902 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10903 } 10904 Binder.restoreCallingIdentity(origId); 10905 } 10906 10907 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10908 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10909 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10910 10911 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10912 dumpPackage); 10913 boolean needSep = printedAnything; 10914 10915 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10916 dumpPackage, needSep, " mFocusedActivity: "); 10917 if (printed) { 10918 printedAnything = true; 10919 needSep = false; 10920 } 10921 10922 if (dumpPackage == null) { 10923 if (needSep) { 10924 pw.println(); 10925 } 10926 needSep = true; 10927 printedAnything = true; 10928 mStackSupervisor.dump(pw, " "); 10929 } 10930 10931 if (mRecentTasks.size() > 0) { 10932 boolean printedHeader = false; 10933 10934 final int N = mRecentTasks.size(); 10935 for (int i=0; i<N; i++) { 10936 TaskRecord tr = mRecentTasks.get(i); 10937 if (dumpPackage != null) { 10938 if (tr.realActivity == null || 10939 !dumpPackage.equals(tr.realActivity)) { 10940 continue; 10941 } 10942 } 10943 if (!printedHeader) { 10944 if (needSep) { 10945 pw.println(); 10946 } 10947 pw.println(" Recent tasks:"); 10948 printedHeader = true; 10949 printedAnything = true; 10950 } 10951 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10952 pw.println(tr); 10953 if (dumpAll) { 10954 mRecentTasks.get(i).dump(pw, " "); 10955 } 10956 } 10957 } 10958 10959 if (!printedAnything) { 10960 pw.println(" (nothing)"); 10961 } 10962 } 10963 10964 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10965 int opti, boolean dumpAll, String dumpPackage) { 10966 boolean needSep = false; 10967 boolean printedAnything = false; 10968 int numPers = 0; 10969 10970 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10971 10972 if (dumpAll) { 10973 final int NP = mProcessNames.getMap().size(); 10974 for (int ip=0; ip<NP; ip++) { 10975 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10976 final int NA = procs.size(); 10977 for (int ia=0; ia<NA; ia++) { 10978 ProcessRecord r = procs.valueAt(ia); 10979 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10980 continue; 10981 } 10982 if (!needSep) { 10983 pw.println(" All known processes:"); 10984 needSep = true; 10985 printedAnything = true; 10986 } 10987 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10988 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10989 pw.print(" "); pw.println(r); 10990 r.dump(pw, " "); 10991 if (r.persistent) { 10992 numPers++; 10993 } 10994 } 10995 } 10996 } 10997 10998 if (mIsolatedProcesses.size() > 0) { 10999 boolean printed = false; 11000 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11001 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11002 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11003 continue; 11004 } 11005 if (!printed) { 11006 if (needSep) { 11007 pw.println(); 11008 } 11009 pw.println(" Isolated process list (sorted by uid):"); 11010 printedAnything = true; 11011 printed = true; 11012 needSep = true; 11013 } 11014 pw.println(String.format("%sIsolated #%2d: %s", 11015 " ", i, r.toString())); 11016 } 11017 } 11018 11019 if (mLruProcesses.size() > 0) { 11020 if (needSep) { 11021 pw.println(); 11022 } 11023 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11024 pw.print(" total, non-act at "); 11025 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11026 pw.print(", non-svc at "); 11027 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11028 pw.println("):"); 11029 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11030 needSep = true; 11031 printedAnything = true; 11032 } 11033 11034 if (dumpAll || dumpPackage != null) { 11035 synchronized (mPidsSelfLocked) { 11036 boolean printed = false; 11037 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11038 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11039 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11040 continue; 11041 } 11042 if (!printed) { 11043 if (needSep) pw.println(); 11044 needSep = true; 11045 pw.println(" PID mappings:"); 11046 printed = true; 11047 printedAnything = true; 11048 } 11049 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11050 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11051 } 11052 } 11053 } 11054 11055 if (mForegroundProcesses.size() > 0) { 11056 synchronized (mPidsSelfLocked) { 11057 boolean printed = false; 11058 for (int i=0; i<mForegroundProcesses.size(); i++) { 11059 ProcessRecord r = mPidsSelfLocked.get( 11060 mForegroundProcesses.valueAt(i).pid); 11061 if (dumpPackage != null && (r == null 11062 || !r.pkgList.containsKey(dumpPackage))) { 11063 continue; 11064 } 11065 if (!printed) { 11066 if (needSep) pw.println(); 11067 needSep = true; 11068 pw.println(" Foreground Processes:"); 11069 printed = true; 11070 printedAnything = true; 11071 } 11072 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11073 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11074 } 11075 } 11076 } 11077 11078 if (mPersistentStartingProcesses.size() > 0) { 11079 if (needSep) pw.println(); 11080 needSep = true; 11081 printedAnything = true; 11082 pw.println(" Persisent processes that are starting:"); 11083 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11084 "Starting Norm", "Restarting PERS", dumpPackage); 11085 } 11086 11087 if (mRemovedProcesses.size() > 0) { 11088 if (needSep) pw.println(); 11089 needSep = true; 11090 printedAnything = true; 11091 pw.println(" Processes that are being removed:"); 11092 dumpProcessList(pw, this, mRemovedProcesses, " ", 11093 "Removed Norm", "Removed PERS", dumpPackage); 11094 } 11095 11096 if (mProcessesOnHold.size() > 0) { 11097 if (needSep) pw.println(); 11098 needSep = true; 11099 printedAnything = true; 11100 pw.println(" Processes that are on old until the system is ready:"); 11101 dumpProcessList(pw, this, mProcessesOnHold, " ", 11102 "OnHold Norm", "OnHold PERS", dumpPackage); 11103 } 11104 11105 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11106 11107 if (mProcessCrashTimes.getMap().size() > 0) { 11108 boolean printed = false; 11109 long now = SystemClock.uptimeMillis(); 11110 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11111 final int NP = pmap.size(); 11112 for (int ip=0; ip<NP; ip++) { 11113 String pname = pmap.keyAt(ip); 11114 SparseArray<Long> uids = pmap.valueAt(ip); 11115 final int N = uids.size(); 11116 for (int i=0; i<N; i++) { 11117 int puid = uids.keyAt(i); 11118 ProcessRecord r = mProcessNames.get(pname, puid); 11119 if (dumpPackage != null && (r == null 11120 || !r.pkgList.containsKey(dumpPackage))) { 11121 continue; 11122 } 11123 if (!printed) { 11124 if (needSep) pw.println(); 11125 needSep = true; 11126 pw.println(" Time since processes crashed:"); 11127 printed = true; 11128 printedAnything = true; 11129 } 11130 pw.print(" Process "); pw.print(pname); 11131 pw.print(" uid "); pw.print(puid); 11132 pw.print(": last crashed "); 11133 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11134 pw.println(" ago"); 11135 } 11136 } 11137 } 11138 11139 if (mBadProcesses.getMap().size() > 0) { 11140 boolean printed = false; 11141 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11142 final int NP = pmap.size(); 11143 for (int ip=0; ip<NP; ip++) { 11144 String pname = pmap.keyAt(ip); 11145 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11146 final int N = uids.size(); 11147 for (int i=0; i<N; i++) { 11148 int puid = uids.keyAt(i); 11149 ProcessRecord r = mProcessNames.get(pname, puid); 11150 if (dumpPackage != null && (r == null 11151 || !r.pkgList.containsKey(dumpPackage))) { 11152 continue; 11153 } 11154 if (!printed) { 11155 if (needSep) pw.println(); 11156 needSep = true; 11157 pw.println(" Bad processes:"); 11158 printedAnything = true; 11159 } 11160 BadProcessInfo info = uids.valueAt(i); 11161 pw.print(" Bad process "); pw.print(pname); 11162 pw.print(" uid "); pw.print(puid); 11163 pw.print(": crashed at time "); pw.println(info.time); 11164 if (info.shortMsg != null) { 11165 pw.print(" Short msg: "); pw.println(info.shortMsg); 11166 } 11167 if (info.longMsg != null) { 11168 pw.print(" Long msg: "); pw.println(info.longMsg); 11169 } 11170 if (info.stack != null) { 11171 pw.println(" Stack:"); 11172 int lastPos = 0; 11173 for (int pos=0; pos<info.stack.length(); pos++) { 11174 if (info.stack.charAt(pos) == '\n') { 11175 pw.print(" "); 11176 pw.write(info.stack, lastPos, pos-lastPos); 11177 pw.println(); 11178 lastPos = pos+1; 11179 } 11180 } 11181 if (lastPos < info.stack.length()) { 11182 pw.print(" "); 11183 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11184 pw.println(); 11185 } 11186 } 11187 } 11188 } 11189 } 11190 11191 if (dumpPackage == null) { 11192 pw.println(); 11193 needSep = false; 11194 pw.println(" mStartedUsers:"); 11195 for (int i=0; i<mStartedUsers.size(); i++) { 11196 UserStartedState uss = mStartedUsers.valueAt(i); 11197 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11198 pw.print(": "); uss.dump("", pw); 11199 } 11200 pw.print(" mStartedUserArray: ["); 11201 for (int i=0; i<mStartedUserArray.length; i++) { 11202 if (i > 0) pw.print(", "); 11203 pw.print(mStartedUserArray[i]); 11204 } 11205 pw.println("]"); 11206 pw.print(" mUserLru: ["); 11207 for (int i=0; i<mUserLru.size(); i++) { 11208 if (i > 0) pw.print(", "); 11209 pw.print(mUserLru.get(i)); 11210 } 11211 pw.println("]"); 11212 if (dumpAll) { 11213 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11214 } 11215 } 11216 if (mHomeProcess != null && (dumpPackage == null 11217 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11218 if (needSep) { 11219 pw.println(); 11220 needSep = false; 11221 } 11222 pw.println(" mHomeProcess: " + mHomeProcess); 11223 } 11224 if (mPreviousProcess != null && (dumpPackage == null 11225 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11226 if (needSep) { 11227 pw.println(); 11228 needSep = false; 11229 } 11230 pw.println(" mPreviousProcess: " + mPreviousProcess); 11231 } 11232 if (dumpAll) { 11233 StringBuilder sb = new StringBuilder(128); 11234 sb.append(" mPreviousProcessVisibleTime: "); 11235 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11236 pw.println(sb); 11237 } 11238 if (mHeavyWeightProcess != null && (dumpPackage == null 11239 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11240 if (needSep) { 11241 pw.println(); 11242 needSep = false; 11243 } 11244 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11245 } 11246 if (dumpPackage == null) { 11247 pw.println(" mConfiguration: " + mConfiguration); 11248 } 11249 if (dumpAll) { 11250 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11251 if (mCompatModePackages.getPackages().size() > 0) { 11252 boolean printed = false; 11253 for (Map.Entry<String, Integer> entry 11254 : mCompatModePackages.getPackages().entrySet()) { 11255 String pkg = entry.getKey(); 11256 int mode = entry.getValue(); 11257 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11258 continue; 11259 } 11260 if (!printed) { 11261 pw.println(" mScreenCompatPackages:"); 11262 printed = true; 11263 } 11264 pw.print(" "); pw.print(pkg); pw.print(": "); 11265 pw.print(mode); pw.println(); 11266 } 11267 } 11268 } 11269 if (dumpPackage == null) { 11270 if (mSleeping || mWentToSleep || mLockScreenShown) { 11271 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11272 + " mLockScreenShown " + mLockScreenShown); 11273 } 11274 if (mShuttingDown || mRunningVoice) { 11275 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11276 } 11277 } 11278 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11279 || mOrigWaitForDebugger) { 11280 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11281 || dumpPackage.equals(mOrigDebugApp)) { 11282 if (needSep) { 11283 pw.println(); 11284 needSep = false; 11285 } 11286 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11287 + " mDebugTransient=" + mDebugTransient 11288 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11289 } 11290 } 11291 if (mOpenGlTraceApp != null) { 11292 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11293 if (needSep) { 11294 pw.println(); 11295 needSep = false; 11296 } 11297 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11298 } 11299 } 11300 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11301 || mProfileFd != null) { 11302 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11303 if (needSep) { 11304 pw.println(); 11305 needSep = false; 11306 } 11307 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11308 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11309 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11310 + mAutoStopProfiler); 11311 } 11312 } 11313 if (dumpPackage == null) { 11314 if (mAlwaysFinishActivities || mController != null) { 11315 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11316 + " mController=" + mController); 11317 } 11318 if (dumpAll) { 11319 pw.println(" Total persistent processes: " + numPers); 11320 pw.println(" mProcessesReady=" + mProcessesReady 11321 + " mSystemReady=" + mSystemReady); 11322 pw.println(" mBooting=" + mBooting 11323 + " mBooted=" + mBooted 11324 + " mFactoryTest=" + mFactoryTest); 11325 pw.print(" mLastPowerCheckRealtime="); 11326 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11327 pw.println(""); 11328 pw.print(" mLastPowerCheckUptime="); 11329 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11330 pw.println(""); 11331 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11332 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11333 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11334 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11335 + " (" + mLruProcesses.size() + " total)" 11336 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11337 + " mNumServiceProcs=" + mNumServiceProcs 11338 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11339 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11340 + " mLastMemoryLevel" + mLastMemoryLevel 11341 + " mLastNumProcesses" + mLastNumProcesses); 11342 long now = SystemClock.uptimeMillis(); 11343 pw.print(" mLastIdleTime="); 11344 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11345 pw.print(" mLowRamSinceLastIdle="); 11346 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11347 pw.println(); 11348 } 11349 } 11350 11351 if (!printedAnything) { 11352 pw.println(" (nothing)"); 11353 } 11354 } 11355 11356 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11357 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11358 if (mProcessesToGc.size() > 0) { 11359 boolean printed = false; 11360 long now = SystemClock.uptimeMillis(); 11361 for (int i=0; i<mProcessesToGc.size(); i++) { 11362 ProcessRecord proc = mProcessesToGc.get(i); 11363 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11364 continue; 11365 } 11366 if (!printed) { 11367 if (needSep) pw.println(); 11368 needSep = true; 11369 pw.println(" Processes that are waiting to GC:"); 11370 printed = true; 11371 } 11372 pw.print(" Process "); pw.println(proc); 11373 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11374 pw.print(", last gced="); 11375 pw.print(now-proc.lastRequestedGc); 11376 pw.print(" ms ago, last lowMem="); 11377 pw.print(now-proc.lastLowMemory); 11378 pw.println(" ms ago"); 11379 11380 } 11381 } 11382 return needSep; 11383 } 11384 11385 void printOomLevel(PrintWriter pw, String name, int adj) { 11386 pw.print(" "); 11387 if (adj >= 0) { 11388 pw.print(' '); 11389 if (adj < 10) pw.print(' '); 11390 } else { 11391 if (adj > -10) pw.print(' '); 11392 } 11393 pw.print(adj); 11394 pw.print(": "); 11395 pw.print(name); 11396 pw.print(" ("); 11397 pw.print(mProcessList.getMemLevel(adj)/1024); 11398 pw.println(" kB)"); 11399 } 11400 11401 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11402 int opti, boolean dumpAll) { 11403 boolean needSep = false; 11404 11405 if (mLruProcesses.size() > 0) { 11406 if (needSep) pw.println(); 11407 needSep = true; 11408 pw.println(" OOM levels:"); 11409 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11410 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11411 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11412 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11413 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11414 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11415 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11416 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11417 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11418 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11419 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11420 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11421 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11422 11423 if (needSep) pw.println(); 11424 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11425 pw.print(" total, non-act at "); 11426 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11427 pw.print(", non-svc at "); 11428 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11429 pw.println("):"); 11430 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11431 needSep = true; 11432 } 11433 11434 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11435 11436 pw.println(); 11437 pw.println(" mHomeProcess: " + mHomeProcess); 11438 pw.println(" mPreviousProcess: " + mPreviousProcess); 11439 if (mHeavyWeightProcess != null) { 11440 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11441 } 11442 11443 return true; 11444 } 11445 11446 /** 11447 * There are three ways to call this: 11448 * - no provider specified: dump all the providers 11449 * - a flattened component name that matched an existing provider was specified as the 11450 * first arg: dump that one provider 11451 * - the first arg isn't the flattened component name of an existing provider: 11452 * dump all providers whose component contains the first arg as a substring 11453 */ 11454 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11455 int opti, boolean dumpAll) { 11456 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11457 } 11458 11459 static class ItemMatcher { 11460 ArrayList<ComponentName> components; 11461 ArrayList<String> strings; 11462 ArrayList<Integer> objects; 11463 boolean all; 11464 11465 ItemMatcher() { 11466 all = true; 11467 } 11468 11469 void build(String name) { 11470 ComponentName componentName = ComponentName.unflattenFromString(name); 11471 if (componentName != null) { 11472 if (components == null) { 11473 components = new ArrayList<ComponentName>(); 11474 } 11475 components.add(componentName); 11476 all = false; 11477 } else { 11478 int objectId = 0; 11479 // Not a '/' separated full component name; maybe an object ID? 11480 try { 11481 objectId = Integer.parseInt(name, 16); 11482 if (objects == null) { 11483 objects = new ArrayList<Integer>(); 11484 } 11485 objects.add(objectId); 11486 all = false; 11487 } catch (RuntimeException e) { 11488 // Not an integer; just do string match. 11489 if (strings == null) { 11490 strings = new ArrayList<String>(); 11491 } 11492 strings.add(name); 11493 all = false; 11494 } 11495 } 11496 } 11497 11498 int build(String[] args, int opti) { 11499 for (; opti<args.length; opti++) { 11500 String name = args[opti]; 11501 if ("--".equals(name)) { 11502 return opti+1; 11503 } 11504 build(name); 11505 } 11506 return opti; 11507 } 11508 11509 boolean match(Object object, ComponentName comp) { 11510 if (all) { 11511 return true; 11512 } 11513 if (components != null) { 11514 for (int i=0; i<components.size(); i++) { 11515 if (components.get(i).equals(comp)) { 11516 return true; 11517 } 11518 } 11519 } 11520 if (objects != null) { 11521 for (int i=0; i<objects.size(); i++) { 11522 if (System.identityHashCode(object) == objects.get(i)) { 11523 return true; 11524 } 11525 } 11526 } 11527 if (strings != null) { 11528 String flat = comp.flattenToString(); 11529 for (int i=0; i<strings.size(); i++) { 11530 if (flat.contains(strings.get(i))) { 11531 return true; 11532 } 11533 } 11534 } 11535 return false; 11536 } 11537 } 11538 11539 /** 11540 * There are three things that cmd can be: 11541 * - a flattened component name that matches an existing activity 11542 * - the cmd arg isn't the flattened component name of an existing activity: 11543 * dump all activity whose component contains the cmd as a substring 11544 * - A hex number of the ActivityRecord object instance. 11545 */ 11546 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11547 int opti, boolean dumpAll) { 11548 ArrayList<ActivityRecord> activities; 11549 11550 synchronized (this) { 11551 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11552 } 11553 11554 if (activities.size() <= 0) { 11555 return false; 11556 } 11557 11558 String[] newArgs = new String[args.length - opti]; 11559 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11560 11561 TaskRecord lastTask = null; 11562 boolean needSep = false; 11563 for (int i=activities.size()-1; i>=0; i--) { 11564 ActivityRecord r = activities.get(i); 11565 if (needSep) { 11566 pw.println(); 11567 } 11568 needSep = true; 11569 synchronized (this) { 11570 if (lastTask != r.task) { 11571 lastTask = r.task; 11572 pw.print("TASK "); pw.print(lastTask.affinity); 11573 pw.print(" id="); pw.println(lastTask.taskId); 11574 if (dumpAll) { 11575 lastTask.dump(pw, " "); 11576 } 11577 } 11578 } 11579 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11580 } 11581 return true; 11582 } 11583 11584 /** 11585 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11586 * there is a thread associated with the activity. 11587 */ 11588 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11589 final ActivityRecord r, String[] args, boolean dumpAll) { 11590 String innerPrefix = prefix + " "; 11591 synchronized (this) { 11592 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11593 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11594 pw.print(" pid="); 11595 if (r.app != null) pw.println(r.app.pid); 11596 else pw.println("(not running)"); 11597 if (dumpAll) { 11598 r.dump(pw, innerPrefix); 11599 } 11600 } 11601 if (r.app != null && r.app.thread != null) { 11602 // flush anything that is already in the PrintWriter since the thread is going 11603 // to write to the file descriptor directly 11604 pw.flush(); 11605 try { 11606 TransferPipe tp = new TransferPipe(); 11607 try { 11608 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11609 r.appToken, innerPrefix, args); 11610 tp.go(fd); 11611 } finally { 11612 tp.kill(); 11613 } 11614 } catch (IOException e) { 11615 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11616 } catch (RemoteException e) { 11617 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11618 } 11619 } 11620 } 11621 11622 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11623 int opti, boolean dumpAll, String dumpPackage) { 11624 boolean needSep = false; 11625 boolean onlyHistory = false; 11626 boolean printedAnything = false; 11627 11628 if ("history".equals(dumpPackage)) { 11629 if (opti < args.length && "-s".equals(args[opti])) { 11630 dumpAll = false; 11631 } 11632 onlyHistory = true; 11633 dumpPackage = null; 11634 } 11635 11636 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11637 if (!onlyHistory && dumpAll) { 11638 if (mRegisteredReceivers.size() > 0) { 11639 boolean printed = false; 11640 Iterator it = mRegisteredReceivers.values().iterator(); 11641 while (it.hasNext()) { 11642 ReceiverList r = (ReceiverList)it.next(); 11643 if (dumpPackage != null && (r.app == null || 11644 !dumpPackage.equals(r.app.info.packageName))) { 11645 continue; 11646 } 11647 if (!printed) { 11648 pw.println(" Registered Receivers:"); 11649 needSep = true; 11650 printed = true; 11651 printedAnything = true; 11652 } 11653 pw.print(" * "); pw.println(r); 11654 r.dump(pw, " "); 11655 } 11656 } 11657 11658 if (mReceiverResolver.dump(pw, needSep ? 11659 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11660 " ", dumpPackage, false)) { 11661 needSep = true; 11662 printedAnything = true; 11663 } 11664 } 11665 11666 for (BroadcastQueue q : mBroadcastQueues) { 11667 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11668 printedAnything |= needSep; 11669 } 11670 11671 needSep = true; 11672 11673 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11674 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11675 if (needSep) { 11676 pw.println(); 11677 } 11678 needSep = true; 11679 printedAnything = true; 11680 pw.print(" Sticky broadcasts for user "); 11681 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11682 StringBuilder sb = new StringBuilder(128); 11683 for (Map.Entry<String, ArrayList<Intent>> ent 11684 : mStickyBroadcasts.valueAt(user).entrySet()) { 11685 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11686 if (dumpAll) { 11687 pw.println(":"); 11688 ArrayList<Intent> intents = ent.getValue(); 11689 final int N = intents.size(); 11690 for (int i=0; i<N; i++) { 11691 sb.setLength(0); 11692 sb.append(" Intent: "); 11693 intents.get(i).toShortString(sb, false, true, false, false); 11694 pw.println(sb.toString()); 11695 Bundle bundle = intents.get(i).getExtras(); 11696 if (bundle != null) { 11697 pw.print(" "); 11698 pw.println(bundle.toString()); 11699 } 11700 } 11701 } else { 11702 pw.println(""); 11703 } 11704 } 11705 } 11706 } 11707 11708 if (!onlyHistory && dumpAll) { 11709 pw.println(); 11710 for (BroadcastQueue queue : mBroadcastQueues) { 11711 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11712 + queue.mBroadcastsScheduled); 11713 } 11714 pw.println(" mHandler:"); 11715 mHandler.dump(new PrintWriterPrinter(pw), " "); 11716 needSep = true; 11717 printedAnything = true; 11718 } 11719 11720 if (!printedAnything) { 11721 pw.println(" (nothing)"); 11722 } 11723 } 11724 11725 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11726 int opti, boolean dumpAll, String dumpPackage) { 11727 boolean needSep; 11728 boolean printedAnything = false; 11729 11730 ItemMatcher matcher = new ItemMatcher(); 11731 matcher.build(args, opti); 11732 11733 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11734 11735 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11736 printedAnything |= needSep; 11737 11738 if (mLaunchingProviders.size() > 0) { 11739 boolean printed = false; 11740 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11741 ContentProviderRecord r = mLaunchingProviders.get(i); 11742 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11743 continue; 11744 } 11745 if (!printed) { 11746 if (needSep) pw.println(); 11747 needSep = true; 11748 pw.println(" Launching content providers:"); 11749 printed = true; 11750 printedAnything = true; 11751 } 11752 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11753 pw.println(r); 11754 } 11755 } 11756 11757 if (mGrantedUriPermissions.size() > 0) { 11758 boolean printed = false; 11759 int dumpUid = -2; 11760 if (dumpPackage != null) { 11761 try { 11762 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11763 } catch (NameNotFoundException e) { 11764 dumpUid = -1; 11765 } 11766 } 11767 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11768 int uid = mGrantedUriPermissions.keyAt(i); 11769 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11770 continue; 11771 } 11772 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11773 if (!printed) { 11774 if (needSep) pw.println(); 11775 needSep = true; 11776 pw.println(" Granted Uri Permissions:"); 11777 printed = true; 11778 printedAnything = true; 11779 } 11780 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11781 for (UriPermission perm : perms.values()) { 11782 pw.print(" "); pw.println(perm); 11783 if (dumpAll) { 11784 perm.dump(pw, " "); 11785 } 11786 } 11787 } 11788 } 11789 11790 if (!printedAnything) { 11791 pw.println(" (nothing)"); 11792 } 11793 } 11794 11795 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11796 int opti, boolean dumpAll, String dumpPackage) { 11797 boolean printed = false; 11798 11799 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11800 11801 if (mIntentSenderRecords.size() > 0) { 11802 Iterator<WeakReference<PendingIntentRecord>> it 11803 = mIntentSenderRecords.values().iterator(); 11804 while (it.hasNext()) { 11805 WeakReference<PendingIntentRecord> ref = it.next(); 11806 PendingIntentRecord rec = ref != null ? ref.get(): null; 11807 if (dumpPackage != null && (rec == null 11808 || !dumpPackage.equals(rec.key.packageName))) { 11809 continue; 11810 } 11811 printed = true; 11812 if (rec != null) { 11813 pw.print(" * "); pw.println(rec); 11814 if (dumpAll) { 11815 rec.dump(pw, " "); 11816 } 11817 } else { 11818 pw.print(" * "); pw.println(ref); 11819 } 11820 } 11821 } 11822 11823 if (!printed) { 11824 pw.println(" (nothing)"); 11825 } 11826 } 11827 11828 private static final int dumpProcessList(PrintWriter pw, 11829 ActivityManagerService service, List list, 11830 String prefix, String normalLabel, String persistentLabel, 11831 String dumpPackage) { 11832 int numPers = 0; 11833 final int N = list.size()-1; 11834 for (int i=N; i>=0; i--) { 11835 ProcessRecord r = (ProcessRecord)list.get(i); 11836 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11837 continue; 11838 } 11839 pw.println(String.format("%s%s #%2d: %s", 11840 prefix, (r.persistent ? persistentLabel : normalLabel), 11841 i, r.toString())); 11842 if (r.persistent) { 11843 numPers++; 11844 } 11845 } 11846 return numPers; 11847 } 11848 11849 private static final boolean dumpProcessOomList(PrintWriter pw, 11850 ActivityManagerService service, List<ProcessRecord> origList, 11851 String prefix, String normalLabel, String persistentLabel, 11852 boolean inclDetails, String dumpPackage) { 11853 11854 ArrayList<Pair<ProcessRecord, Integer>> list 11855 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11856 for (int i=0; i<origList.size(); i++) { 11857 ProcessRecord r = origList.get(i); 11858 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11859 continue; 11860 } 11861 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11862 } 11863 11864 if (list.size() <= 0) { 11865 return false; 11866 } 11867 11868 Comparator<Pair<ProcessRecord, Integer>> comparator 11869 = new Comparator<Pair<ProcessRecord, Integer>>() { 11870 @Override 11871 public int compare(Pair<ProcessRecord, Integer> object1, 11872 Pair<ProcessRecord, Integer> object2) { 11873 if (object1.first.setAdj != object2.first.setAdj) { 11874 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11875 } 11876 if (object1.second.intValue() != object2.second.intValue()) { 11877 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11878 } 11879 return 0; 11880 } 11881 }; 11882 11883 Collections.sort(list, comparator); 11884 11885 final long curRealtime = SystemClock.elapsedRealtime(); 11886 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11887 final long curUptime = SystemClock.uptimeMillis(); 11888 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11889 11890 for (int i=list.size()-1; i>=0; i--) { 11891 ProcessRecord r = list.get(i).first; 11892 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11893 char schedGroup; 11894 switch (r.setSchedGroup) { 11895 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11896 schedGroup = 'B'; 11897 break; 11898 case Process.THREAD_GROUP_DEFAULT: 11899 schedGroup = 'F'; 11900 break; 11901 default: 11902 schedGroup = '?'; 11903 break; 11904 } 11905 char foreground; 11906 if (r.foregroundActivities) { 11907 foreground = 'A'; 11908 } else if (r.foregroundServices) { 11909 foreground = 'S'; 11910 } else { 11911 foreground = ' '; 11912 } 11913 String procState = ProcessList.makeProcStateString(r.curProcState); 11914 pw.print(prefix); 11915 pw.print(r.persistent ? persistentLabel : normalLabel); 11916 pw.print(" #"); 11917 int num = (origList.size()-1)-list.get(i).second; 11918 if (num < 10) pw.print(' '); 11919 pw.print(num); 11920 pw.print(": "); 11921 pw.print(oomAdj); 11922 pw.print(' '); 11923 pw.print(schedGroup); 11924 pw.print('/'); 11925 pw.print(foreground); 11926 pw.print('/'); 11927 pw.print(procState); 11928 pw.print(" trm:"); 11929 if (r.trimMemoryLevel < 10) pw.print(' '); 11930 pw.print(r.trimMemoryLevel); 11931 pw.print(' '); 11932 pw.print(r.toShortString()); 11933 pw.print(" ("); 11934 pw.print(r.adjType); 11935 pw.println(')'); 11936 if (r.adjSource != null || r.adjTarget != null) { 11937 pw.print(prefix); 11938 pw.print(" "); 11939 if (r.adjTarget instanceof ComponentName) { 11940 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11941 } else if (r.adjTarget != null) { 11942 pw.print(r.adjTarget.toString()); 11943 } else { 11944 pw.print("{null}"); 11945 } 11946 pw.print("<="); 11947 if (r.adjSource instanceof ProcessRecord) { 11948 pw.print("Proc{"); 11949 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11950 pw.println("}"); 11951 } else if (r.adjSource != null) { 11952 pw.println(r.adjSource.toString()); 11953 } else { 11954 pw.println("{null}"); 11955 } 11956 } 11957 if (inclDetails) { 11958 pw.print(prefix); 11959 pw.print(" "); 11960 pw.print("oom: max="); pw.print(r.maxAdj); 11961 pw.print(" curRaw="); pw.print(r.curRawAdj); 11962 pw.print(" setRaw="); pw.print(r.setRawAdj); 11963 pw.print(" cur="); pw.print(r.curAdj); 11964 pw.print(" set="); pw.println(r.setAdj); 11965 pw.print(prefix); 11966 pw.print(" "); 11967 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11968 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11969 pw.print(" lastPss="); pw.print(r.lastPss); 11970 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11971 pw.print(prefix); 11972 pw.print(" "); 11973 pw.print("keeping="); pw.print(r.keeping); 11974 pw.print(" cached="); pw.print(r.cached); 11975 pw.print(" empty="); pw.print(r.empty); 11976 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11977 11978 if (!r.keeping) { 11979 if (r.lastWakeTime != 0) { 11980 long wtime; 11981 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11982 synchronized (stats) { 11983 wtime = stats.getProcessWakeTime(r.info.uid, 11984 r.pid, curRealtime); 11985 } 11986 long timeUsed = wtime - r.lastWakeTime; 11987 pw.print(prefix); 11988 pw.print(" "); 11989 pw.print("keep awake over "); 11990 TimeUtils.formatDuration(realtimeSince, pw); 11991 pw.print(" used "); 11992 TimeUtils.formatDuration(timeUsed, pw); 11993 pw.print(" ("); 11994 pw.print((timeUsed*100)/realtimeSince); 11995 pw.println("%)"); 11996 } 11997 if (r.lastCpuTime != 0) { 11998 long timeUsed = r.curCpuTime - r.lastCpuTime; 11999 pw.print(prefix); 12000 pw.print(" "); 12001 pw.print("run cpu over "); 12002 TimeUtils.formatDuration(uptimeSince, pw); 12003 pw.print(" used "); 12004 TimeUtils.formatDuration(timeUsed, pw); 12005 pw.print(" ("); 12006 pw.print((timeUsed*100)/uptimeSince); 12007 pw.println("%)"); 12008 } 12009 } 12010 } 12011 } 12012 return true; 12013 } 12014 12015 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12016 ArrayList<ProcessRecord> procs; 12017 synchronized (this) { 12018 if (args != null && args.length > start 12019 && args[start].charAt(0) != '-') { 12020 procs = new ArrayList<ProcessRecord>(); 12021 int pid = -1; 12022 try { 12023 pid = Integer.parseInt(args[start]); 12024 } catch (NumberFormatException e) { 12025 } 12026 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12027 ProcessRecord proc = mLruProcesses.get(i); 12028 if (proc.pid == pid) { 12029 procs.add(proc); 12030 } else if (proc.processName.equals(args[start])) { 12031 procs.add(proc); 12032 } 12033 } 12034 if (procs.size() <= 0) { 12035 return null; 12036 } 12037 } else { 12038 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12039 } 12040 } 12041 return procs; 12042 } 12043 12044 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12045 PrintWriter pw, String[] args) { 12046 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12047 if (procs == null) { 12048 pw.println("No process found for: " + args[0]); 12049 return; 12050 } 12051 12052 long uptime = SystemClock.uptimeMillis(); 12053 long realtime = SystemClock.elapsedRealtime(); 12054 pw.println("Applications Graphics Acceleration Info:"); 12055 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12056 12057 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12058 ProcessRecord r = procs.get(i); 12059 if (r.thread != null) { 12060 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12061 pw.flush(); 12062 try { 12063 TransferPipe tp = new TransferPipe(); 12064 try { 12065 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12066 tp.go(fd); 12067 } finally { 12068 tp.kill(); 12069 } 12070 } catch (IOException e) { 12071 pw.println("Failure while dumping the app: " + r); 12072 pw.flush(); 12073 } catch (RemoteException e) { 12074 pw.println("Got a RemoteException while dumping the app " + r); 12075 pw.flush(); 12076 } 12077 } 12078 } 12079 } 12080 12081 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12082 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12083 if (procs == null) { 12084 pw.println("No process found for: " + args[0]); 12085 return; 12086 } 12087 12088 pw.println("Applications Database Info:"); 12089 12090 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12091 ProcessRecord r = procs.get(i); 12092 if (r.thread != null) { 12093 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12094 pw.flush(); 12095 try { 12096 TransferPipe tp = new TransferPipe(); 12097 try { 12098 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12099 tp.go(fd); 12100 } finally { 12101 tp.kill(); 12102 } 12103 } catch (IOException e) { 12104 pw.println("Failure while dumping the app: " + r); 12105 pw.flush(); 12106 } catch (RemoteException e) { 12107 pw.println("Got a RemoteException while dumping the app " + r); 12108 pw.flush(); 12109 } 12110 } 12111 } 12112 } 12113 12114 final static class MemItem { 12115 final boolean isProc; 12116 final String label; 12117 final String shortLabel; 12118 final long pss; 12119 final int id; 12120 final boolean hasActivities; 12121 ArrayList<MemItem> subitems; 12122 12123 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12124 boolean _hasActivities) { 12125 isProc = true; 12126 label = _label; 12127 shortLabel = _shortLabel; 12128 pss = _pss; 12129 id = _id; 12130 hasActivities = _hasActivities; 12131 } 12132 12133 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12134 isProc = false; 12135 label = _label; 12136 shortLabel = _shortLabel; 12137 pss = _pss; 12138 id = _id; 12139 hasActivities = false; 12140 } 12141 } 12142 12143 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12144 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12145 if (sort && !isCompact) { 12146 Collections.sort(items, new Comparator<MemItem>() { 12147 @Override 12148 public int compare(MemItem lhs, MemItem rhs) { 12149 if (lhs.pss < rhs.pss) { 12150 return 1; 12151 } else if (lhs.pss > rhs.pss) { 12152 return -1; 12153 } 12154 return 0; 12155 } 12156 }); 12157 } 12158 12159 for (int i=0; i<items.size(); i++) { 12160 MemItem mi = items.get(i); 12161 if (!isCompact) { 12162 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12163 } else if (mi.isProc) { 12164 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12165 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12166 pw.println(mi.hasActivities ? ",a" : ",e"); 12167 } else { 12168 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12169 pw.println(mi.pss); 12170 } 12171 if (mi.subitems != null) { 12172 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12173 true, isCompact); 12174 } 12175 } 12176 } 12177 12178 // These are in KB. 12179 static final long[] DUMP_MEM_BUCKETS = new long[] { 12180 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12181 120*1024, 160*1024, 200*1024, 12182 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12183 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12184 }; 12185 12186 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12187 boolean stackLike) { 12188 int start = label.lastIndexOf('.'); 12189 if (start >= 0) start++; 12190 else start = 0; 12191 int end = label.length(); 12192 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12193 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12194 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12195 out.append(bucket); 12196 out.append(stackLike ? "MB." : "MB "); 12197 out.append(label, start, end); 12198 return; 12199 } 12200 } 12201 out.append(memKB/1024); 12202 out.append(stackLike ? "MB." : "MB "); 12203 out.append(label, start, end); 12204 } 12205 12206 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12207 ProcessList.NATIVE_ADJ, 12208 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12209 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12210 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12211 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12212 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12213 }; 12214 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12215 "Native", 12216 "System", "Persistent", "Foreground", 12217 "Visible", "Perceptible", 12218 "Heavy Weight", "Backup", 12219 "A Services", "Home", 12220 "Previous", "B Services", "Cached" 12221 }; 12222 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12223 "native", 12224 "sys", "pers", "fore", 12225 "vis", "percept", 12226 "heavy", "backup", 12227 "servicea", "home", 12228 "prev", "serviceb", "cached" 12229 }; 12230 12231 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12232 long realtime, boolean isCheckinRequest, boolean isCompact) { 12233 if (isCheckinRequest || isCompact) { 12234 // short checkin version 12235 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12236 } else { 12237 pw.println("Applications Memory Usage (kB):"); 12238 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12239 } 12240 } 12241 12242 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12243 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12244 boolean dumpDetails = false; 12245 boolean dumpFullDetails = false; 12246 boolean dumpDalvik = false; 12247 boolean oomOnly = false; 12248 boolean isCompact = false; 12249 boolean localOnly = false; 12250 12251 int opti = 0; 12252 while (opti < args.length) { 12253 String opt = args[opti]; 12254 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12255 break; 12256 } 12257 opti++; 12258 if ("-a".equals(opt)) { 12259 dumpDetails = true; 12260 dumpFullDetails = true; 12261 dumpDalvik = true; 12262 } else if ("-d".equals(opt)) { 12263 dumpDalvik = true; 12264 } else if ("-c".equals(opt)) { 12265 isCompact = true; 12266 } else if ("--oom".equals(opt)) { 12267 oomOnly = true; 12268 } else if ("--local".equals(opt)) { 12269 localOnly = true; 12270 } else if ("-h".equals(opt)) { 12271 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12272 pw.println(" -a: include all available information for each process."); 12273 pw.println(" -d: include dalvik details when dumping process details."); 12274 pw.println(" -c: dump in a compact machine-parseable representation."); 12275 pw.println(" --oom: only show processes organized by oom adj."); 12276 pw.println(" --local: only collect details locally, don't call process."); 12277 pw.println("If [process] is specified it can be the name or "); 12278 pw.println("pid of a specific process to dump."); 12279 return; 12280 } else { 12281 pw.println("Unknown argument: " + opt + "; use -h for help"); 12282 } 12283 } 12284 12285 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12286 long uptime = SystemClock.uptimeMillis(); 12287 long realtime = SystemClock.elapsedRealtime(); 12288 final long[] tmpLong = new long[1]; 12289 12290 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12291 if (procs == null) { 12292 // No Java processes. Maybe they want to print a native process. 12293 if (args != null && args.length > opti 12294 && args[opti].charAt(0) != '-') { 12295 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12296 = new ArrayList<ProcessCpuTracker.Stats>(); 12297 updateCpuStatsNow(); 12298 int findPid = -1; 12299 try { 12300 findPid = Integer.parseInt(args[opti]); 12301 } catch (NumberFormatException e) { 12302 } 12303 synchronized (mProcessCpuThread) { 12304 final int N = mProcessCpuTracker.countStats(); 12305 for (int i=0; i<N; i++) { 12306 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12307 if (st.pid == findPid || (st.baseName != null 12308 && st.baseName.equals(args[opti]))) { 12309 nativeProcs.add(st); 12310 } 12311 } 12312 } 12313 if (nativeProcs.size() > 0) { 12314 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12315 isCompact); 12316 Debug.MemoryInfo mi = null; 12317 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12318 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12319 final int pid = r.pid; 12320 if (!isCheckinRequest && dumpDetails) { 12321 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12322 } 12323 if (mi == null) { 12324 mi = new Debug.MemoryInfo(); 12325 } 12326 if (dumpDetails || (!brief && !oomOnly)) { 12327 Debug.getMemoryInfo(pid, mi); 12328 } else { 12329 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12330 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12331 } 12332 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12333 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12334 if (isCheckinRequest) { 12335 pw.println(); 12336 } 12337 } 12338 return; 12339 } 12340 } 12341 pw.println("No process found for: " + args[opti]); 12342 return; 12343 } 12344 12345 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12346 dumpDetails = true; 12347 } 12348 12349 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12350 12351 String[] innerArgs = new String[args.length-opti]; 12352 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12353 12354 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12355 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12356 long nativePss=0, dalvikPss=0, otherPss=0; 12357 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12358 12359 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12360 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12361 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12362 12363 long totalPss = 0; 12364 long cachedPss = 0; 12365 12366 Debug.MemoryInfo mi = null; 12367 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12368 final ProcessRecord r = procs.get(i); 12369 final IApplicationThread thread; 12370 final int pid; 12371 final int oomAdj; 12372 final boolean hasActivities; 12373 synchronized (this) { 12374 thread = r.thread; 12375 pid = r.pid; 12376 oomAdj = r.getSetAdjWithServices(); 12377 hasActivities = r.activities.size() > 0; 12378 } 12379 if (thread != null) { 12380 if (!isCheckinRequest && dumpDetails) { 12381 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12382 } 12383 if (mi == null) { 12384 mi = new Debug.MemoryInfo(); 12385 } 12386 if (dumpDetails || (!brief && !oomOnly)) { 12387 Debug.getMemoryInfo(pid, mi); 12388 } else { 12389 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12390 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12391 } 12392 if (dumpDetails) { 12393 if (localOnly) { 12394 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12395 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12396 if (isCheckinRequest) { 12397 pw.println(); 12398 } 12399 } else { 12400 try { 12401 pw.flush(); 12402 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12403 dumpDalvik, innerArgs); 12404 } catch (RemoteException e) { 12405 if (!isCheckinRequest) { 12406 pw.println("Got RemoteException!"); 12407 pw.flush(); 12408 } 12409 } 12410 } 12411 } 12412 12413 final long myTotalPss = mi.getTotalPss(); 12414 final long myTotalUss = mi.getTotalUss(); 12415 12416 synchronized (this) { 12417 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12418 // Record this for posterity if the process has been stable. 12419 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12420 } 12421 } 12422 12423 if (!isCheckinRequest && mi != null) { 12424 totalPss += myTotalPss; 12425 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12426 (hasActivities ? " / activities)" : ")"), 12427 r.processName, myTotalPss, pid, hasActivities); 12428 procMems.add(pssItem); 12429 procMemsMap.put(pid, pssItem); 12430 12431 nativePss += mi.nativePss; 12432 dalvikPss += mi.dalvikPss; 12433 otherPss += mi.otherPss; 12434 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12435 long mem = mi.getOtherPss(j); 12436 miscPss[j] += mem; 12437 otherPss -= mem; 12438 } 12439 12440 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12441 cachedPss += myTotalPss; 12442 } 12443 12444 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12445 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12446 || oomIndex == (oomPss.length-1)) { 12447 oomPss[oomIndex] += myTotalPss; 12448 if (oomProcs[oomIndex] == null) { 12449 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12450 } 12451 oomProcs[oomIndex].add(pssItem); 12452 break; 12453 } 12454 } 12455 } 12456 } 12457 } 12458 12459 if (!isCheckinRequest && procs.size() > 1) { 12460 // If we are showing aggregations, also look for native processes to 12461 // include so that our aggregations are more accurate. 12462 updateCpuStatsNow(); 12463 synchronized (mProcessCpuThread) { 12464 final int N = mProcessCpuTracker.countStats(); 12465 for (int i=0; i<N; i++) { 12466 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12467 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12468 if (mi == null) { 12469 mi = new Debug.MemoryInfo(); 12470 } 12471 if (!brief && !oomOnly) { 12472 Debug.getMemoryInfo(st.pid, mi); 12473 } else { 12474 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12475 mi.nativePrivateDirty = (int)tmpLong[0]; 12476 } 12477 12478 final long myTotalPss = mi.getTotalPss(); 12479 totalPss += myTotalPss; 12480 12481 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12482 st.name, myTotalPss, st.pid, false); 12483 procMems.add(pssItem); 12484 12485 nativePss += mi.nativePss; 12486 dalvikPss += mi.dalvikPss; 12487 otherPss += mi.otherPss; 12488 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12489 long mem = mi.getOtherPss(j); 12490 miscPss[j] += mem; 12491 otherPss -= mem; 12492 } 12493 oomPss[0] += myTotalPss; 12494 if (oomProcs[0] == null) { 12495 oomProcs[0] = new ArrayList<MemItem>(); 12496 } 12497 oomProcs[0].add(pssItem); 12498 } 12499 } 12500 } 12501 12502 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12503 12504 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12505 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12506 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12507 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12508 String label = Debug.MemoryInfo.getOtherLabel(j); 12509 catMems.add(new MemItem(label, label, miscPss[j], j)); 12510 } 12511 12512 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12513 for (int j=0; j<oomPss.length; j++) { 12514 if (oomPss[j] != 0) { 12515 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12516 : DUMP_MEM_OOM_LABEL[j]; 12517 MemItem item = new MemItem(label, label, oomPss[j], 12518 DUMP_MEM_OOM_ADJ[j]); 12519 item.subitems = oomProcs[j]; 12520 oomMems.add(item); 12521 } 12522 } 12523 12524 if (!brief && !oomOnly && !isCompact) { 12525 pw.println(); 12526 pw.println("Total PSS by process:"); 12527 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12528 pw.println(); 12529 } 12530 if (!isCompact) { 12531 pw.println("Total PSS by OOM adjustment:"); 12532 } 12533 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12534 if (!brief && !oomOnly) { 12535 PrintWriter out = categoryPw != null ? categoryPw : pw; 12536 if (!isCompact) { 12537 out.println(); 12538 out.println("Total PSS by category:"); 12539 } 12540 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12541 } 12542 if (!isCompact) { 12543 pw.println(); 12544 } 12545 MemInfoReader memInfo = new MemInfoReader(); 12546 memInfo.readMemInfo(); 12547 if (!brief) { 12548 if (!isCompact) { 12549 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12550 pw.print(" kB (status "); 12551 switch (mLastMemoryLevel) { 12552 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12553 pw.println("normal)"); 12554 break; 12555 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12556 pw.println("moderate)"); 12557 break; 12558 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12559 pw.println("low)"); 12560 break; 12561 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12562 pw.println("critical)"); 12563 break; 12564 default: 12565 pw.print(mLastMemoryLevel); 12566 pw.println(")"); 12567 break; 12568 } 12569 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12570 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12571 pw.print(cachedPss); pw.print(" cached pss + "); 12572 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12573 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12574 } else { 12575 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12576 pw.print(cachedPss + memInfo.getCachedSizeKb() 12577 + memInfo.getFreeSizeKb()); pw.print(","); 12578 pw.println(totalPss - cachedPss); 12579 } 12580 } 12581 if (!isCompact) { 12582 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12583 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12584 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12585 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12586 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12587 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12588 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12589 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12590 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12591 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12592 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12593 } 12594 if (!brief) { 12595 if (memInfo.getZramTotalSizeKb() != 0) { 12596 if (!isCompact) { 12597 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12598 pw.print(" kB physical used for "); 12599 pw.print(memInfo.getSwapTotalSizeKb() 12600 - memInfo.getSwapFreeSizeKb()); 12601 pw.print(" kB in swap ("); 12602 pw.print(memInfo.getSwapTotalSizeKb()); 12603 pw.println(" kB total swap)"); 12604 } else { 12605 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12606 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12607 pw.println(memInfo.getSwapFreeSizeKb()); 12608 } 12609 } 12610 final int[] SINGLE_LONG_FORMAT = new int[] { 12611 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12612 }; 12613 long[] longOut = new long[1]; 12614 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12615 SINGLE_LONG_FORMAT, null, longOut, null); 12616 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12617 longOut[0] = 0; 12618 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12619 SINGLE_LONG_FORMAT, null, longOut, null); 12620 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12621 longOut[0] = 0; 12622 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12623 SINGLE_LONG_FORMAT, null, longOut, null); 12624 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12625 longOut[0] = 0; 12626 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12627 SINGLE_LONG_FORMAT, null, longOut, null); 12628 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12629 if (!isCompact) { 12630 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12631 pw.print(" KSM: "); pw.print(sharing); 12632 pw.print(" kB saved from shared "); 12633 pw.print(shared); pw.println(" kB"); 12634 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12635 pw.print(voltile); pw.println(" kB volatile"); 12636 } 12637 pw.print(" Tuning: "); 12638 pw.print(ActivityManager.staticGetMemoryClass()); 12639 pw.print(" (large "); 12640 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12641 pw.print("), oom "); 12642 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12643 pw.print(" kB"); 12644 pw.print(", restore limit "); 12645 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12646 pw.print(" kB"); 12647 if (ActivityManager.isLowRamDeviceStatic()) { 12648 pw.print(" (low-ram)"); 12649 } 12650 if (ActivityManager.isHighEndGfx()) { 12651 pw.print(" (high-end-gfx)"); 12652 } 12653 pw.println(); 12654 } else { 12655 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12656 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12657 pw.println(voltile); 12658 pw.print("tuning,"); 12659 pw.print(ActivityManager.staticGetMemoryClass()); 12660 pw.print(','); 12661 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12662 pw.print(','); 12663 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12664 if (ActivityManager.isLowRamDeviceStatic()) { 12665 pw.print(",low-ram"); 12666 } 12667 if (ActivityManager.isHighEndGfx()) { 12668 pw.print(",high-end-gfx"); 12669 } 12670 pw.println(); 12671 } 12672 } 12673 } 12674 } 12675 12676 /** 12677 * Searches array of arguments for the specified string 12678 * @param args array of argument strings 12679 * @param value value to search for 12680 * @return true if the value is contained in the array 12681 */ 12682 private static boolean scanArgs(String[] args, String value) { 12683 if (args != null) { 12684 for (String arg : args) { 12685 if (value.equals(arg)) { 12686 return true; 12687 } 12688 } 12689 } 12690 return false; 12691 } 12692 12693 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12694 ContentProviderRecord cpr, boolean always) { 12695 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12696 12697 if (!inLaunching || always) { 12698 synchronized (cpr) { 12699 cpr.launchingApp = null; 12700 cpr.notifyAll(); 12701 } 12702 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12703 String names[] = cpr.info.authority.split(";"); 12704 for (int j = 0; j < names.length; j++) { 12705 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12706 } 12707 } 12708 12709 for (int i=0; i<cpr.connections.size(); i++) { 12710 ContentProviderConnection conn = cpr.connections.get(i); 12711 if (conn.waiting) { 12712 // If this connection is waiting for the provider, then we don't 12713 // need to mess with its process unless we are always removing 12714 // or for some reason the provider is not currently launching. 12715 if (inLaunching && !always) { 12716 continue; 12717 } 12718 } 12719 ProcessRecord capp = conn.client; 12720 conn.dead = true; 12721 if (conn.stableCount > 0) { 12722 if (!capp.persistent && capp.thread != null 12723 && capp.pid != 0 12724 && capp.pid != MY_PID) { 12725 killUnneededProcessLocked(capp, "depends on provider " 12726 + cpr.name.flattenToShortString() 12727 + " in dying proc " + (proc != null ? proc.processName : "??")); 12728 } 12729 } else if (capp.thread != null && conn.provider.provider != null) { 12730 try { 12731 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12732 } catch (RemoteException e) { 12733 } 12734 // In the protocol here, we don't expect the client to correctly 12735 // clean up this connection, we'll just remove it. 12736 cpr.connections.remove(i); 12737 conn.client.conProviders.remove(conn); 12738 } 12739 } 12740 12741 if (inLaunching && always) { 12742 mLaunchingProviders.remove(cpr); 12743 } 12744 return inLaunching; 12745 } 12746 12747 /** 12748 * Main code for cleaning up a process when it has gone away. This is 12749 * called both as a result of the process dying, or directly when stopping 12750 * a process when running in single process mode. 12751 */ 12752 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12753 boolean restarting, boolean allowRestart, int index) { 12754 if (index >= 0) { 12755 removeLruProcessLocked(app); 12756 ProcessList.remove(app.pid); 12757 } 12758 12759 mProcessesToGc.remove(app); 12760 mPendingPssProcesses.remove(app); 12761 12762 // Dismiss any open dialogs. 12763 if (app.crashDialog != null && !app.forceCrashReport) { 12764 app.crashDialog.dismiss(); 12765 app.crashDialog = null; 12766 } 12767 if (app.anrDialog != null) { 12768 app.anrDialog.dismiss(); 12769 app.anrDialog = null; 12770 } 12771 if (app.waitDialog != null) { 12772 app.waitDialog.dismiss(); 12773 app.waitDialog = null; 12774 } 12775 12776 app.crashing = false; 12777 app.notResponding = false; 12778 12779 app.resetPackageList(mProcessStats); 12780 app.unlinkDeathRecipient(); 12781 app.makeInactive(mProcessStats); 12782 app.forcingToForeground = null; 12783 updateProcessForegroundLocked(app, false, false); 12784 app.foregroundActivities = false; 12785 app.hasShownUi = false; 12786 app.treatLikeActivity = false; 12787 app.hasAboveClient = false; 12788 app.hasClientActivities = false; 12789 12790 mServices.killServicesLocked(app, allowRestart); 12791 12792 boolean restart = false; 12793 12794 // Remove published content providers. 12795 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12796 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12797 final boolean always = app.bad || !allowRestart; 12798 if (removeDyingProviderLocked(app, cpr, always) || always) { 12799 // We left the provider in the launching list, need to 12800 // restart it. 12801 restart = true; 12802 } 12803 12804 cpr.provider = null; 12805 cpr.proc = null; 12806 } 12807 app.pubProviders.clear(); 12808 12809 // Take care of any launching providers waiting for this process. 12810 if (checkAppInLaunchingProvidersLocked(app, false)) { 12811 restart = true; 12812 } 12813 12814 // Unregister from connected content providers. 12815 if (!app.conProviders.isEmpty()) { 12816 for (int i=0; i<app.conProviders.size(); i++) { 12817 ContentProviderConnection conn = app.conProviders.get(i); 12818 conn.provider.connections.remove(conn); 12819 } 12820 app.conProviders.clear(); 12821 } 12822 12823 // At this point there may be remaining entries in mLaunchingProviders 12824 // where we were the only one waiting, so they are no longer of use. 12825 // Look for these and clean up if found. 12826 // XXX Commented out for now. Trying to figure out a way to reproduce 12827 // the actual situation to identify what is actually going on. 12828 if (false) { 12829 for (int i=0; i<mLaunchingProviders.size(); i++) { 12830 ContentProviderRecord cpr = (ContentProviderRecord) 12831 mLaunchingProviders.get(i); 12832 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12833 synchronized (cpr) { 12834 cpr.launchingApp = null; 12835 cpr.notifyAll(); 12836 } 12837 } 12838 } 12839 } 12840 12841 skipCurrentReceiverLocked(app); 12842 12843 // Unregister any receivers. 12844 for (int i=app.receivers.size()-1; i>=0; i--) { 12845 removeReceiverLocked(app.receivers.valueAt(i)); 12846 } 12847 app.receivers.clear(); 12848 12849 // If the app is undergoing backup, tell the backup manager about it 12850 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12851 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12852 + mBackupTarget.appInfo + " died during backup"); 12853 try { 12854 IBackupManager bm = IBackupManager.Stub.asInterface( 12855 ServiceManager.getService(Context.BACKUP_SERVICE)); 12856 bm.agentDisconnected(app.info.packageName); 12857 } catch (RemoteException e) { 12858 // can't happen; backup manager is local 12859 } 12860 } 12861 12862 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12863 ProcessChangeItem item = mPendingProcessChanges.get(i); 12864 if (item.pid == app.pid) { 12865 mPendingProcessChanges.remove(i); 12866 mAvailProcessChanges.add(item); 12867 } 12868 } 12869 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12870 12871 // If the caller is restarting this app, then leave it in its 12872 // current lists and let the caller take care of it. 12873 if (restarting) { 12874 return; 12875 } 12876 12877 if (!app.persistent || app.isolated) { 12878 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12879 "Removing non-persistent process during cleanup: " + app); 12880 mProcessNames.remove(app.processName, app.uid); 12881 mIsolatedProcesses.remove(app.uid); 12882 if (mHeavyWeightProcess == app) { 12883 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12884 mHeavyWeightProcess.userId, 0)); 12885 mHeavyWeightProcess = null; 12886 } 12887 } else if (!app.removed) { 12888 // This app is persistent, so we need to keep its record around. 12889 // If it is not already on the pending app list, add it there 12890 // and start a new process for it. 12891 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12892 mPersistentStartingProcesses.add(app); 12893 restart = true; 12894 } 12895 } 12896 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12897 "Clean-up removing on hold: " + app); 12898 mProcessesOnHold.remove(app); 12899 12900 if (app == mHomeProcess) { 12901 mHomeProcess = null; 12902 } 12903 if (app == mPreviousProcess) { 12904 mPreviousProcess = null; 12905 } 12906 12907 if (restart && !app.isolated) { 12908 // We have components that still need to be running in the 12909 // process, so re-launch it. 12910 mProcessNames.put(app.processName, app.uid, app); 12911 startProcessLocked(app, "restart", app.processName); 12912 } else if (app.pid > 0 && app.pid != MY_PID) { 12913 // Goodbye! 12914 boolean removed; 12915 synchronized (mPidsSelfLocked) { 12916 mPidsSelfLocked.remove(app.pid); 12917 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12918 } 12919 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12920 app.processName, app.info.uid); 12921 if (app.isolated) { 12922 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12923 } 12924 app.setPid(0); 12925 } 12926 } 12927 12928 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12929 // Look through the content providers we are waiting to have launched, 12930 // and if any run in this process then either schedule a restart of 12931 // the process or kill the client waiting for it if this process has 12932 // gone bad. 12933 int NL = mLaunchingProviders.size(); 12934 boolean restart = false; 12935 for (int i=0; i<NL; i++) { 12936 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12937 if (cpr.launchingApp == app) { 12938 if (!alwaysBad && !app.bad) { 12939 restart = true; 12940 } else { 12941 removeDyingProviderLocked(app, cpr, true); 12942 // cpr should have been removed from mLaunchingProviders 12943 NL = mLaunchingProviders.size(); 12944 i--; 12945 } 12946 } 12947 } 12948 return restart; 12949 } 12950 12951 // ========================================================= 12952 // SERVICES 12953 // ========================================================= 12954 12955 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12956 int flags) { 12957 enforceNotIsolatedCaller("getServices"); 12958 synchronized (this) { 12959 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12960 } 12961 } 12962 12963 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12964 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12965 synchronized (this) { 12966 return mServices.getRunningServiceControlPanelLocked(name); 12967 } 12968 } 12969 12970 public ComponentName startService(IApplicationThread caller, Intent service, 12971 String resolvedType, int userId) { 12972 enforceNotIsolatedCaller("startService"); 12973 // Refuse possible leaked file descriptors 12974 if (service != null && service.hasFileDescriptors() == true) { 12975 throw new IllegalArgumentException("File descriptors passed in Intent"); 12976 } 12977 12978 if (DEBUG_SERVICE) 12979 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12980 synchronized(this) { 12981 final int callingPid = Binder.getCallingPid(); 12982 final int callingUid = Binder.getCallingUid(); 12983 final long origId = Binder.clearCallingIdentity(); 12984 ComponentName res = mServices.startServiceLocked(caller, service, 12985 resolvedType, callingPid, callingUid, userId); 12986 Binder.restoreCallingIdentity(origId); 12987 return res; 12988 } 12989 } 12990 12991 ComponentName startServiceInPackage(int uid, 12992 Intent service, String resolvedType, int userId) { 12993 synchronized(this) { 12994 if (DEBUG_SERVICE) 12995 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12996 final long origId = Binder.clearCallingIdentity(); 12997 ComponentName res = mServices.startServiceLocked(null, service, 12998 resolvedType, -1, uid, userId); 12999 Binder.restoreCallingIdentity(origId); 13000 return res; 13001 } 13002 } 13003 13004 public int stopService(IApplicationThread caller, Intent service, 13005 String resolvedType, int userId) { 13006 enforceNotIsolatedCaller("stopService"); 13007 // Refuse possible leaked file descriptors 13008 if (service != null && service.hasFileDescriptors() == true) { 13009 throw new IllegalArgumentException("File descriptors passed in Intent"); 13010 } 13011 13012 synchronized(this) { 13013 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13014 } 13015 } 13016 13017 public IBinder peekService(Intent service, String resolvedType) { 13018 enforceNotIsolatedCaller("peekService"); 13019 // Refuse possible leaked file descriptors 13020 if (service != null && service.hasFileDescriptors() == true) { 13021 throw new IllegalArgumentException("File descriptors passed in Intent"); 13022 } 13023 synchronized(this) { 13024 return mServices.peekServiceLocked(service, resolvedType); 13025 } 13026 } 13027 13028 public boolean stopServiceToken(ComponentName className, IBinder token, 13029 int startId) { 13030 synchronized(this) { 13031 return mServices.stopServiceTokenLocked(className, token, startId); 13032 } 13033 } 13034 13035 public void setServiceForeground(ComponentName className, IBinder token, 13036 int id, Notification notification, boolean removeNotification) { 13037 synchronized(this) { 13038 mServices.setServiceForegroundLocked(className, token, id, notification, 13039 removeNotification); 13040 } 13041 } 13042 13043 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13044 boolean requireFull, String name, String callerPackage) { 13045 final int callingUserId = UserHandle.getUserId(callingUid); 13046 if (callingUserId != userId) { 13047 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13048 if ((requireFull || checkComponentPermission( 13049 android.Manifest.permission.INTERACT_ACROSS_USERS, 13050 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13051 && checkComponentPermission( 13052 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13053 callingPid, callingUid, -1, true) 13054 != PackageManager.PERMISSION_GRANTED) { 13055 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13056 // In this case, they would like to just execute as their 13057 // owner user instead of failing. 13058 userId = callingUserId; 13059 } else { 13060 StringBuilder builder = new StringBuilder(128); 13061 builder.append("Permission Denial: "); 13062 builder.append(name); 13063 if (callerPackage != null) { 13064 builder.append(" from "); 13065 builder.append(callerPackage); 13066 } 13067 builder.append(" asks to run as user "); 13068 builder.append(userId); 13069 builder.append(" but is calling from user "); 13070 builder.append(UserHandle.getUserId(callingUid)); 13071 builder.append("; this requires "); 13072 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13073 if (!requireFull) { 13074 builder.append(" or "); 13075 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13076 } 13077 String msg = builder.toString(); 13078 Slog.w(TAG, msg); 13079 throw new SecurityException(msg); 13080 } 13081 } 13082 } 13083 if (userId == UserHandle.USER_CURRENT 13084 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13085 // Note that we may be accessing this outside of a lock... 13086 // shouldn't be a big deal, if this is being called outside 13087 // of a locked context there is intrinsically a race with 13088 // the value the caller will receive and someone else changing it. 13089 userId = mCurrentUserId; 13090 } 13091 if (!allowAll && userId < 0) { 13092 throw new IllegalArgumentException( 13093 "Call does not support special user #" + userId); 13094 } 13095 } 13096 return userId; 13097 } 13098 13099 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13100 String className, int flags) { 13101 boolean result = false; 13102 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13103 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13104 if (ActivityManager.checkUidPermission( 13105 android.Manifest.permission.INTERACT_ACROSS_USERS, 13106 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13107 ComponentName comp = new ComponentName(aInfo.packageName, className); 13108 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13109 + " requests FLAG_SINGLE_USER, but app does not hold " 13110 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13111 Slog.w(TAG, msg); 13112 throw new SecurityException(msg); 13113 } 13114 result = true; 13115 } 13116 } else if (componentProcessName == aInfo.packageName) { 13117 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13118 } else if ("system".equals(componentProcessName)) { 13119 result = true; 13120 } 13121 if (DEBUG_MU) { 13122 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13123 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13124 } 13125 return result; 13126 } 13127 13128 public int bindService(IApplicationThread caller, IBinder token, 13129 Intent service, String resolvedType, 13130 IServiceConnection connection, int flags, int userId) { 13131 enforceNotIsolatedCaller("bindService"); 13132 // Refuse possible leaked file descriptors 13133 if (service != null && service.hasFileDescriptors() == true) { 13134 throw new IllegalArgumentException("File descriptors passed in Intent"); 13135 } 13136 13137 synchronized(this) { 13138 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13139 connection, flags, userId); 13140 } 13141 } 13142 13143 public boolean unbindService(IServiceConnection connection) { 13144 synchronized (this) { 13145 return mServices.unbindServiceLocked(connection); 13146 } 13147 } 13148 13149 public void publishService(IBinder token, Intent intent, IBinder service) { 13150 // Refuse possible leaked file descriptors 13151 if (intent != null && intent.hasFileDescriptors() == true) { 13152 throw new IllegalArgumentException("File descriptors passed in Intent"); 13153 } 13154 13155 synchronized(this) { 13156 if (!(token instanceof ServiceRecord)) { 13157 throw new IllegalArgumentException("Invalid service token"); 13158 } 13159 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13160 } 13161 } 13162 13163 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13164 // Refuse possible leaked file descriptors 13165 if (intent != null && intent.hasFileDescriptors() == true) { 13166 throw new IllegalArgumentException("File descriptors passed in Intent"); 13167 } 13168 13169 synchronized(this) { 13170 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13171 } 13172 } 13173 13174 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13175 synchronized(this) { 13176 if (!(token instanceof ServiceRecord)) { 13177 throw new IllegalArgumentException("Invalid service token"); 13178 } 13179 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13180 } 13181 } 13182 13183 // ========================================================= 13184 // BACKUP AND RESTORE 13185 // ========================================================= 13186 13187 // Cause the target app to be launched if necessary and its backup agent 13188 // instantiated. The backup agent will invoke backupAgentCreated() on the 13189 // activity manager to announce its creation. 13190 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13191 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13192 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13193 13194 synchronized(this) { 13195 // !!! TODO: currently no check here that we're already bound 13196 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13197 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13198 synchronized (stats) { 13199 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13200 } 13201 13202 // Backup agent is now in use, its package can't be stopped. 13203 try { 13204 AppGlobals.getPackageManager().setPackageStoppedState( 13205 app.packageName, false, UserHandle.getUserId(app.uid)); 13206 } catch (RemoteException e) { 13207 } catch (IllegalArgumentException e) { 13208 Slog.w(TAG, "Failed trying to unstop package " 13209 + app.packageName + ": " + e); 13210 } 13211 13212 BackupRecord r = new BackupRecord(ss, app, backupMode); 13213 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13214 ? new ComponentName(app.packageName, app.backupAgentName) 13215 : new ComponentName("android", "FullBackupAgent"); 13216 // startProcessLocked() returns existing proc's record if it's already running 13217 ProcessRecord proc = startProcessLocked(app.processName, app, 13218 false, 0, "backup", hostingName, false, false, false); 13219 if (proc == null) { 13220 Slog.e(TAG, "Unable to start backup agent process " + r); 13221 return false; 13222 } 13223 13224 r.app = proc; 13225 mBackupTarget = r; 13226 mBackupAppName = app.packageName; 13227 13228 // Try not to kill the process during backup 13229 updateOomAdjLocked(proc); 13230 13231 // If the process is already attached, schedule the creation of the backup agent now. 13232 // If it is not yet live, this will be done when it attaches to the framework. 13233 if (proc.thread != null) { 13234 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13235 try { 13236 proc.thread.scheduleCreateBackupAgent(app, 13237 compatibilityInfoForPackageLocked(app), backupMode); 13238 } catch (RemoteException e) { 13239 // Will time out on the backup manager side 13240 } 13241 } else { 13242 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13243 } 13244 // Invariants: at this point, the target app process exists and the application 13245 // is either already running or in the process of coming up. mBackupTarget and 13246 // mBackupAppName describe the app, so that when it binds back to the AM we 13247 // know that it's scheduled for a backup-agent operation. 13248 } 13249 13250 return true; 13251 } 13252 13253 @Override 13254 public void clearPendingBackup() { 13255 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13256 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13257 13258 synchronized (this) { 13259 mBackupTarget = null; 13260 mBackupAppName = null; 13261 } 13262 } 13263 13264 // A backup agent has just come up 13265 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13266 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13267 + " = " + agent); 13268 13269 synchronized(this) { 13270 if (!agentPackageName.equals(mBackupAppName)) { 13271 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13272 return; 13273 } 13274 } 13275 13276 long oldIdent = Binder.clearCallingIdentity(); 13277 try { 13278 IBackupManager bm = IBackupManager.Stub.asInterface( 13279 ServiceManager.getService(Context.BACKUP_SERVICE)); 13280 bm.agentConnected(agentPackageName, agent); 13281 } catch (RemoteException e) { 13282 // can't happen; the backup manager service is local 13283 } catch (Exception e) { 13284 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13285 e.printStackTrace(); 13286 } finally { 13287 Binder.restoreCallingIdentity(oldIdent); 13288 } 13289 } 13290 13291 // done with this agent 13292 public void unbindBackupAgent(ApplicationInfo appInfo) { 13293 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13294 if (appInfo == null) { 13295 Slog.w(TAG, "unbind backup agent for null app"); 13296 return; 13297 } 13298 13299 synchronized(this) { 13300 try { 13301 if (mBackupAppName == null) { 13302 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13303 return; 13304 } 13305 13306 if (!mBackupAppName.equals(appInfo.packageName)) { 13307 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13308 return; 13309 } 13310 13311 // Not backing this app up any more; reset its OOM adjustment 13312 final ProcessRecord proc = mBackupTarget.app; 13313 updateOomAdjLocked(proc); 13314 13315 // If the app crashed during backup, 'thread' will be null here 13316 if (proc.thread != null) { 13317 try { 13318 proc.thread.scheduleDestroyBackupAgent(appInfo, 13319 compatibilityInfoForPackageLocked(appInfo)); 13320 } catch (Exception e) { 13321 Slog.e(TAG, "Exception when unbinding backup agent:"); 13322 e.printStackTrace(); 13323 } 13324 } 13325 } finally { 13326 mBackupTarget = null; 13327 mBackupAppName = null; 13328 } 13329 } 13330 } 13331 // ========================================================= 13332 // BROADCASTS 13333 // ========================================================= 13334 13335 private final List getStickiesLocked(String action, IntentFilter filter, 13336 List cur, int userId) { 13337 final ContentResolver resolver = mContext.getContentResolver(); 13338 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13339 if (stickies == null) { 13340 return cur; 13341 } 13342 final ArrayList<Intent> list = stickies.get(action); 13343 if (list == null) { 13344 return cur; 13345 } 13346 int N = list.size(); 13347 for (int i=0; i<N; i++) { 13348 Intent intent = list.get(i); 13349 if (filter.match(resolver, intent, true, TAG) >= 0) { 13350 if (cur == null) { 13351 cur = new ArrayList<Intent>(); 13352 } 13353 cur.add(intent); 13354 } 13355 } 13356 return cur; 13357 } 13358 13359 boolean isPendingBroadcastProcessLocked(int pid) { 13360 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13361 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13362 } 13363 13364 void skipPendingBroadcastLocked(int pid) { 13365 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13366 for (BroadcastQueue queue : mBroadcastQueues) { 13367 queue.skipPendingBroadcastLocked(pid); 13368 } 13369 } 13370 13371 // The app just attached; send any pending broadcasts that it should receive 13372 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13373 boolean didSomething = false; 13374 for (BroadcastQueue queue : mBroadcastQueues) { 13375 didSomething |= queue.sendPendingBroadcastsLocked(app); 13376 } 13377 return didSomething; 13378 } 13379 13380 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13381 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13382 enforceNotIsolatedCaller("registerReceiver"); 13383 int callingUid; 13384 int callingPid; 13385 synchronized(this) { 13386 ProcessRecord callerApp = null; 13387 if (caller != null) { 13388 callerApp = getRecordForAppLocked(caller); 13389 if (callerApp == null) { 13390 throw new SecurityException( 13391 "Unable to find app for caller " + caller 13392 + " (pid=" + Binder.getCallingPid() 13393 + ") when registering receiver " + receiver); 13394 } 13395 if (callerApp.info.uid != Process.SYSTEM_UID && 13396 !callerApp.pkgList.containsKey(callerPackage) && 13397 !"android".equals(callerPackage)) { 13398 throw new SecurityException("Given caller package " + callerPackage 13399 + " is not running in process " + callerApp); 13400 } 13401 callingUid = callerApp.info.uid; 13402 callingPid = callerApp.pid; 13403 } else { 13404 callerPackage = null; 13405 callingUid = Binder.getCallingUid(); 13406 callingPid = Binder.getCallingPid(); 13407 } 13408 13409 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13410 true, true, "registerReceiver", callerPackage); 13411 13412 List allSticky = null; 13413 13414 // Look for any matching sticky broadcasts... 13415 Iterator actions = filter.actionsIterator(); 13416 if (actions != null) { 13417 while (actions.hasNext()) { 13418 String action = (String)actions.next(); 13419 allSticky = getStickiesLocked(action, filter, allSticky, 13420 UserHandle.USER_ALL); 13421 allSticky = getStickiesLocked(action, filter, allSticky, 13422 UserHandle.getUserId(callingUid)); 13423 } 13424 } else { 13425 allSticky = getStickiesLocked(null, filter, allSticky, 13426 UserHandle.USER_ALL); 13427 allSticky = getStickiesLocked(null, filter, allSticky, 13428 UserHandle.getUserId(callingUid)); 13429 } 13430 13431 // The first sticky in the list is returned directly back to 13432 // the client. 13433 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13434 13435 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13436 + ": " + sticky); 13437 13438 if (receiver == null) { 13439 return sticky; 13440 } 13441 13442 ReceiverList rl 13443 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13444 if (rl == null) { 13445 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13446 userId, receiver); 13447 if (rl.app != null) { 13448 rl.app.receivers.add(rl); 13449 } else { 13450 try { 13451 receiver.asBinder().linkToDeath(rl, 0); 13452 } catch (RemoteException e) { 13453 return sticky; 13454 } 13455 rl.linkedToDeath = true; 13456 } 13457 mRegisteredReceivers.put(receiver.asBinder(), rl); 13458 } else if (rl.uid != callingUid) { 13459 throw new IllegalArgumentException( 13460 "Receiver requested to register for uid " + callingUid 13461 + " was previously registered for uid " + rl.uid); 13462 } else if (rl.pid != callingPid) { 13463 throw new IllegalArgumentException( 13464 "Receiver requested to register for pid " + callingPid 13465 + " was previously registered for pid " + rl.pid); 13466 } else if (rl.userId != userId) { 13467 throw new IllegalArgumentException( 13468 "Receiver requested to register for user " + userId 13469 + " was previously registered for user " + rl.userId); 13470 } 13471 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13472 permission, callingUid, userId); 13473 rl.add(bf); 13474 if (!bf.debugCheck()) { 13475 Slog.w(TAG, "==> For Dynamic broadast"); 13476 } 13477 mReceiverResolver.addFilter(bf); 13478 13479 // Enqueue broadcasts for all existing stickies that match 13480 // this filter. 13481 if (allSticky != null) { 13482 ArrayList receivers = new ArrayList(); 13483 receivers.add(bf); 13484 13485 int N = allSticky.size(); 13486 for (int i=0; i<N; i++) { 13487 Intent intent = (Intent)allSticky.get(i); 13488 BroadcastQueue queue = broadcastQueueForIntent(intent); 13489 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13490 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13491 null, null, false, true, true, -1); 13492 queue.enqueueParallelBroadcastLocked(r); 13493 queue.scheduleBroadcastsLocked(); 13494 } 13495 } 13496 13497 return sticky; 13498 } 13499 } 13500 13501 public void unregisterReceiver(IIntentReceiver receiver) { 13502 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13503 13504 final long origId = Binder.clearCallingIdentity(); 13505 try { 13506 boolean doTrim = false; 13507 13508 synchronized(this) { 13509 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13510 if (rl != null) { 13511 if (rl.curBroadcast != null) { 13512 BroadcastRecord r = rl.curBroadcast; 13513 final boolean doNext = finishReceiverLocked( 13514 receiver.asBinder(), r.resultCode, r.resultData, 13515 r.resultExtras, r.resultAbort); 13516 if (doNext) { 13517 doTrim = true; 13518 r.queue.processNextBroadcast(false); 13519 } 13520 } 13521 13522 if (rl.app != null) { 13523 rl.app.receivers.remove(rl); 13524 } 13525 removeReceiverLocked(rl); 13526 if (rl.linkedToDeath) { 13527 rl.linkedToDeath = false; 13528 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13529 } 13530 } 13531 } 13532 13533 // If we actually concluded any broadcasts, we might now be able 13534 // to trim the recipients' apps from our working set 13535 if (doTrim) { 13536 trimApplications(); 13537 return; 13538 } 13539 13540 } finally { 13541 Binder.restoreCallingIdentity(origId); 13542 } 13543 } 13544 13545 void removeReceiverLocked(ReceiverList rl) { 13546 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13547 int N = rl.size(); 13548 for (int i=0; i<N; i++) { 13549 mReceiverResolver.removeFilter(rl.get(i)); 13550 } 13551 } 13552 13553 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13554 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13555 ProcessRecord r = mLruProcesses.get(i); 13556 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13557 try { 13558 r.thread.dispatchPackageBroadcast(cmd, packages); 13559 } catch (RemoteException ex) { 13560 } 13561 } 13562 } 13563 } 13564 13565 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13566 int[] users) { 13567 List<ResolveInfo> receivers = null; 13568 try { 13569 HashSet<ComponentName> singleUserReceivers = null; 13570 boolean scannedFirstReceivers = false; 13571 for (int user : users) { 13572 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13573 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13574 if (user != 0 && newReceivers != null) { 13575 // If this is not the primary user, we need to check for 13576 // any receivers that should be filtered out. 13577 for (int i=0; i<newReceivers.size(); i++) { 13578 ResolveInfo ri = newReceivers.get(i); 13579 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13580 newReceivers.remove(i); 13581 i--; 13582 } 13583 } 13584 } 13585 if (newReceivers != null && newReceivers.size() == 0) { 13586 newReceivers = null; 13587 } 13588 if (receivers == null) { 13589 receivers = newReceivers; 13590 } else if (newReceivers != null) { 13591 // We need to concatenate the additional receivers 13592 // found with what we have do far. This would be easy, 13593 // but we also need to de-dup any receivers that are 13594 // singleUser. 13595 if (!scannedFirstReceivers) { 13596 // Collect any single user receivers we had already retrieved. 13597 scannedFirstReceivers = true; 13598 for (int i=0; i<receivers.size(); i++) { 13599 ResolveInfo ri = receivers.get(i); 13600 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13601 ComponentName cn = new ComponentName( 13602 ri.activityInfo.packageName, ri.activityInfo.name); 13603 if (singleUserReceivers == null) { 13604 singleUserReceivers = new HashSet<ComponentName>(); 13605 } 13606 singleUserReceivers.add(cn); 13607 } 13608 } 13609 } 13610 // Add the new results to the existing results, tracking 13611 // and de-dupping single user receivers. 13612 for (int i=0; i<newReceivers.size(); i++) { 13613 ResolveInfo ri = newReceivers.get(i); 13614 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13615 ComponentName cn = new ComponentName( 13616 ri.activityInfo.packageName, ri.activityInfo.name); 13617 if (singleUserReceivers == null) { 13618 singleUserReceivers = new HashSet<ComponentName>(); 13619 } 13620 if (!singleUserReceivers.contains(cn)) { 13621 singleUserReceivers.add(cn); 13622 receivers.add(ri); 13623 } 13624 } else { 13625 receivers.add(ri); 13626 } 13627 } 13628 } 13629 } 13630 } catch (RemoteException ex) { 13631 // pm is in same process, this will never happen. 13632 } 13633 return receivers; 13634 } 13635 13636 private final int broadcastIntentLocked(ProcessRecord callerApp, 13637 String callerPackage, Intent intent, String resolvedType, 13638 IIntentReceiver resultTo, int resultCode, String resultData, 13639 Bundle map, String requiredPermission, int appOp, 13640 boolean ordered, boolean sticky, int callingPid, int callingUid, 13641 int userId) { 13642 intent = new Intent(intent); 13643 13644 // By default broadcasts do not go to stopped apps. 13645 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13646 13647 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13648 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13649 + " ordered=" + ordered + " userid=" + userId); 13650 if ((resultTo != null) && !ordered) { 13651 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13652 } 13653 13654 userId = handleIncomingUser(callingPid, callingUid, userId, 13655 true, false, "broadcast", callerPackage); 13656 13657 // Make sure that the user who is receiving this broadcast is started. 13658 // If not, we will just skip it. 13659 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13660 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13661 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13662 Slog.w(TAG, "Skipping broadcast of " + intent 13663 + ": user " + userId + " is stopped"); 13664 return ActivityManager.BROADCAST_SUCCESS; 13665 } 13666 } 13667 13668 /* 13669 * Prevent non-system code (defined here to be non-persistent 13670 * processes) from sending protected broadcasts. 13671 */ 13672 int callingAppId = UserHandle.getAppId(callingUid); 13673 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13674 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13675 callingUid == 0) { 13676 // Always okay. 13677 } else if (callerApp == null || !callerApp.persistent) { 13678 try { 13679 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13680 intent.getAction())) { 13681 String msg = "Permission Denial: not allowed to send broadcast " 13682 + intent.getAction() + " from pid=" 13683 + callingPid + ", uid=" + callingUid; 13684 Slog.w(TAG, msg); 13685 throw new SecurityException(msg); 13686 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13687 // Special case for compatibility: we don't want apps to send this, 13688 // but historically it has not been protected and apps may be using it 13689 // to poke their own app widget. So, instead of making it protected, 13690 // just limit it to the caller. 13691 if (callerApp == null) { 13692 String msg = "Permission Denial: not allowed to send broadcast " 13693 + intent.getAction() + " from unknown caller."; 13694 Slog.w(TAG, msg); 13695 throw new SecurityException(msg); 13696 } else if (intent.getComponent() != null) { 13697 // They are good enough to send to an explicit component... verify 13698 // it is being sent to the calling app. 13699 if (!intent.getComponent().getPackageName().equals( 13700 callerApp.info.packageName)) { 13701 String msg = "Permission Denial: not allowed to send broadcast " 13702 + intent.getAction() + " to " 13703 + intent.getComponent().getPackageName() + " from " 13704 + callerApp.info.packageName; 13705 Slog.w(TAG, msg); 13706 throw new SecurityException(msg); 13707 } 13708 } else { 13709 // Limit broadcast to their own package. 13710 intent.setPackage(callerApp.info.packageName); 13711 } 13712 } 13713 } catch (RemoteException e) { 13714 Slog.w(TAG, "Remote exception", e); 13715 return ActivityManager.BROADCAST_SUCCESS; 13716 } 13717 } 13718 13719 // Handle special intents: if this broadcast is from the package 13720 // manager about a package being removed, we need to remove all of 13721 // its activities from the history stack. 13722 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13723 intent.getAction()); 13724 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13725 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13726 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13727 || uidRemoved) { 13728 if (checkComponentPermission( 13729 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13730 callingPid, callingUid, -1, true) 13731 == PackageManager.PERMISSION_GRANTED) { 13732 if (uidRemoved) { 13733 final Bundle intentExtras = intent.getExtras(); 13734 final int uid = intentExtras != null 13735 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13736 if (uid >= 0) { 13737 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13738 synchronized (bs) { 13739 bs.removeUidStatsLocked(uid); 13740 } 13741 mAppOpsService.uidRemoved(uid); 13742 } 13743 } else { 13744 // If resources are unavailable just force stop all 13745 // those packages and flush the attribute cache as well. 13746 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13747 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13748 if (list != null && (list.length > 0)) { 13749 for (String pkg : list) { 13750 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13751 "storage unmount"); 13752 } 13753 sendPackageBroadcastLocked( 13754 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13755 } 13756 } else { 13757 Uri data = intent.getData(); 13758 String ssp; 13759 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13760 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13761 intent.getAction()); 13762 boolean fullUninstall = removed && 13763 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13764 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13765 forceStopPackageLocked(ssp, UserHandle.getAppId( 13766 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13767 false, fullUninstall, userId, 13768 removed ? "pkg removed" : "pkg changed"); 13769 } 13770 if (removed) { 13771 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13772 new String[] {ssp}, userId); 13773 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13774 mAppOpsService.packageRemoved( 13775 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13776 13777 // Remove all permissions granted from/to this package 13778 removeUriPermissionsForPackageLocked(ssp, userId, true); 13779 } 13780 } 13781 } 13782 } 13783 } 13784 } else { 13785 String msg = "Permission Denial: " + intent.getAction() 13786 + " broadcast from " + callerPackage + " (pid=" + callingPid 13787 + ", uid=" + callingUid + ")" 13788 + " requires " 13789 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13790 Slog.w(TAG, msg); 13791 throw new SecurityException(msg); 13792 } 13793 13794 // Special case for adding a package: by default turn on compatibility 13795 // mode. 13796 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13797 Uri data = intent.getData(); 13798 String ssp; 13799 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13800 mCompatModePackages.handlePackageAddedLocked(ssp, 13801 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13802 } 13803 } 13804 13805 /* 13806 * If this is the time zone changed action, queue up a message that will reset the timezone 13807 * of all currently running processes. This message will get queued up before the broadcast 13808 * happens. 13809 */ 13810 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13811 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13812 } 13813 13814 /* 13815 * If the user set the time, let all running processes know. 13816 */ 13817 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13818 final int is24Hour = intent.getBooleanExtra( 13819 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13820 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13821 } 13822 13823 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13824 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13825 } 13826 13827 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13828 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13829 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13830 } 13831 13832 // Add to the sticky list if requested. 13833 if (sticky) { 13834 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13835 callingPid, callingUid) 13836 != PackageManager.PERMISSION_GRANTED) { 13837 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13838 + callingPid + ", uid=" + callingUid 13839 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13840 Slog.w(TAG, msg); 13841 throw new SecurityException(msg); 13842 } 13843 if (requiredPermission != null) { 13844 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13845 + " and enforce permission " + requiredPermission); 13846 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13847 } 13848 if (intent.getComponent() != null) { 13849 throw new SecurityException( 13850 "Sticky broadcasts can't target a specific component"); 13851 } 13852 // We use userId directly here, since the "all" target is maintained 13853 // as a separate set of sticky broadcasts. 13854 if (userId != UserHandle.USER_ALL) { 13855 // But first, if this is not a broadcast to all users, then 13856 // make sure it doesn't conflict with an existing broadcast to 13857 // all users. 13858 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13859 UserHandle.USER_ALL); 13860 if (stickies != null) { 13861 ArrayList<Intent> list = stickies.get(intent.getAction()); 13862 if (list != null) { 13863 int N = list.size(); 13864 int i; 13865 for (i=0; i<N; i++) { 13866 if (intent.filterEquals(list.get(i))) { 13867 throw new IllegalArgumentException( 13868 "Sticky broadcast " + intent + " for user " 13869 + userId + " conflicts with existing global broadcast"); 13870 } 13871 } 13872 } 13873 } 13874 } 13875 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13876 if (stickies == null) { 13877 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13878 mStickyBroadcasts.put(userId, stickies); 13879 } 13880 ArrayList<Intent> list = stickies.get(intent.getAction()); 13881 if (list == null) { 13882 list = new ArrayList<Intent>(); 13883 stickies.put(intent.getAction(), list); 13884 } 13885 int N = list.size(); 13886 int i; 13887 for (i=0; i<N; i++) { 13888 if (intent.filterEquals(list.get(i))) { 13889 // This sticky already exists, replace it. 13890 list.set(i, new Intent(intent)); 13891 break; 13892 } 13893 } 13894 if (i >= N) { 13895 list.add(new Intent(intent)); 13896 } 13897 } 13898 13899 int[] users; 13900 if (userId == UserHandle.USER_ALL) { 13901 // Caller wants broadcast to go to all started users. 13902 users = mStartedUserArray; 13903 } else { 13904 // Caller wants broadcast to go to one specific user. 13905 users = new int[] {userId}; 13906 } 13907 13908 // Figure out who all will receive this broadcast. 13909 List receivers = null; 13910 List<BroadcastFilter> registeredReceivers = null; 13911 // Need to resolve the intent to interested receivers... 13912 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13913 == 0) { 13914 receivers = collectReceiverComponents(intent, resolvedType, users); 13915 } 13916 if (intent.getComponent() == null) { 13917 registeredReceivers = mReceiverResolver.queryIntent(intent, 13918 resolvedType, false, userId); 13919 } 13920 13921 final boolean replacePending = 13922 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13923 13924 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13925 + " replacePending=" + replacePending); 13926 13927 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13928 if (!ordered && NR > 0) { 13929 // If we are not serializing this broadcast, then send the 13930 // registered receivers separately so they don't wait for the 13931 // components to be launched. 13932 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13933 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13934 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13935 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13936 ordered, sticky, false, userId); 13937 if (DEBUG_BROADCAST) Slog.v( 13938 TAG, "Enqueueing parallel broadcast " + r); 13939 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13940 if (!replaced) { 13941 queue.enqueueParallelBroadcastLocked(r); 13942 queue.scheduleBroadcastsLocked(); 13943 } 13944 registeredReceivers = null; 13945 NR = 0; 13946 } 13947 13948 // Merge into one list. 13949 int ir = 0; 13950 if (receivers != null) { 13951 // A special case for PACKAGE_ADDED: do not allow the package 13952 // being added to see this broadcast. This prevents them from 13953 // using this as a back door to get run as soon as they are 13954 // installed. Maybe in the future we want to have a special install 13955 // broadcast or such for apps, but we'd like to deliberately make 13956 // this decision. 13957 String skipPackages[] = null; 13958 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13959 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13960 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13961 Uri data = intent.getData(); 13962 if (data != null) { 13963 String pkgName = data.getSchemeSpecificPart(); 13964 if (pkgName != null) { 13965 skipPackages = new String[] { pkgName }; 13966 } 13967 } 13968 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13969 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13970 } 13971 if (skipPackages != null && (skipPackages.length > 0)) { 13972 for (String skipPackage : skipPackages) { 13973 if (skipPackage != null) { 13974 int NT = receivers.size(); 13975 for (int it=0; it<NT; it++) { 13976 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13977 if (curt.activityInfo.packageName.equals(skipPackage)) { 13978 receivers.remove(it); 13979 it--; 13980 NT--; 13981 } 13982 } 13983 } 13984 } 13985 } 13986 13987 int NT = receivers != null ? receivers.size() : 0; 13988 int it = 0; 13989 ResolveInfo curt = null; 13990 BroadcastFilter curr = null; 13991 while (it < NT && ir < NR) { 13992 if (curt == null) { 13993 curt = (ResolveInfo)receivers.get(it); 13994 } 13995 if (curr == null) { 13996 curr = registeredReceivers.get(ir); 13997 } 13998 if (curr.getPriority() >= curt.priority) { 13999 // Insert this broadcast record into the final list. 14000 receivers.add(it, curr); 14001 ir++; 14002 curr = null; 14003 it++; 14004 NT++; 14005 } else { 14006 // Skip to the next ResolveInfo in the final list. 14007 it++; 14008 curt = null; 14009 } 14010 } 14011 } 14012 while (ir < NR) { 14013 if (receivers == null) { 14014 receivers = new ArrayList(); 14015 } 14016 receivers.add(registeredReceivers.get(ir)); 14017 ir++; 14018 } 14019 14020 if ((receivers != null && receivers.size() > 0) 14021 || resultTo != null) { 14022 BroadcastQueue queue = broadcastQueueForIntent(intent); 14023 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14024 callerPackage, callingPid, callingUid, resolvedType, 14025 requiredPermission, appOp, receivers, resultTo, resultCode, 14026 resultData, map, ordered, sticky, false, userId); 14027 if (DEBUG_BROADCAST) Slog.v( 14028 TAG, "Enqueueing ordered broadcast " + r 14029 + ": prev had " + queue.mOrderedBroadcasts.size()); 14030 if (DEBUG_BROADCAST) { 14031 int seq = r.intent.getIntExtra("seq", -1); 14032 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14033 } 14034 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14035 if (!replaced) { 14036 queue.enqueueOrderedBroadcastLocked(r); 14037 queue.scheduleBroadcastsLocked(); 14038 } 14039 } 14040 14041 return ActivityManager.BROADCAST_SUCCESS; 14042 } 14043 14044 final Intent verifyBroadcastLocked(Intent intent) { 14045 // Refuse possible leaked file descriptors 14046 if (intent != null && intent.hasFileDescriptors() == true) { 14047 throw new IllegalArgumentException("File descriptors passed in Intent"); 14048 } 14049 14050 int flags = intent.getFlags(); 14051 14052 if (!mProcessesReady) { 14053 // if the caller really truly claims to know what they're doing, go 14054 // ahead and allow the broadcast without launching any receivers 14055 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14056 intent = new Intent(intent); 14057 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14058 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14059 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14060 + " before boot completion"); 14061 throw new IllegalStateException("Cannot broadcast before boot completed"); 14062 } 14063 } 14064 14065 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14066 throw new IllegalArgumentException( 14067 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14068 } 14069 14070 return intent; 14071 } 14072 14073 public final int broadcastIntent(IApplicationThread caller, 14074 Intent intent, String resolvedType, IIntentReceiver resultTo, 14075 int resultCode, String resultData, Bundle map, 14076 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14077 enforceNotIsolatedCaller("broadcastIntent"); 14078 synchronized(this) { 14079 intent = verifyBroadcastLocked(intent); 14080 14081 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14082 final int callingPid = Binder.getCallingPid(); 14083 final int callingUid = Binder.getCallingUid(); 14084 final long origId = Binder.clearCallingIdentity(); 14085 int res = broadcastIntentLocked(callerApp, 14086 callerApp != null ? callerApp.info.packageName : null, 14087 intent, resolvedType, resultTo, 14088 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14089 callingPid, callingUid, userId); 14090 Binder.restoreCallingIdentity(origId); 14091 return res; 14092 } 14093 } 14094 14095 int broadcastIntentInPackage(String packageName, int uid, 14096 Intent intent, String resolvedType, IIntentReceiver resultTo, 14097 int resultCode, String resultData, Bundle map, 14098 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14099 synchronized(this) { 14100 intent = verifyBroadcastLocked(intent); 14101 14102 final long origId = Binder.clearCallingIdentity(); 14103 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14104 resultTo, resultCode, resultData, map, requiredPermission, 14105 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14106 Binder.restoreCallingIdentity(origId); 14107 return res; 14108 } 14109 } 14110 14111 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14112 // Refuse possible leaked file descriptors 14113 if (intent != null && intent.hasFileDescriptors() == true) { 14114 throw new IllegalArgumentException("File descriptors passed in Intent"); 14115 } 14116 14117 userId = handleIncomingUser(Binder.getCallingPid(), 14118 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14119 14120 synchronized(this) { 14121 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14122 != PackageManager.PERMISSION_GRANTED) { 14123 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14124 + Binder.getCallingPid() 14125 + ", uid=" + Binder.getCallingUid() 14126 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14127 Slog.w(TAG, msg); 14128 throw new SecurityException(msg); 14129 } 14130 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14131 if (stickies != null) { 14132 ArrayList<Intent> list = stickies.get(intent.getAction()); 14133 if (list != null) { 14134 int N = list.size(); 14135 int i; 14136 for (i=0; i<N; i++) { 14137 if (intent.filterEquals(list.get(i))) { 14138 list.remove(i); 14139 break; 14140 } 14141 } 14142 if (list.size() <= 0) { 14143 stickies.remove(intent.getAction()); 14144 } 14145 } 14146 if (stickies.size() <= 0) { 14147 mStickyBroadcasts.remove(userId); 14148 } 14149 } 14150 } 14151 } 14152 14153 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14154 String resultData, Bundle resultExtras, boolean resultAbort) { 14155 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14156 if (r == null) { 14157 Slog.w(TAG, "finishReceiver called but not found on queue"); 14158 return false; 14159 } 14160 14161 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14162 } 14163 14164 void backgroundServicesFinishedLocked(int userId) { 14165 for (BroadcastQueue queue : mBroadcastQueues) { 14166 queue.backgroundServicesFinishedLocked(userId); 14167 } 14168 } 14169 14170 public void finishReceiver(IBinder who, int resultCode, String resultData, 14171 Bundle resultExtras, boolean resultAbort) { 14172 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14173 14174 // Refuse possible leaked file descriptors 14175 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14176 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14177 } 14178 14179 final long origId = Binder.clearCallingIdentity(); 14180 try { 14181 boolean doNext = false; 14182 BroadcastRecord r; 14183 14184 synchronized(this) { 14185 r = broadcastRecordForReceiverLocked(who); 14186 if (r != null) { 14187 doNext = r.queue.finishReceiverLocked(r, resultCode, 14188 resultData, resultExtras, resultAbort, true); 14189 } 14190 } 14191 14192 if (doNext) { 14193 r.queue.processNextBroadcast(false); 14194 } 14195 trimApplications(); 14196 } finally { 14197 Binder.restoreCallingIdentity(origId); 14198 } 14199 } 14200 14201 // ========================================================= 14202 // INSTRUMENTATION 14203 // ========================================================= 14204 14205 public boolean startInstrumentation(ComponentName className, 14206 String profileFile, int flags, Bundle arguments, 14207 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14208 int userId) { 14209 enforceNotIsolatedCaller("startInstrumentation"); 14210 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14211 userId, false, true, "startInstrumentation", null); 14212 // Refuse possible leaked file descriptors 14213 if (arguments != null && arguments.hasFileDescriptors()) { 14214 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14215 } 14216 14217 synchronized(this) { 14218 InstrumentationInfo ii = null; 14219 ApplicationInfo ai = null; 14220 try { 14221 ii = mContext.getPackageManager().getInstrumentationInfo( 14222 className, STOCK_PM_FLAGS); 14223 ai = AppGlobals.getPackageManager().getApplicationInfo( 14224 ii.targetPackage, STOCK_PM_FLAGS, userId); 14225 } catch (PackageManager.NameNotFoundException e) { 14226 } catch (RemoteException e) { 14227 } 14228 if (ii == null) { 14229 reportStartInstrumentationFailure(watcher, className, 14230 "Unable to find instrumentation info for: " + className); 14231 return false; 14232 } 14233 if (ai == null) { 14234 reportStartInstrumentationFailure(watcher, className, 14235 "Unable to find instrumentation target package: " + ii.targetPackage); 14236 return false; 14237 } 14238 14239 int match = mContext.getPackageManager().checkSignatures( 14240 ii.targetPackage, ii.packageName); 14241 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14242 String msg = "Permission Denial: starting instrumentation " 14243 + className + " from pid=" 14244 + Binder.getCallingPid() 14245 + ", uid=" + Binder.getCallingPid() 14246 + " not allowed because package " + ii.packageName 14247 + " does not have a signature matching the target " 14248 + ii.targetPackage; 14249 reportStartInstrumentationFailure(watcher, className, msg); 14250 throw new SecurityException(msg); 14251 } 14252 14253 final long origId = Binder.clearCallingIdentity(); 14254 // Instrumentation can kill and relaunch even persistent processes 14255 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14256 "start instr"); 14257 ProcessRecord app = addAppLocked(ai, false); 14258 app.instrumentationClass = className; 14259 app.instrumentationInfo = ai; 14260 app.instrumentationProfileFile = profileFile; 14261 app.instrumentationArguments = arguments; 14262 app.instrumentationWatcher = watcher; 14263 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14264 app.instrumentationResultClass = className; 14265 Binder.restoreCallingIdentity(origId); 14266 } 14267 14268 return true; 14269 } 14270 14271 /** 14272 * Report errors that occur while attempting to start Instrumentation. Always writes the 14273 * error to the logs, but if somebody is watching, send the report there too. This enables 14274 * the "am" command to report errors with more information. 14275 * 14276 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14277 * @param cn The component name of the instrumentation. 14278 * @param report The error report. 14279 */ 14280 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14281 ComponentName cn, String report) { 14282 Slog.w(TAG, report); 14283 try { 14284 if (watcher != null) { 14285 Bundle results = new Bundle(); 14286 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14287 results.putString("Error", report); 14288 watcher.instrumentationStatus(cn, -1, results); 14289 } 14290 } catch (RemoteException e) { 14291 Slog.w(TAG, e); 14292 } 14293 } 14294 14295 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14296 if (app.instrumentationWatcher != null) { 14297 try { 14298 // NOTE: IInstrumentationWatcher *must* be oneway here 14299 app.instrumentationWatcher.instrumentationFinished( 14300 app.instrumentationClass, 14301 resultCode, 14302 results); 14303 } catch (RemoteException e) { 14304 } 14305 } 14306 if (app.instrumentationUiAutomationConnection != null) { 14307 try { 14308 app.instrumentationUiAutomationConnection.shutdown(); 14309 } catch (RemoteException re) { 14310 /* ignore */ 14311 } 14312 // Only a UiAutomation can set this flag and now that 14313 // it is finished we make sure it is reset to its default. 14314 mUserIsMonkey = false; 14315 } 14316 app.instrumentationWatcher = null; 14317 app.instrumentationUiAutomationConnection = null; 14318 app.instrumentationClass = null; 14319 app.instrumentationInfo = null; 14320 app.instrumentationProfileFile = null; 14321 app.instrumentationArguments = null; 14322 14323 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14324 "finished inst"); 14325 } 14326 14327 public void finishInstrumentation(IApplicationThread target, 14328 int resultCode, Bundle results) { 14329 int userId = UserHandle.getCallingUserId(); 14330 // Refuse possible leaked file descriptors 14331 if (results != null && results.hasFileDescriptors()) { 14332 throw new IllegalArgumentException("File descriptors passed in Intent"); 14333 } 14334 14335 synchronized(this) { 14336 ProcessRecord app = getRecordForAppLocked(target); 14337 if (app == null) { 14338 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14339 return; 14340 } 14341 final long origId = Binder.clearCallingIdentity(); 14342 finishInstrumentationLocked(app, resultCode, results); 14343 Binder.restoreCallingIdentity(origId); 14344 } 14345 } 14346 14347 // ========================================================= 14348 // CONFIGURATION 14349 // ========================================================= 14350 14351 public ConfigurationInfo getDeviceConfigurationInfo() { 14352 ConfigurationInfo config = new ConfigurationInfo(); 14353 synchronized (this) { 14354 config.reqTouchScreen = mConfiguration.touchscreen; 14355 config.reqKeyboardType = mConfiguration.keyboard; 14356 config.reqNavigation = mConfiguration.navigation; 14357 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14358 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14359 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14360 } 14361 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14362 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14363 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14364 } 14365 config.reqGlEsVersion = GL_ES_VERSION; 14366 } 14367 return config; 14368 } 14369 14370 ActivityStack getFocusedStack() { 14371 return mStackSupervisor.getFocusedStack(); 14372 } 14373 14374 public Configuration getConfiguration() { 14375 Configuration ci; 14376 synchronized(this) { 14377 ci = new Configuration(mConfiguration); 14378 } 14379 return ci; 14380 } 14381 14382 public void updatePersistentConfiguration(Configuration values) { 14383 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14384 "updateConfiguration()"); 14385 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14386 "updateConfiguration()"); 14387 if (values == null) { 14388 throw new NullPointerException("Configuration must not be null"); 14389 } 14390 14391 synchronized(this) { 14392 final long origId = Binder.clearCallingIdentity(); 14393 updateConfigurationLocked(values, null, true, false); 14394 Binder.restoreCallingIdentity(origId); 14395 } 14396 } 14397 14398 public void updateConfiguration(Configuration values) { 14399 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14400 "updateConfiguration()"); 14401 14402 synchronized(this) { 14403 if (values == null && mWindowManager != null) { 14404 // sentinel: fetch the current configuration from the window manager 14405 values = mWindowManager.computeNewConfiguration(); 14406 } 14407 14408 if (mWindowManager != null) { 14409 mProcessList.applyDisplaySize(mWindowManager); 14410 } 14411 14412 final long origId = Binder.clearCallingIdentity(); 14413 if (values != null) { 14414 Settings.System.clearConfiguration(values); 14415 } 14416 updateConfigurationLocked(values, null, false, false); 14417 Binder.restoreCallingIdentity(origId); 14418 } 14419 } 14420 14421 /** 14422 * Do either or both things: (1) change the current configuration, and (2) 14423 * make sure the given activity is running with the (now) current 14424 * configuration. Returns true if the activity has been left running, or 14425 * false if <var>starting</var> is being destroyed to match the new 14426 * configuration. 14427 * @param persistent TODO 14428 */ 14429 boolean updateConfigurationLocked(Configuration values, 14430 ActivityRecord starting, boolean persistent, boolean initLocale) { 14431 int changes = 0; 14432 14433 if (values != null) { 14434 Configuration newConfig = new Configuration(mConfiguration); 14435 changes = newConfig.updateFrom(values); 14436 if (changes != 0) { 14437 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14438 Slog.i(TAG, "Updating configuration to: " + values); 14439 } 14440 14441 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14442 14443 if (values.locale != null && !initLocale) { 14444 saveLocaleLocked(values.locale, 14445 !values.locale.equals(mConfiguration.locale), 14446 values.userSetLocale); 14447 } 14448 14449 mConfigurationSeq++; 14450 if (mConfigurationSeq <= 0) { 14451 mConfigurationSeq = 1; 14452 } 14453 newConfig.seq = mConfigurationSeq; 14454 mConfiguration = newConfig; 14455 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14456 mUsageStatsService.noteStartConfig(newConfig); 14457 14458 final Configuration configCopy = new Configuration(mConfiguration); 14459 14460 // TODO: If our config changes, should we auto dismiss any currently 14461 // showing dialogs? 14462 mShowDialogs = shouldShowDialogs(newConfig); 14463 14464 AttributeCache ac = AttributeCache.instance(); 14465 if (ac != null) { 14466 ac.updateConfiguration(configCopy); 14467 } 14468 14469 // Make sure all resources in our process are updated 14470 // right now, so that anyone who is going to retrieve 14471 // resource values after we return will be sure to get 14472 // the new ones. This is especially important during 14473 // boot, where the first config change needs to guarantee 14474 // all resources have that config before following boot 14475 // code is executed. 14476 mSystemThread.applyConfigurationToResources(configCopy); 14477 14478 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14479 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14480 msg.obj = new Configuration(configCopy); 14481 mHandler.sendMessage(msg); 14482 } 14483 14484 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14485 ProcessRecord app = mLruProcesses.get(i); 14486 try { 14487 if (app.thread != null) { 14488 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14489 + app.processName + " new config " + mConfiguration); 14490 app.thread.scheduleConfigurationChanged(configCopy); 14491 } 14492 } catch (Exception e) { 14493 } 14494 } 14495 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14496 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14497 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14498 | Intent.FLAG_RECEIVER_FOREGROUND); 14499 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14500 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14501 Process.SYSTEM_UID, UserHandle.USER_ALL); 14502 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14503 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14504 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14505 broadcastIntentLocked(null, null, intent, 14506 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14507 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14508 } 14509 } 14510 } 14511 14512 boolean kept = true; 14513 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14514 // mainStack is null during startup. 14515 if (mainStack != null) { 14516 if (changes != 0 && starting == null) { 14517 // If the configuration changed, and the caller is not already 14518 // in the process of starting an activity, then find the top 14519 // activity to check if its configuration needs to change. 14520 starting = mainStack.topRunningActivityLocked(null); 14521 } 14522 14523 if (starting != null) { 14524 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14525 // And we need to make sure at this point that all other activities 14526 // are made visible with the correct configuration. 14527 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14528 } 14529 } 14530 14531 if (values != null && mWindowManager != null) { 14532 mWindowManager.setNewConfiguration(mConfiguration); 14533 } 14534 14535 return kept; 14536 } 14537 14538 /** 14539 * Decide based on the configuration whether we should shouw the ANR, 14540 * crash, etc dialogs. The idea is that if there is no affordnace to 14541 * press the on-screen buttons, we shouldn't show the dialog. 14542 * 14543 * A thought: SystemUI might also want to get told about this, the Power 14544 * dialog / global actions also might want different behaviors. 14545 */ 14546 private static final boolean shouldShowDialogs(Configuration config) { 14547 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14548 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14549 } 14550 14551 /** 14552 * Save the locale. You must be inside a synchronized (this) block. 14553 */ 14554 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14555 if(isDiff) { 14556 SystemProperties.set("user.language", l.getLanguage()); 14557 SystemProperties.set("user.region", l.getCountry()); 14558 } 14559 14560 if(isPersist) { 14561 SystemProperties.set("persist.sys.language", l.getLanguage()); 14562 SystemProperties.set("persist.sys.country", l.getCountry()); 14563 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14564 } 14565 } 14566 14567 @Override 14568 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14569 ActivityRecord srec = ActivityRecord.forToken(token); 14570 return srec != null && srec.task.affinity != null && 14571 srec.task.affinity.equals(destAffinity); 14572 } 14573 14574 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14575 Intent resultData) { 14576 14577 synchronized (this) { 14578 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14579 if (stack != null) { 14580 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14581 } 14582 return false; 14583 } 14584 } 14585 14586 public int getLaunchedFromUid(IBinder activityToken) { 14587 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14588 if (srec == null) { 14589 return -1; 14590 } 14591 return srec.launchedFromUid; 14592 } 14593 14594 public String getLaunchedFromPackage(IBinder activityToken) { 14595 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14596 if (srec == null) { 14597 return null; 14598 } 14599 return srec.launchedFromPackage; 14600 } 14601 14602 // ========================================================= 14603 // LIFETIME MANAGEMENT 14604 // ========================================================= 14605 14606 // Returns which broadcast queue the app is the current [or imminent] receiver 14607 // on, or 'null' if the app is not an active broadcast recipient. 14608 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14609 BroadcastRecord r = app.curReceiver; 14610 if (r != null) { 14611 return r.queue; 14612 } 14613 14614 // It's not the current receiver, but it might be starting up to become one 14615 synchronized (this) { 14616 for (BroadcastQueue queue : mBroadcastQueues) { 14617 r = queue.mPendingBroadcast; 14618 if (r != null && r.curApp == app) { 14619 // found it; report which queue it's in 14620 return queue; 14621 } 14622 } 14623 } 14624 14625 return null; 14626 } 14627 14628 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14629 boolean doingAll, long now) { 14630 if (mAdjSeq == app.adjSeq) { 14631 // This adjustment has already been computed. 14632 return app.curRawAdj; 14633 } 14634 14635 if (app.thread == null) { 14636 app.adjSeq = mAdjSeq; 14637 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14638 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14639 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14640 } 14641 14642 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14643 app.adjSource = null; 14644 app.adjTarget = null; 14645 app.empty = false; 14646 app.cached = false; 14647 14648 final int activitiesSize = app.activities.size(); 14649 14650 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14651 // The max adjustment doesn't allow this app to be anything 14652 // below foreground, so it is not worth doing work for it. 14653 app.adjType = "fixed"; 14654 app.adjSeq = mAdjSeq; 14655 app.curRawAdj = app.maxAdj; 14656 app.foregroundActivities = false; 14657 app.keeping = true; 14658 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14659 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14660 // System processes can do UI, and when they do we want to have 14661 // them trim their memory after the user leaves the UI. To 14662 // facilitate this, here we need to determine whether or not it 14663 // is currently showing UI. 14664 app.systemNoUi = true; 14665 if (app == TOP_APP) { 14666 app.systemNoUi = false; 14667 } else if (activitiesSize > 0) { 14668 for (int j = 0; j < activitiesSize; j++) { 14669 final ActivityRecord r = app.activities.get(j); 14670 if (r.visible) { 14671 app.systemNoUi = false; 14672 } 14673 } 14674 } 14675 if (!app.systemNoUi) { 14676 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14677 } 14678 return (app.curAdj=app.maxAdj); 14679 } 14680 14681 app.keeping = false; 14682 app.systemNoUi = false; 14683 14684 // Determine the importance of the process, starting with most 14685 // important to least, and assign an appropriate OOM adjustment. 14686 int adj; 14687 int schedGroup; 14688 int procState; 14689 boolean foregroundActivities = false; 14690 boolean interesting = false; 14691 BroadcastQueue queue; 14692 if (app == TOP_APP) { 14693 // The last app on the list is the foreground app. 14694 adj = ProcessList.FOREGROUND_APP_ADJ; 14695 schedGroup = Process.THREAD_GROUP_DEFAULT; 14696 app.adjType = "top-activity"; 14697 foregroundActivities = true; 14698 interesting = true; 14699 procState = ActivityManager.PROCESS_STATE_TOP; 14700 } else if (app.instrumentationClass != null) { 14701 // Don't want to kill running instrumentation. 14702 adj = ProcessList.FOREGROUND_APP_ADJ; 14703 schedGroup = Process.THREAD_GROUP_DEFAULT; 14704 app.adjType = "instrumentation"; 14705 interesting = true; 14706 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14707 } else if ((queue = isReceivingBroadcast(app)) != null) { 14708 // An app that is currently receiving a broadcast also 14709 // counts as being in the foreground for OOM killer purposes. 14710 // It's placed in a sched group based on the nature of the 14711 // broadcast as reflected by which queue it's active in. 14712 adj = ProcessList.FOREGROUND_APP_ADJ; 14713 schedGroup = (queue == mFgBroadcastQueue) 14714 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14715 app.adjType = "broadcast"; 14716 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14717 } else if (app.executingServices.size() > 0) { 14718 // An app that is currently executing a service callback also 14719 // counts as being in the foreground. 14720 adj = ProcessList.FOREGROUND_APP_ADJ; 14721 schedGroup = app.execServicesFg ? 14722 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14723 app.adjType = "exec-service"; 14724 procState = ActivityManager.PROCESS_STATE_SERVICE; 14725 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14726 } else { 14727 // As far as we know the process is empty. We may change our mind later. 14728 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14729 // At this point we don't actually know the adjustment. Use the cached adj 14730 // value that the caller wants us to. 14731 adj = cachedAdj; 14732 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14733 app.cached = true; 14734 app.empty = true; 14735 app.adjType = "cch-empty"; 14736 } 14737 14738 // Examine all activities if not already foreground. 14739 if (!foregroundActivities && activitiesSize > 0) { 14740 for (int j = 0; j < activitiesSize; j++) { 14741 final ActivityRecord r = app.activities.get(j); 14742 if (r.app != app) { 14743 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14744 + app + "?!?"); 14745 continue; 14746 } 14747 if (r.visible) { 14748 // App has a visible activity; only upgrade adjustment. 14749 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14750 adj = ProcessList.VISIBLE_APP_ADJ; 14751 app.adjType = "visible"; 14752 } 14753 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14754 procState = ActivityManager.PROCESS_STATE_TOP; 14755 } 14756 schedGroup = Process.THREAD_GROUP_DEFAULT; 14757 app.cached = false; 14758 app.empty = false; 14759 foregroundActivities = true; 14760 break; 14761 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14762 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14763 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14764 app.adjType = "pausing"; 14765 } 14766 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14767 procState = ActivityManager.PROCESS_STATE_TOP; 14768 } 14769 schedGroup = Process.THREAD_GROUP_DEFAULT; 14770 app.cached = false; 14771 app.empty = false; 14772 foregroundActivities = true; 14773 } else if (r.state == ActivityState.STOPPING) { 14774 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14775 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14776 app.adjType = "stopping"; 14777 } 14778 // For the process state, we will at this point consider the 14779 // process to be cached. It will be cached either as an activity 14780 // or empty depending on whether the activity is finishing. We do 14781 // this so that we can treat the process as cached for purposes of 14782 // memory trimming (determing current memory level, trim command to 14783 // send to process) since there can be an arbitrary number of stopping 14784 // processes and they should soon all go into the cached state. 14785 if (!r.finishing) { 14786 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14787 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14788 } 14789 } 14790 app.cached = false; 14791 app.empty = false; 14792 foregroundActivities = true; 14793 } else { 14794 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14795 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14796 app.adjType = "cch-act"; 14797 } 14798 } 14799 } 14800 } 14801 14802 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14803 if (app.foregroundServices) { 14804 // The user is aware of this app, so make it visible. 14805 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14806 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14807 app.cached = false; 14808 app.adjType = "fg-service"; 14809 schedGroup = Process.THREAD_GROUP_DEFAULT; 14810 } else if (app.forcingToForeground != null) { 14811 // The user is aware of this app, so make it visible. 14812 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14813 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14814 app.cached = false; 14815 app.adjType = "force-fg"; 14816 app.adjSource = app.forcingToForeground; 14817 schedGroup = Process.THREAD_GROUP_DEFAULT; 14818 } 14819 } 14820 14821 if (app.foregroundServices) { 14822 interesting = true; 14823 } 14824 14825 if (app == mHeavyWeightProcess) { 14826 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14827 // We don't want to kill the current heavy-weight process. 14828 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14829 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14830 app.cached = false; 14831 app.adjType = "heavy"; 14832 } 14833 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14834 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14835 } 14836 } 14837 14838 if (app == mHomeProcess) { 14839 if (adj > ProcessList.HOME_APP_ADJ) { 14840 // This process is hosting what we currently consider to be the 14841 // home app, so we don't want to let it go into the background. 14842 adj = ProcessList.HOME_APP_ADJ; 14843 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14844 app.cached = false; 14845 app.adjType = "home"; 14846 } 14847 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14848 procState = ActivityManager.PROCESS_STATE_HOME; 14849 } 14850 } 14851 14852 if (app == mPreviousProcess && app.activities.size() > 0) { 14853 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14854 // This was the previous process that showed UI to the user. 14855 // We want to try to keep it around more aggressively, to give 14856 // a good experience around switching between two apps. 14857 adj = ProcessList.PREVIOUS_APP_ADJ; 14858 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14859 app.cached = false; 14860 app.adjType = "previous"; 14861 } 14862 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14863 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14864 } 14865 } 14866 14867 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14868 + " reason=" + app.adjType); 14869 14870 // By default, we use the computed adjustment. It may be changed if 14871 // there are applications dependent on our services or providers, but 14872 // this gives us a baseline and makes sure we don't get into an 14873 // infinite recursion. 14874 app.adjSeq = mAdjSeq; 14875 app.curRawAdj = adj; 14876 app.hasStartedServices = false; 14877 14878 if (mBackupTarget != null && app == mBackupTarget.app) { 14879 // If possible we want to avoid killing apps while they're being backed up 14880 if (adj > ProcessList.BACKUP_APP_ADJ) { 14881 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14882 adj = ProcessList.BACKUP_APP_ADJ; 14883 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14884 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14885 } 14886 app.adjType = "backup"; 14887 app.cached = false; 14888 } 14889 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14890 procState = ActivityManager.PROCESS_STATE_BACKUP; 14891 } 14892 } 14893 14894 boolean mayBeTop = false; 14895 14896 for (int is = app.services.size()-1; 14897 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14898 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14899 || procState > ActivityManager.PROCESS_STATE_TOP); 14900 is--) { 14901 ServiceRecord s = app.services.valueAt(is); 14902 if (s.startRequested) { 14903 app.hasStartedServices = true; 14904 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14905 procState = ActivityManager.PROCESS_STATE_SERVICE; 14906 } 14907 if (app.hasShownUi && app != mHomeProcess) { 14908 // If this process has shown some UI, let it immediately 14909 // go to the LRU list because it may be pretty heavy with 14910 // UI stuff. We'll tag it with a label just to help 14911 // debug and understand what is going on. 14912 if (adj > ProcessList.SERVICE_ADJ) { 14913 app.adjType = "cch-started-ui-services"; 14914 } 14915 } else { 14916 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14917 // This service has seen some activity within 14918 // recent memory, so we will keep its process ahead 14919 // of the background processes. 14920 if (adj > ProcessList.SERVICE_ADJ) { 14921 adj = ProcessList.SERVICE_ADJ; 14922 app.adjType = "started-services"; 14923 app.cached = false; 14924 } 14925 } 14926 // If we have let the service slide into the background 14927 // state, still have some text describing what it is doing 14928 // even though the service no longer has an impact. 14929 if (adj > ProcessList.SERVICE_ADJ) { 14930 app.adjType = "cch-started-services"; 14931 } 14932 } 14933 // Don't kill this process because it is doing work; it 14934 // has said it is doing work. 14935 app.keeping = true; 14936 } 14937 for (int conni = s.connections.size()-1; 14938 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14940 || procState > ActivityManager.PROCESS_STATE_TOP); 14941 conni--) { 14942 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14943 for (int i = 0; 14944 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14945 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14946 || procState > ActivityManager.PROCESS_STATE_TOP); 14947 i++) { 14948 // XXX should compute this based on the max of 14949 // all connected clients. 14950 ConnectionRecord cr = clist.get(i); 14951 if (cr.binding.client == app) { 14952 // Binding to ourself is not interesting. 14953 continue; 14954 } 14955 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14956 ProcessRecord client = cr.binding.client; 14957 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14958 TOP_APP, doingAll, now); 14959 int clientProcState = client.curProcState; 14960 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14961 // If the other app is cached for any reason, for purposes here 14962 // we are going to consider it empty. The specific cached state 14963 // doesn't propagate except under certain conditions. 14964 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14965 } 14966 String adjType = null; 14967 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14968 // Not doing bind OOM management, so treat 14969 // this guy more like a started service. 14970 if (app.hasShownUi && app != mHomeProcess) { 14971 // If this process has shown some UI, let it immediately 14972 // go to the LRU list because it may be pretty heavy with 14973 // UI stuff. We'll tag it with a label just to help 14974 // debug and understand what is going on. 14975 if (adj > clientAdj) { 14976 adjType = "cch-bound-ui-services"; 14977 } 14978 app.cached = false; 14979 clientAdj = adj; 14980 clientProcState = procState; 14981 } else { 14982 if (now >= (s.lastActivity 14983 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14984 // This service has not seen activity within 14985 // recent memory, so allow it to drop to the 14986 // LRU list if there is no other reason to keep 14987 // it around. We'll also tag it with a label just 14988 // to help debug and undertand what is going on. 14989 if (adj > clientAdj) { 14990 adjType = "cch-bound-services"; 14991 } 14992 clientAdj = adj; 14993 } 14994 } 14995 } 14996 if (adj > clientAdj) { 14997 // If this process has recently shown UI, and 14998 // the process that is binding to it is less 14999 // important than being visible, then we don't 15000 // care about the binding as much as we care 15001 // about letting this process get into the LRU 15002 // list to be killed and restarted if needed for 15003 // memory. 15004 if (app.hasShownUi && app != mHomeProcess 15005 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15006 adjType = "cch-bound-ui-services"; 15007 } else { 15008 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15009 |Context.BIND_IMPORTANT)) != 0) { 15010 adj = clientAdj; 15011 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15012 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15013 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15014 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15015 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15016 adj = clientAdj; 15017 } else { 15018 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15019 adj = ProcessList.VISIBLE_APP_ADJ; 15020 } 15021 } 15022 if (!client.cached) { 15023 app.cached = false; 15024 } 15025 if (client.keeping) { 15026 app.keeping = true; 15027 } 15028 adjType = "service"; 15029 } 15030 } 15031 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15032 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15033 schedGroup = Process.THREAD_GROUP_DEFAULT; 15034 } 15035 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15036 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15037 // Special handling of clients who are in the top state. 15038 // We *may* want to consider this process to be in the 15039 // top state as well, but only if there is not another 15040 // reason for it to be running. Being on the top is a 15041 // special state, meaning you are specifically running 15042 // for the current top app. If the process is already 15043 // running in the background for some other reason, it 15044 // is more important to continue considering it to be 15045 // in the background state. 15046 mayBeTop = true; 15047 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15048 } else { 15049 // Special handling for above-top states (persistent 15050 // processes). These should not bring the current process 15051 // into the top state, since they are not on top. Instead 15052 // give them the best state after that. 15053 clientProcState = 15054 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15055 } 15056 } 15057 } else { 15058 if (clientProcState < 15059 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15060 clientProcState = 15061 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15062 } 15063 } 15064 if (procState > clientProcState) { 15065 procState = clientProcState; 15066 } 15067 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15068 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15069 app.pendingUiClean = true; 15070 } 15071 if (adjType != null) { 15072 app.adjType = adjType; 15073 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15074 .REASON_SERVICE_IN_USE; 15075 app.adjSource = cr.binding.client; 15076 app.adjSourceOom = clientAdj; 15077 app.adjTarget = s.name; 15078 } 15079 } 15080 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15081 app.treatLikeActivity = true; 15082 } 15083 final ActivityRecord a = cr.activity; 15084 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15085 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15086 (a.visible || a.state == ActivityState.RESUMED 15087 || a.state == ActivityState.PAUSING)) { 15088 adj = ProcessList.FOREGROUND_APP_ADJ; 15089 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15090 schedGroup = Process.THREAD_GROUP_DEFAULT; 15091 } 15092 app.cached = false; 15093 app.adjType = "service"; 15094 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15095 .REASON_SERVICE_IN_USE; 15096 app.adjSource = a; 15097 app.adjSourceOom = adj; 15098 app.adjTarget = s.name; 15099 } 15100 } 15101 } 15102 } 15103 } 15104 15105 for (int provi = app.pubProviders.size()-1; 15106 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15107 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15108 || procState > ActivityManager.PROCESS_STATE_TOP); 15109 provi--) { 15110 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15111 for (int i = cpr.connections.size()-1; 15112 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15113 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15114 || procState > ActivityManager.PROCESS_STATE_TOP); 15115 i--) { 15116 ContentProviderConnection conn = cpr.connections.get(i); 15117 ProcessRecord client = conn.client; 15118 if (client == app) { 15119 // Being our own client is not interesting. 15120 continue; 15121 } 15122 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15123 int clientProcState = client.curProcState; 15124 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15125 // If the other app is cached for any reason, for purposes here 15126 // we are going to consider it empty. 15127 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15128 } 15129 if (adj > clientAdj) { 15130 if (app.hasShownUi && app != mHomeProcess 15131 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15132 app.adjType = "cch-ui-provider"; 15133 } else { 15134 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15135 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15136 app.adjType = "provider"; 15137 } 15138 app.cached &= client.cached; 15139 app.keeping |= client.keeping; 15140 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15141 .REASON_PROVIDER_IN_USE; 15142 app.adjSource = client; 15143 app.adjSourceOom = clientAdj; 15144 app.adjTarget = cpr.name; 15145 } 15146 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15147 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15148 // Special handling of clients who are in the top state. 15149 // We *may* want to consider this process to be in the 15150 // top state as well, but only if there is not another 15151 // reason for it to be running. Being on the top is a 15152 // special state, meaning you are specifically running 15153 // for the current top app. If the process is already 15154 // running in the background for some other reason, it 15155 // is more important to continue considering it to be 15156 // in the background state. 15157 mayBeTop = true; 15158 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15159 } else { 15160 // Special handling for above-top states (persistent 15161 // processes). These should not bring the current process 15162 // into the top state, since they are not on top. Instead 15163 // give them the best state after that. 15164 clientProcState = 15165 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15166 } 15167 } 15168 if (procState > clientProcState) { 15169 procState = clientProcState; 15170 } 15171 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15172 schedGroup = Process.THREAD_GROUP_DEFAULT; 15173 } 15174 } 15175 // If the provider has external (non-framework) process 15176 // dependencies, ensure that its adjustment is at least 15177 // FOREGROUND_APP_ADJ. 15178 if (cpr.hasExternalProcessHandles()) { 15179 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15180 adj = ProcessList.FOREGROUND_APP_ADJ; 15181 schedGroup = Process.THREAD_GROUP_DEFAULT; 15182 app.cached = false; 15183 app.keeping = true; 15184 app.adjType = "provider"; 15185 app.adjTarget = cpr.name; 15186 } 15187 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15188 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15189 } 15190 } 15191 } 15192 15193 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15194 // A client of one of our services or providers is in the top state. We 15195 // *may* want to be in the top state, but not if we are already running in 15196 // the background for some other reason. For the decision here, we are going 15197 // to pick out a few specific states that we want to remain in when a client 15198 // is top (states that tend to be longer-term) and otherwise allow it to go 15199 // to the top state. 15200 switch (procState) { 15201 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15202 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15203 case ActivityManager.PROCESS_STATE_SERVICE: 15204 // These all are longer-term states, so pull them up to the top 15205 // of the background states, but not all the way to the top state. 15206 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15207 break; 15208 default: 15209 // Otherwise, top is a better choice, so take it. 15210 procState = ActivityManager.PROCESS_STATE_TOP; 15211 break; 15212 } 15213 } 15214 15215 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15216 if (app.hasClientActivities) { 15217 // This is a cached process, but with client activities. Mark it so. 15218 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15219 app.adjType = "cch-client-act"; 15220 } else if (app.treatLikeActivity) { 15221 // This is a cached process, but somebody wants us to treat it like it has 15222 // an activity, okay! 15223 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15224 app.adjType = "cch-as-act"; 15225 } 15226 } 15227 15228 if (adj == ProcessList.SERVICE_ADJ) { 15229 if (doingAll) { 15230 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15231 mNewNumServiceProcs++; 15232 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15233 if (!app.serviceb) { 15234 // This service isn't far enough down on the LRU list to 15235 // normally be a B service, but if we are low on RAM and it 15236 // is large we want to force it down since we would prefer to 15237 // keep launcher over it. 15238 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15239 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15240 app.serviceHighRam = true; 15241 app.serviceb = true; 15242 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15243 } else { 15244 mNewNumAServiceProcs++; 15245 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15246 } 15247 } else { 15248 app.serviceHighRam = false; 15249 } 15250 } 15251 if (app.serviceb) { 15252 adj = ProcessList.SERVICE_B_ADJ; 15253 } 15254 } 15255 15256 app.curRawAdj = adj; 15257 15258 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15259 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15260 if (adj > app.maxAdj) { 15261 adj = app.maxAdj; 15262 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15263 schedGroup = Process.THREAD_GROUP_DEFAULT; 15264 } 15265 } 15266 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15267 app.keeping = true; 15268 } 15269 15270 // Do final modification to adj. Everything we do between here and applying 15271 // the final setAdj must be done in this function, because we will also use 15272 // it when computing the final cached adj later. Note that we don't need to 15273 // worry about this for max adj above, since max adj will always be used to 15274 // keep it out of the cached vaues. 15275 app.curAdj = app.modifyRawOomAdj(adj); 15276 app.curSchedGroup = schedGroup; 15277 app.curProcState = procState; 15278 app.foregroundActivities = foregroundActivities; 15279 15280 return app.curRawAdj; 15281 } 15282 15283 /** 15284 * Schedule PSS collection of a process. 15285 */ 15286 void requestPssLocked(ProcessRecord proc, int procState) { 15287 if (mPendingPssProcesses.contains(proc)) { 15288 return; 15289 } 15290 if (mPendingPssProcesses.size() == 0) { 15291 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15292 } 15293 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15294 proc.pssProcState = procState; 15295 mPendingPssProcesses.add(proc); 15296 } 15297 15298 /** 15299 * Schedule PSS collection of all processes. 15300 */ 15301 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15302 if (!always) { 15303 if (now < (mLastFullPssTime + 15304 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15305 return; 15306 } 15307 } 15308 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15309 mLastFullPssTime = now; 15310 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15311 mPendingPssProcesses.clear(); 15312 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15313 ProcessRecord app = mLruProcesses.get(i); 15314 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15315 app.pssProcState = app.setProcState; 15316 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15317 isSleeping(), now); 15318 mPendingPssProcesses.add(app); 15319 } 15320 } 15321 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15322 } 15323 15324 /** 15325 * Ask a given process to GC right now. 15326 */ 15327 final void performAppGcLocked(ProcessRecord app) { 15328 try { 15329 app.lastRequestedGc = SystemClock.uptimeMillis(); 15330 if (app.thread != null) { 15331 if (app.reportLowMemory) { 15332 app.reportLowMemory = false; 15333 app.thread.scheduleLowMemory(); 15334 } else { 15335 app.thread.processInBackground(); 15336 } 15337 } 15338 } catch (Exception e) { 15339 // whatever. 15340 } 15341 } 15342 15343 /** 15344 * Returns true if things are idle enough to perform GCs. 15345 */ 15346 private final boolean canGcNowLocked() { 15347 boolean processingBroadcasts = false; 15348 for (BroadcastQueue q : mBroadcastQueues) { 15349 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15350 processingBroadcasts = true; 15351 } 15352 } 15353 return !processingBroadcasts 15354 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15355 } 15356 15357 /** 15358 * Perform GCs on all processes that are waiting for it, but only 15359 * if things are idle. 15360 */ 15361 final void performAppGcsLocked() { 15362 final int N = mProcessesToGc.size(); 15363 if (N <= 0) { 15364 return; 15365 } 15366 if (canGcNowLocked()) { 15367 while (mProcessesToGc.size() > 0) { 15368 ProcessRecord proc = mProcessesToGc.remove(0); 15369 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15370 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15371 <= SystemClock.uptimeMillis()) { 15372 // To avoid spamming the system, we will GC processes one 15373 // at a time, waiting a few seconds between each. 15374 performAppGcLocked(proc); 15375 scheduleAppGcsLocked(); 15376 return; 15377 } else { 15378 // It hasn't been long enough since we last GCed this 15379 // process... put it in the list to wait for its time. 15380 addProcessToGcListLocked(proc); 15381 break; 15382 } 15383 } 15384 } 15385 15386 scheduleAppGcsLocked(); 15387 } 15388 } 15389 15390 /** 15391 * If all looks good, perform GCs on all processes waiting for them. 15392 */ 15393 final void performAppGcsIfAppropriateLocked() { 15394 if (canGcNowLocked()) { 15395 performAppGcsLocked(); 15396 return; 15397 } 15398 // Still not idle, wait some more. 15399 scheduleAppGcsLocked(); 15400 } 15401 15402 /** 15403 * Schedule the execution of all pending app GCs. 15404 */ 15405 final void scheduleAppGcsLocked() { 15406 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15407 15408 if (mProcessesToGc.size() > 0) { 15409 // Schedule a GC for the time to the next process. 15410 ProcessRecord proc = mProcessesToGc.get(0); 15411 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15412 15413 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15414 long now = SystemClock.uptimeMillis(); 15415 if (when < (now+GC_TIMEOUT)) { 15416 when = now + GC_TIMEOUT; 15417 } 15418 mHandler.sendMessageAtTime(msg, when); 15419 } 15420 } 15421 15422 /** 15423 * Add a process to the array of processes waiting to be GCed. Keeps the 15424 * list in sorted order by the last GC time. The process can't already be 15425 * on the list. 15426 */ 15427 final void addProcessToGcListLocked(ProcessRecord proc) { 15428 boolean added = false; 15429 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15430 if (mProcessesToGc.get(i).lastRequestedGc < 15431 proc.lastRequestedGc) { 15432 added = true; 15433 mProcessesToGc.add(i+1, proc); 15434 break; 15435 } 15436 } 15437 if (!added) { 15438 mProcessesToGc.add(0, proc); 15439 } 15440 } 15441 15442 /** 15443 * Set up to ask a process to GC itself. This will either do it 15444 * immediately, or put it on the list of processes to gc the next 15445 * time things are idle. 15446 */ 15447 final void scheduleAppGcLocked(ProcessRecord app) { 15448 long now = SystemClock.uptimeMillis(); 15449 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15450 return; 15451 } 15452 if (!mProcessesToGc.contains(app)) { 15453 addProcessToGcListLocked(app); 15454 scheduleAppGcsLocked(); 15455 } 15456 } 15457 15458 final void checkExcessivePowerUsageLocked(boolean doKills) { 15459 updateCpuStatsNow(); 15460 15461 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15462 boolean doWakeKills = doKills; 15463 boolean doCpuKills = doKills; 15464 if (mLastPowerCheckRealtime == 0) { 15465 doWakeKills = false; 15466 } 15467 if (mLastPowerCheckUptime == 0) { 15468 doCpuKills = false; 15469 } 15470 if (stats.isScreenOn()) { 15471 doWakeKills = false; 15472 } 15473 final long curRealtime = SystemClock.elapsedRealtime(); 15474 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15475 final long curUptime = SystemClock.uptimeMillis(); 15476 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15477 mLastPowerCheckRealtime = curRealtime; 15478 mLastPowerCheckUptime = curUptime; 15479 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15480 doWakeKills = false; 15481 } 15482 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15483 doCpuKills = false; 15484 } 15485 int i = mLruProcesses.size(); 15486 while (i > 0) { 15487 i--; 15488 ProcessRecord app = mLruProcesses.get(i); 15489 if (!app.keeping) { 15490 long wtime; 15491 synchronized (stats) { 15492 wtime = stats.getProcessWakeTime(app.info.uid, 15493 app.pid, curRealtime); 15494 } 15495 long wtimeUsed = wtime - app.lastWakeTime; 15496 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15497 if (DEBUG_POWER) { 15498 StringBuilder sb = new StringBuilder(128); 15499 sb.append("Wake for "); 15500 app.toShortString(sb); 15501 sb.append(": over "); 15502 TimeUtils.formatDuration(realtimeSince, sb); 15503 sb.append(" used "); 15504 TimeUtils.formatDuration(wtimeUsed, sb); 15505 sb.append(" ("); 15506 sb.append((wtimeUsed*100)/realtimeSince); 15507 sb.append("%)"); 15508 Slog.i(TAG, sb.toString()); 15509 sb.setLength(0); 15510 sb.append("CPU for "); 15511 app.toShortString(sb); 15512 sb.append(": over "); 15513 TimeUtils.formatDuration(uptimeSince, sb); 15514 sb.append(" used "); 15515 TimeUtils.formatDuration(cputimeUsed, sb); 15516 sb.append(" ("); 15517 sb.append((cputimeUsed*100)/uptimeSince); 15518 sb.append("%)"); 15519 Slog.i(TAG, sb.toString()); 15520 } 15521 // If a process has held a wake lock for more 15522 // than 50% of the time during this period, 15523 // that sounds bad. Kill! 15524 if (doWakeKills && realtimeSince > 0 15525 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15526 synchronized (stats) { 15527 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15528 realtimeSince, wtimeUsed); 15529 } 15530 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15531 + " during " + realtimeSince); 15532 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15533 } else if (doCpuKills && uptimeSince > 0 15534 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15535 synchronized (stats) { 15536 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15537 uptimeSince, cputimeUsed); 15538 } 15539 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15540 + " during " + uptimeSince); 15541 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15542 } else { 15543 app.lastWakeTime = wtime; 15544 app.lastCpuTime = app.curCpuTime; 15545 } 15546 } 15547 } 15548 } 15549 15550 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15551 ProcessRecord TOP_APP, boolean doingAll, long now) { 15552 boolean success = true; 15553 15554 if (app.curRawAdj != app.setRawAdj) { 15555 if (wasKeeping && !app.keeping) { 15556 // This app is no longer something we want to keep. Note 15557 // its current wake lock time to later know to kill it if 15558 // it is not behaving well. 15559 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15560 synchronized (stats) { 15561 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15562 app.pid, SystemClock.elapsedRealtime()); 15563 } 15564 app.lastCpuTime = app.curCpuTime; 15565 } 15566 15567 app.setRawAdj = app.curRawAdj; 15568 } 15569 15570 int changes = 0; 15571 15572 if (app.curAdj != app.setAdj) { 15573 ProcessList.setOomAdj(app.pid, app.curAdj); 15574 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15575 TAG, "Set " + app.pid + " " + app.processName + 15576 " adj " + app.curAdj + ": " + app.adjType); 15577 app.setAdj = app.curAdj; 15578 } 15579 15580 if (app.setSchedGroup != app.curSchedGroup) { 15581 app.setSchedGroup = app.curSchedGroup; 15582 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15583 "Setting process group of " + app.processName 15584 + " to " + app.curSchedGroup); 15585 if (app.waitingToKill != null && 15586 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15587 killUnneededProcessLocked(app, app.waitingToKill); 15588 success = false; 15589 } else { 15590 if (true) { 15591 long oldId = Binder.clearCallingIdentity(); 15592 try { 15593 Process.setProcessGroup(app.pid, app.curSchedGroup); 15594 } catch (Exception e) { 15595 Slog.w(TAG, "Failed setting process group of " + app.pid 15596 + " to " + app.curSchedGroup); 15597 e.printStackTrace(); 15598 } finally { 15599 Binder.restoreCallingIdentity(oldId); 15600 } 15601 } else { 15602 if (app.thread != null) { 15603 try { 15604 app.thread.setSchedulingGroup(app.curSchedGroup); 15605 } catch (RemoteException e) { 15606 } 15607 } 15608 } 15609 Process.setSwappiness(app.pid, 15610 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15611 } 15612 } 15613 if (app.repForegroundActivities != app.foregroundActivities) { 15614 app.repForegroundActivities = app.foregroundActivities; 15615 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15616 } 15617 if (app.repProcState != app.curProcState) { 15618 app.repProcState = app.curProcState; 15619 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15620 if (app.thread != null) { 15621 try { 15622 if (false) { 15623 //RuntimeException h = new RuntimeException("here"); 15624 Slog.i(TAG, "Sending new process state " + app.repProcState 15625 + " to " + app /*, h*/); 15626 } 15627 app.thread.setProcessState(app.repProcState); 15628 } catch (RemoteException e) { 15629 } 15630 } 15631 } 15632 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15633 app.setProcState)) { 15634 app.lastStateTime = now; 15635 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15636 isSleeping(), now); 15637 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15638 + ProcessList.makeProcStateString(app.setProcState) + " to " 15639 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15640 + (app.nextPssTime-now) + ": " + app); 15641 } else { 15642 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15643 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15644 requestPssLocked(app, app.setProcState); 15645 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15646 isSleeping(), now); 15647 } else if (false && DEBUG_PSS) { 15648 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15649 } 15650 } 15651 if (app.setProcState != app.curProcState) { 15652 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15653 "Proc state change of " + app.processName 15654 + " to " + app.curProcState); 15655 app.setProcState = app.curProcState; 15656 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15657 app.notCachedSinceIdle = false; 15658 } 15659 if (!doingAll) { 15660 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15661 } else { 15662 app.procStateChanged = true; 15663 } 15664 } 15665 15666 if (changes != 0) { 15667 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15668 int i = mPendingProcessChanges.size()-1; 15669 ProcessChangeItem item = null; 15670 while (i >= 0) { 15671 item = mPendingProcessChanges.get(i); 15672 if (item.pid == app.pid) { 15673 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15674 break; 15675 } 15676 i--; 15677 } 15678 if (i < 0) { 15679 // No existing item in pending changes; need a new one. 15680 final int NA = mAvailProcessChanges.size(); 15681 if (NA > 0) { 15682 item = mAvailProcessChanges.remove(NA-1); 15683 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15684 } else { 15685 item = new ProcessChangeItem(); 15686 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15687 } 15688 item.changes = 0; 15689 item.pid = app.pid; 15690 item.uid = app.info.uid; 15691 if (mPendingProcessChanges.size() == 0) { 15692 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15693 "*** Enqueueing dispatch processes changed!"); 15694 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15695 } 15696 mPendingProcessChanges.add(item); 15697 } 15698 item.changes |= changes; 15699 item.processState = app.repProcState; 15700 item.foregroundActivities = app.repForegroundActivities; 15701 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15702 + Integer.toHexString(System.identityHashCode(item)) 15703 + " " + app.toShortString() + ": changes=" + item.changes 15704 + " procState=" + item.processState 15705 + " foreground=" + item.foregroundActivities 15706 + " type=" + app.adjType + " source=" + app.adjSource 15707 + " target=" + app.adjTarget); 15708 } 15709 15710 return success; 15711 } 15712 15713 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15714 if (proc.thread != null && proc.baseProcessTracker != null) { 15715 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15716 } 15717 } 15718 15719 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15720 ProcessRecord TOP_APP, boolean doingAll, long now) { 15721 if (app.thread == null) { 15722 return false; 15723 } 15724 15725 final boolean wasKeeping = app.keeping; 15726 15727 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15728 15729 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15730 } 15731 15732 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15733 boolean oomAdj) { 15734 if (isForeground != proc.foregroundServices) { 15735 proc.foregroundServices = isForeground; 15736 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15737 proc.info.uid); 15738 if (isForeground) { 15739 if (curProcs == null) { 15740 curProcs = new ArrayList<ProcessRecord>(); 15741 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15742 } 15743 if (!curProcs.contains(proc)) { 15744 curProcs.add(proc); 15745 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15746 proc.info.packageName, proc.info.uid); 15747 } 15748 } else { 15749 if (curProcs != null) { 15750 if (curProcs.remove(proc)) { 15751 mBatteryStatsService.noteEvent( 15752 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15753 proc.info.packageName, proc.info.uid); 15754 if (curProcs.size() <= 0) { 15755 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15756 } 15757 } 15758 } 15759 } 15760 if (oomAdj) { 15761 updateOomAdjLocked(); 15762 } 15763 } 15764 } 15765 15766 private final ActivityRecord resumedAppLocked() { 15767 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15768 String pkg; 15769 int uid; 15770 if (act != null && !act.sleeping) { 15771 pkg = act.packageName; 15772 uid = act.info.applicationInfo.uid; 15773 } else { 15774 pkg = null; 15775 uid = -1; 15776 } 15777 // Has the UID or resumed package name changed? 15778 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15779 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15780 if (mCurResumedPackage != null) { 15781 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15782 mCurResumedPackage, mCurResumedUid); 15783 } 15784 mCurResumedPackage = pkg; 15785 mCurResumedUid = uid; 15786 if (mCurResumedPackage != null) { 15787 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15788 mCurResumedPackage, mCurResumedUid); 15789 } 15790 } 15791 return act; 15792 } 15793 15794 final boolean updateOomAdjLocked(ProcessRecord app) { 15795 final ActivityRecord TOP_ACT = resumedAppLocked(); 15796 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15797 final boolean wasCached = app.cached; 15798 15799 mAdjSeq++; 15800 15801 // This is the desired cached adjusment we want to tell it to use. 15802 // If our app is currently cached, we know it, and that is it. Otherwise, 15803 // we don't know it yet, and it needs to now be cached we will then 15804 // need to do a complete oom adj. 15805 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15806 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15807 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15808 SystemClock.uptimeMillis()); 15809 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15810 // Changed to/from cached state, so apps after it in the LRU 15811 // list may also be changed. 15812 updateOomAdjLocked(); 15813 } 15814 return success; 15815 } 15816 15817 final void updateOomAdjLocked() { 15818 final ActivityRecord TOP_ACT = resumedAppLocked(); 15819 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15820 final long now = SystemClock.uptimeMillis(); 15821 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15822 final int N = mLruProcesses.size(); 15823 15824 if (false) { 15825 RuntimeException e = new RuntimeException(); 15826 e.fillInStackTrace(); 15827 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15828 } 15829 15830 mAdjSeq++; 15831 mNewNumServiceProcs = 0; 15832 mNewNumAServiceProcs = 0; 15833 15834 final int emptyProcessLimit; 15835 final int cachedProcessLimit; 15836 if (mProcessLimit <= 0) { 15837 emptyProcessLimit = cachedProcessLimit = 0; 15838 } else if (mProcessLimit == 1) { 15839 emptyProcessLimit = 1; 15840 cachedProcessLimit = 0; 15841 } else { 15842 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15843 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15844 } 15845 15846 // Let's determine how many processes we have running vs. 15847 // how many slots we have for background processes; we may want 15848 // to put multiple processes in a slot of there are enough of 15849 // them. 15850 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15851 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15852 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15853 if (numEmptyProcs > cachedProcessLimit) { 15854 // If there are more empty processes than our limit on cached 15855 // processes, then use the cached process limit for the factor. 15856 // This ensures that the really old empty processes get pushed 15857 // down to the bottom, so if we are running low on memory we will 15858 // have a better chance at keeping around more cached processes 15859 // instead of a gazillion empty processes. 15860 numEmptyProcs = cachedProcessLimit; 15861 } 15862 int emptyFactor = numEmptyProcs/numSlots; 15863 if (emptyFactor < 1) emptyFactor = 1; 15864 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15865 if (cachedFactor < 1) cachedFactor = 1; 15866 int stepCached = 0; 15867 int stepEmpty = 0; 15868 int numCached = 0; 15869 int numEmpty = 0; 15870 int numTrimming = 0; 15871 15872 mNumNonCachedProcs = 0; 15873 mNumCachedHiddenProcs = 0; 15874 15875 // First update the OOM adjustment for each of the 15876 // application processes based on their current state. 15877 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15878 int nextCachedAdj = curCachedAdj+1; 15879 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15880 int nextEmptyAdj = curEmptyAdj+2; 15881 for (int i=N-1; i>=0; i--) { 15882 ProcessRecord app = mLruProcesses.get(i); 15883 if (!app.killedByAm && app.thread != null) { 15884 app.procStateChanged = false; 15885 final boolean wasKeeping = app.keeping; 15886 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15887 15888 // If we haven't yet assigned the final cached adj 15889 // to the process, do that now. 15890 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15891 switch (app.curProcState) { 15892 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15893 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15894 // This process is a cached process holding activities... 15895 // assign it the next cached value for that type, and then 15896 // step that cached level. 15897 app.curRawAdj = curCachedAdj; 15898 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15899 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15900 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15901 + ")"); 15902 if (curCachedAdj != nextCachedAdj) { 15903 stepCached++; 15904 if (stepCached >= cachedFactor) { 15905 stepCached = 0; 15906 curCachedAdj = nextCachedAdj; 15907 nextCachedAdj += 2; 15908 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15909 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15910 } 15911 } 15912 } 15913 break; 15914 default: 15915 // For everything else, assign next empty cached process 15916 // level and bump that up. Note that this means that 15917 // long-running services that have dropped down to the 15918 // cached level will be treated as empty (since their process 15919 // state is still as a service), which is what we want. 15920 app.curRawAdj = curEmptyAdj; 15921 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15922 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15923 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15924 + ")"); 15925 if (curEmptyAdj != nextEmptyAdj) { 15926 stepEmpty++; 15927 if (stepEmpty >= emptyFactor) { 15928 stepEmpty = 0; 15929 curEmptyAdj = nextEmptyAdj; 15930 nextEmptyAdj += 2; 15931 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15932 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15933 } 15934 } 15935 } 15936 break; 15937 } 15938 } 15939 15940 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15941 15942 // Count the number of process types. 15943 switch (app.curProcState) { 15944 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15945 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15946 mNumCachedHiddenProcs++; 15947 numCached++; 15948 if (numCached > cachedProcessLimit) { 15949 killUnneededProcessLocked(app, "cached #" + numCached); 15950 } 15951 break; 15952 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15953 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15954 && app.lastActivityTime < oldTime) { 15955 killUnneededProcessLocked(app, "empty for " 15956 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15957 / 1000) + "s"); 15958 } else { 15959 numEmpty++; 15960 if (numEmpty > emptyProcessLimit) { 15961 killUnneededProcessLocked(app, "empty #" + numEmpty); 15962 } 15963 } 15964 break; 15965 default: 15966 mNumNonCachedProcs++; 15967 break; 15968 } 15969 15970 if (app.isolated && app.services.size() <= 0) { 15971 // If this is an isolated process, and there are no 15972 // services running in it, then the process is no longer 15973 // needed. We agressively kill these because we can by 15974 // definition not re-use the same process again, and it is 15975 // good to avoid having whatever code was running in them 15976 // left sitting around after no longer needed. 15977 killUnneededProcessLocked(app, "isolated not needed"); 15978 } 15979 15980 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15981 && !app.killedByAm) { 15982 numTrimming++; 15983 } 15984 } 15985 } 15986 15987 mNumServiceProcs = mNewNumServiceProcs; 15988 15989 // Now determine the memory trimming level of background processes. 15990 // Unfortunately we need to start at the back of the list to do this 15991 // properly. We only do this if the number of background apps we 15992 // are managing to keep around is less than half the maximum we desire; 15993 // if we are keeping a good number around, we'll let them use whatever 15994 // memory they want. 15995 final int numCachedAndEmpty = numCached + numEmpty; 15996 int memFactor; 15997 if (numCached <= ProcessList.TRIM_CACHED_APPS 15998 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15999 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16000 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16001 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16002 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16003 } else { 16004 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16005 } 16006 } else { 16007 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16008 } 16009 // We always allow the memory level to go up (better). We only allow it to go 16010 // down if we are in a state where that is allowed, *and* the total number of processes 16011 // has gone down since last time. 16012 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16013 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16014 + " last=" + mLastNumProcesses); 16015 if (memFactor > mLastMemoryLevel) { 16016 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16017 memFactor = mLastMemoryLevel; 16018 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16019 } 16020 } 16021 mLastMemoryLevel = memFactor; 16022 mLastNumProcesses = mLruProcesses.size(); 16023 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16024 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16025 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16026 if (mLowRamStartTime == 0) { 16027 mLowRamStartTime = now; 16028 } 16029 int step = 0; 16030 int fgTrimLevel; 16031 switch (memFactor) { 16032 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16033 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16034 break; 16035 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16036 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16037 break; 16038 default: 16039 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16040 break; 16041 } 16042 int factor = numTrimming/3; 16043 int minFactor = 2; 16044 if (mHomeProcess != null) minFactor++; 16045 if (mPreviousProcess != null) minFactor++; 16046 if (factor < minFactor) factor = minFactor; 16047 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16048 for (int i=N-1; i>=0; i--) { 16049 ProcessRecord app = mLruProcesses.get(i); 16050 if (allChanged || app.procStateChanged) { 16051 setProcessTrackerState(app, trackerMemFactor, now); 16052 app.procStateChanged = false; 16053 } 16054 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16055 && !app.killedByAm) { 16056 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16057 try { 16058 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16059 "Trimming memory of " + app.processName 16060 + " to " + curLevel); 16061 app.thread.scheduleTrimMemory(curLevel); 16062 } catch (RemoteException e) { 16063 } 16064 if (false) { 16065 // For now we won't do this; our memory trimming seems 16066 // to be good enough at this point that destroying 16067 // activities causes more harm than good. 16068 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16069 && app != mHomeProcess && app != mPreviousProcess) { 16070 // Need to do this on its own message because the stack may not 16071 // be in a consistent state at this point. 16072 // For these apps we will also finish their activities 16073 // to help them free memory. 16074 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16075 } 16076 } 16077 } 16078 app.trimMemoryLevel = curLevel; 16079 step++; 16080 if (step >= factor) { 16081 step = 0; 16082 switch (curLevel) { 16083 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16084 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16085 break; 16086 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16087 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16088 break; 16089 } 16090 } 16091 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16092 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16093 && app.thread != null) { 16094 try { 16095 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16096 "Trimming memory of heavy-weight " + app.processName 16097 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16098 app.thread.scheduleTrimMemory( 16099 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16100 } catch (RemoteException e) { 16101 } 16102 } 16103 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16104 } else { 16105 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16106 || app.systemNoUi) && app.pendingUiClean) { 16107 // If this application is now in the background and it 16108 // had done UI, then give it the special trim level to 16109 // have it free UI resources. 16110 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16111 if (app.trimMemoryLevel < level && app.thread != null) { 16112 try { 16113 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16114 "Trimming memory of bg-ui " + app.processName 16115 + " to " + level); 16116 app.thread.scheduleTrimMemory(level); 16117 } catch (RemoteException e) { 16118 } 16119 } 16120 app.pendingUiClean = false; 16121 } 16122 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16123 try { 16124 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16125 "Trimming memory of fg " + app.processName 16126 + " to " + fgTrimLevel); 16127 app.thread.scheduleTrimMemory(fgTrimLevel); 16128 } catch (RemoteException e) { 16129 } 16130 } 16131 app.trimMemoryLevel = fgTrimLevel; 16132 } 16133 } 16134 } else { 16135 if (mLowRamStartTime != 0) { 16136 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16137 mLowRamStartTime = 0; 16138 } 16139 for (int i=N-1; i>=0; i--) { 16140 ProcessRecord app = mLruProcesses.get(i); 16141 if (allChanged || app.procStateChanged) { 16142 setProcessTrackerState(app, trackerMemFactor, now); 16143 app.procStateChanged = false; 16144 } 16145 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16146 || app.systemNoUi) && app.pendingUiClean) { 16147 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16148 && app.thread != null) { 16149 try { 16150 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16151 "Trimming memory of ui hidden " + app.processName 16152 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16153 app.thread.scheduleTrimMemory( 16154 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16155 } catch (RemoteException e) { 16156 } 16157 } 16158 app.pendingUiClean = false; 16159 } 16160 app.trimMemoryLevel = 0; 16161 } 16162 } 16163 16164 if (mAlwaysFinishActivities) { 16165 // Need to do this on its own message because the stack may not 16166 // be in a consistent state at this point. 16167 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16168 } 16169 16170 if (allChanged) { 16171 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16172 } 16173 16174 if (mProcessStats.shouldWriteNowLocked(now)) { 16175 mHandler.post(new Runnable() { 16176 @Override public void run() { 16177 synchronized (ActivityManagerService.this) { 16178 mProcessStats.writeStateAsyncLocked(); 16179 } 16180 } 16181 }); 16182 } 16183 16184 if (DEBUG_OOM_ADJ) { 16185 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16186 } 16187 } 16188 16189 final void trimApplications() { 16190 synchronized (this) { 16191 int i; 16192 16193 // First remove any unused application processes whose package 16194 // has been removed. 16195 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16196 final ProcessRecord app = mRemovedProcesses.get(i); 16197 if (app.activities.size() == 0 16198 && app.curReceiver == null && app.services.size() == 0) { 16199 Slog.i( 16200 TAG, "Exiting empty application process " 16201 + app.processName + " (" 16202 + (app.thread != null ? app.thread.asBinder() : null) 16203 + ")\n"); 16204 if (app.pid > 0 && app.pid != MY_PID) { 16205 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16206 app.processName, app.setAdj, "empty"); 16207 app.killedByAm = true; 16208 Process.killProcessQuiet(app.pid); 16209 } else { 16210 try { 16211 app.thread.scheduleExit(); 16212 } catch (Exception e) { 16213 // Ignore exceptions. 16214 } 16215 } 16216 cleanUpApplicationRecordLocked(app, false, true, -1); 16217 mRemovedProcesses.remove(i); 16218 16219 if (app.persistent) { 16220 if (app.persistent) { 16221 addAppLocked(app.info, false); 16222 } 16223 } 16224 } 16225 } 16226 16227 // Now update the oom adj for all processes. 16228 updateOomAdjLocked(); 16229 } 16230 } 16231 16232 /** This method sends the specified signal to each of the persistent apps */ 16233 public void signalPersistentProcesses(int sig) throws RemoteException { 16234 if (sig != Process.SIGNAL_USR1) { 16235 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16236 } 16237 16238 synchronized (this) { 16239 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16240 != PackageManager.PERMISSION_GRANTED) { 16241 throw new SecurityException("Requires permission " 16242 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16243 } 16244 16245 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16246 ProcessRecord r = mLruProcesses.get(i); 16247 if (r.thread != null && r.persistent) { 16248 Process.sendSignal(r.pid, sig); 16249 } 16250 } 16251 } 16252 } 16253 16254 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16255 if (proc == null || proc == mProfileProc) { 16256 proc = mProfileProc; 16257 path = mProfileFile; 16258 profileType = mProfileType; 16259 clearProfilerLocked(); 16260 } 16261 if (proc == null) { 16262 return; 16263 } 16264 try { 16265 proc.thread.profilerControl(false, path, null, profileType); 16266 } catch (RemoteException e) { 16267 throw new IllegalStateException("Process disappeared"); 16268 } 16269 } 16270 16271 private void clearProfilerLocked() { 16272 if (mProfileFd != null) { 16273 try { 16274 mProfileFd.close(); 16275 } catch (IOException e) { 16276 } 16277 } 16278 mProfileApp = null; 16279 mProfileProc = null; 16280 mProfileFile = null; 16281 mProfileType = 0; 16282 mAutoStopProfiler = false; 16283 } 16284 16285 public boolean profileControl(String process, int userId, boolean start, 16286 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16287 16288 try { 16289 synchronized (this) { 16290 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16291 // its own permission. 16292 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16293 != PackageManager.PERMISSION_GRANTED) { 16294 throw new SecurityException("Requires permission " 16295 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16296 } 16297 16298 if (start && fd == null) { 16299 throw new IllegalArgumentException("null fd"); 16300 } 16301 16302 ProcessRecord proc = null; 16303 if (process != null) { 16304 proc = findProcessLocked(process, userId, "profileControl"); 16305 } 16306 16307 if (start && (proc == null || proc.thread == null)) { 16308 throw new IllegalArgumentException("Unknown process: " + process); 16309 } 16310 16311 if (start) { 16312 stopProfilerLocked(null, null, 0); 16313 setProfileApp(proc.info, proc.processName, path, fd, false); 16314 mProfileProc = proc; 16315 mProfileType = profileType; 16316 try { 16317 fd = fd.dup(); 16318 } catch (IOException e) { 16319 fd = null; 16320 } 16321 proc.thread.profilerControl(start, path, fd, profileType); 16322 fd = null; 16323 mProfileFd = null; 16324 } else { 16325 stopProfilerLocked(proc, path, profileType); 16326 if (fd != null) { 16327 try { 16328 fd.close(); 16329 } catch (IOException e) { 16330 } 16331 } 16332 } 16333 16334 return true; 16335 } 16336 } catch (RemoteException e) { 16337 throw new IllegalStateException("Process disappeared"); 16338 } finally { 16339 if (fd != null) { 16340 try { 16341 fd.close(); 16342 } catch (IOException e) { 16343 } 16344 } 16345 } 16346 } 16347 16348 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16349 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16350 userId, true, true, callName, null); 16351 ProcessRecord proc = null; 16352 try { 16353 int pid = Integer.parseInt(process); 16354 synchronized (mPidsSelfLocked) { 16355 proc = mPidsSelfLocked.get(pid); 16356 } 16357 } catch (NumberFormatException e) { 16358 } 16359 16360 if (proc == null) { 16361 ArrayMap<String, SparseArray<ProcessRecord>> all 16362 = mProcessNames.getMap(); 16363 SparseArray<ProcessRecord> procs = all.get(process); 16364 if (procs != null && procs.size() > 0) { 16365 proc = procs.valueAt(0); 16366 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16367 for (int i=1; i<procs.size(); i++) { 16368 ProcessRecord thisProc = procs.valueAt(i); 16369 if (thisProc.userId == userId) { 16370 proc = thisProc; 16371 break; 16372 } 16373 } 16374 } 16375 } 16376 } 16377 16378 return proc; 16379 } 16380 16381 public boolean dumpHeap(String process, int userId, boolean managed, 16382 String path, ParcelFileDescriptor fd) throws RemoteException { 16383 16384 try { 16385 synchronized (this) { 16386 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16387 // its own permission (same as profileControl). 16388 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16389 != PackageManager.PERMISSION_GRANTED) { 16390 throw new SecurityException("Requires permission " 16391 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16392 } 16393 16394 if (fd == null) { 16395 throw new IllegalArgumentException("null fd"); 16396 } 16397 16398 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16399 if (proc == null || proc.thread == null) { 16400 throw new IllegalArgumentException("Unknown process: " + process); 16401 } 16402 16403 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16404 if (!isDebuggable) { 16405 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16406 throw new SecurityException("Process not debuggable: " + proc); 16407 } 16408 } 16409 16410 proc.thread.dumpHeap(managed, path, fd); 16411 fd = null; 16412 return true; 16413 } 16414 } catch (RemoteException e) { 16415 throw new IllegalStateException("Process disappeared"); 16416 } finally { 16417 if (fd != null) { 16418 try { 16419 fd.close(); 16420 } catch (IOException e) { 16421 } 16422 } 16423 } 16424 } 16425 16426 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16427 public void monitor() { 16428 synchronized (this) { } 16429 } 16430 16431 void onCoreSettingsChange(Bundle settings) { 16432 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16433 ProcessRecord processRecord = mLruProcesses.get(i); 16434 try { 16435 if (processRecord.thread != null) { 16436 processRecord.thread.setCoreSettings(settings); 16437 } 16438 } catch (RemoteException re) { 16439 /* ignore */ 16440 } 16441 } 16442 } 16443 16444 // Multi-user methods 16445 16446 /** 16447 * Start user, if its not already running, but don't bring it to foreground. 16448 */ 16449 @Override 16450 public boolean startUserInBackground(final int userId) { 16451 return startUser(userId, /* foreground */ false); 16452 } 16453 16454 /** 16455 * Refreshes the list of users related to the current user when either a 16456 * user switch happens or when a new related user is started in the 16457 * background. 16458 */ 16459 private void updateCurrentProfileIdsLocked() { 16460 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16461 mCurrentUserId, false /* enabledOnly */); 16462 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16463 for (int i = 0; i < currentProfileIds.length; i++) { 16464 currentProfileIds[i] = profiles.get(i).id; 16465 } 16466 mCurrentProfileIds = currentProfileIds; 16467 } 16468 16469 private Set getProfileIdsLocked(int userId) { 16470 Set userIds = new HashSet<Integer>(); 16471 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16472 userId, false /* enabledOnly */); 16473 for (UserInfo user : profiles) { 16474 userIds.add(Integer.valueOf(user.id)); 16475 } 16476 return userIds; 16477 } 16478 16479 @Override 16480 public boolean switchUser(final int userId) { 16481 return startUser(userId, /* foregound */ true); 16482 } 16483 16484 private boolean startUser(final int userId, boolean foreground) { 16485 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16486 != PackageManager.PERMISSION_GRANTED) { 16487 String msg = "Permission Denial: switchUser() from pid=" 16488 + Binder.getCallingPid() 16489 + ", uid=" + Binder.getCallingUid() 16490 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16491 Slog.w(TAG, msg); 16492 throw new SecurityException(msg); 16493 } 16494 16495 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16496 16497 final long ident = Binder.clearCallingIdentity(); 16498 try { 16499 synchronized (this) { 16500 final int oldUserId = mCurrentUserId; 16501 if (oldUserId == userId) { 16502 return true; 16503 } 16504 16505 mStackSupervisor.setLockTaskModeLocked(null); 16506 16507 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16508 if (userInfo == null) { 16509 Slog.w(TAG, "No user info for user #" + userId); 16510 return false; 16511 } 16512 16513 if (foreground) { 16514 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16515 R.anim.screen_user_enter); 16516 } 16517 16518 boolean needStart = false; 16519 16520 // If the user we are switching to is not currently started, then 16521 // we need to start it now. 16522 if (mStartedUsers.get(userId) == null) { 16523 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16524 updateStartedUserArrayLocked(); 16525 needStart = true; 16526 } 16527 16528 final Integer userIdInt = Integer.valueOf(userId); 16529 mUserLru.remove(userIdInt); 16530 mUserLru.add(userIdInt); 16531 16532 if (foreground) { 16533 mCurrentUserId = userId; 16534 updateCurrentProfileIdsLocked(); 16535 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16536 // Once the internal notion of the active user has switched, we lock the device 16537 // with the option to show the user switcher on the keyguard. 16538 mWindowManager.lockNow(null); 16539 } else { 16540 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16541 updateCurrentProfileIdsLocked(); 16542 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16543 mUserLru.remove(currentUserIdInt); 16544 mUserLru.add(currentUserIdInt); 16545 } 16546 16547 final UserStartedState uss = mStartedUsers.get(userId); 16548 16549 // Make sure user is in the started state. If it is currently 16550 // stopping, we need to knock that off. 16551 if (uss.mState == UserStartedState.STATE_STOPPING) { 16552 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16553 // so we can just fairly silently bring the user back from 16554 // the almost-dead. 16555 uss.mState = UserStartedState.STATE_RUNNING; 16556 updateStartedUserArrayLocked(); 16557 needStart = true; 16558 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16559 // This means ACTION_SHUTDOWN has been sent, so we will 16560 // need to treat this as a new boot of the user. 16561 uss.mState = UserStartedState.STATE_BOOTING; 16562 updateStartedUserArrayLocked(); 16563 needStart = true; 16564 } 16565 16566 if (uss.mState == UserStartedState.STATE_BOOTING) { 16567 // Booting up a new user, need to tell system services about it. 16568 // Note that this is on the same handler as scheduling of broadcasts, 16569 // which is important because it needs to go first. 16570 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16571 } 16572 16573 if (foreground) { 16574 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16575 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16576 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16577 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16578 oldUserId, userId, uss)); 16579 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16580 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16581 } 16582 16583 if (needStart) { 16584 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16585 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16586 | Intent.FLAG_RECEIVER_FOREGROUND); 16587 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16588 broadcastIntentLocked(null, null, intent, 16589 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16590 false, false, MY_PID, Process.SYSTEM_UID, userId); 16591 } 16592 16593 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16594 if (userId != UserHandle.USER_OWNER) { 16595 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16596 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16597 broadcastIntentLocked(null, null, intent, null, 16598 new IIntentReceiver.Stub() { 16599 public void performReceive(Intent intent, int resultCode, 16600 String data, Bundle extras, boolean ordered, 16601 boolean sticky, int sendingUser) { 16602 userInitialized(uss, userId); 16603 } 16604 }, 0, null, null, null, AppOpsManager.OP_NONE, 16605 true, false, MY_PID, Process.SYSTEM_UID, 16606 userId); 16607 uss.initializing = true; 16608 } else { 16609 getUserManagerLocked().makeInitialized(userInfo.id); 16610 } 16611 } 16612 16613 if (foreground) { 16614 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16615 if (homeInFront) { 16616 startHomeActivityLocked(userId); 16617 } else { 16618 mStackSupervisor.resumeTopActivitiesLocked(); 16619 } 16620 EventLogTags.writeAmSwitchUser(userId); 16621 getUserManagerLocked().userForeground(userId); 16622 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16623 } else { 16624 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16625 } 16626 16627 if (needStart) { 16628 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16630 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16631 broadcastIntentLocked(null, null, intent, 16632 null, new IIntentReceiver.Stub() { 16633 @Override 16634 public void performReceive(Intent intent, int resultCode, String data, 16635 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16636 throws RemoteException { 16637 } 16638 }, 0, null, null, 16639 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16640 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16641 } 16642 } 16643 } finally { 16644 Binder.restoreCallingIdentity(ident); 16645 } 16646 16647 return true; 16648 } 16649 16650 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16651 long ident = Binder.clearCallingIdentity(); 16652 try { 16653 Intent intent; 16654 if (oldUserId >= 0) { 16655 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16656 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16657 | Intent.FLAG_RECEIVER_FOREGROUND); 16658 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16659 broadcastIntentLocked(null, null, intent, 16660 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16661 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16662 } 16663 if (newUserId >= 0) { 16664 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16665 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16666 | Intent.FLAG_RECEIVER_FOREGROUND); 16667 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16668 broadcastIntentLocked(null, null, intent, 16669 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16670 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16671 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16672 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16673 | Intent.FLAG_RECEIVER_FOREGROUND); 16674 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16675 broadcastIntentLocked(null, null, intent, 16676 null, null, 0, null, null, 16677 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16678 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16679 } 16680 } finally { 16681 Binder.restoreCallingIdentity(ident); 16682 } 16683 } 16684 16685 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16686 final int newUserId) { 16687 final int N = mUserSwitchObservers.beginBroadcast(); 16688 if (N > 0) { 16689 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16690 int mCount = 0; 16691 @Override 16692 public void sendResult(Bundle data) throws RemoteException { 16693 synchronized (ActivityManagerService.this) { 16694 if (mCurUserSwitchCallback == this) { 16695 mCount++; 16696 if (mCount == N) { 16697 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16698 } 16699 } 16700 } 16701 } 16702 }; 16703 synchronized (this) { 16704 uss.switching = true; 16705 mCurUserSwitchCallback = callback; 16706 } 16707 for (int i=0; i<N; i++) { 16708 try { 16709 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16710 newUserId, callback); 16711 } catch (RemoteException e) { 16712 } 16713 } 16714 } else { 16715 synchronized (this) { 16716 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16717 } 16718 } 16719 mUserSwitchObservers.finishBroadcast(); 16720 } 16721 16722 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16723 synchronized (this) { 16724 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16725 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16726 } 16727 } 16728 16729 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16730 mCurUserSwitchCallback = null; 16731 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16732 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16733 oldUserId, newUserId, uss)); 16734 } 16735 16736 void userInitialized(UserStartedState uss, int newUserId) { 16737 completeSwitchAndInitalize(uss, newUserId, true, false); 16738 } 16739 16740 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16741 completeSwitchAndInitalize(uss, newUserId, false, true); 16742 } 16743 16744 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16745 boolean clearInitializing, boolean clearSwitching) { 16746 boolean unfrozen = false; 16747 synchronized (this) { 16748 if (clearInitializing) { 16749 uss.initializing = false; 16750 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16751 } 16752 if (clearSwitching) { 16753 uss.switching = false; 16754 } 16755 if (!uss.switching && !uss.initializing) { 16756 mWindowManager.stopFreezingScreen(); 16757 unfrozen = true; 16758 } 16759 } 16760 if (unfrozen) { 16761 final int N = mUserSwitchObservers.beginBroadcast(); 16762 for (int i=0; i<N; i++) { 16763 try { 16764 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16765 } catch (RemoteException e) { 16766 } 16767 } 16768 mUserSwitchObservers.finishBroadcast(); 16769 } 16770 } 16771 16772 void scheduleStartProfilesLocked() { 16773 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16774 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16775 DateUtils.SECOND_IN_MILLIS); 16776 } 16777 } 16778 16779 void startProfilesLocked() { 16780 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16781 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16782 mCurrentUserId, false /* enabledOnly */); 16783 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16784 for (UserInfo user : profiles) { 16785 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16786 && user.id != mCurrentUserId) { 16787 toStart.add(user); 16788 } 16789 } 16790 final int n = toStart.size(); 16791 int i = 0; 16792 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16793 startUserInBackground(toStart.get(i).id); 16794 } 16795 if (i < n) { 16796 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16797 } 16798 } 16799 16800 void finishUserBoot(UserStartedState uss) { 16801 synchronized (this) { 16802 if (uss.mState == UserStartedState.STATE_BOOTING 16803 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16804 uss.mState = UserStartedState.STATE_RUNNING; 16805 final int userId = uss.mHandle.getIdentifier(); 16806 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16807 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16808 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16809 broadcastIntentLocked(null, null, intent, 16810 null, null, 0, null, null, 16811 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16812 true, false, MY_PID, Process.SYSTEM_UID, userId); 16813 } 16814 } 16815 } 16816 16817 void finishUserSwitch(UserStartedState uss) { 16818 synchronized (this) { 16819 finishUserBoot(uss); 16820 16821 startProfilesLocked(); 16822 16823 int num = mUserLru.size(); 16824 int i = 0; 16825 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16826 Integer oldUserId = mUserLru.get(i); 16827 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16828 if (oldUss == null) { 16829 // Shouldn't happen, but be sane if it does. 16830 mUserLru.remove(i); 16831 num--; 16832 continue; 16833 } 16834 if (oldUss.mState == UserStartedState.STATE_STOPPING 16835 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16836 // This user is already stopping, doesn't count. 16837 num--; 16838 i++; 16839 continue; 16840 } 16841 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16842 // Owner and current can't be stopped, but count as running. 16843 i++; 16844 continue; 16845 } 16846 // This is a user to be stopped. 16847 stopUserLocked(oldUserId, null); 16848 num--; 16849 i++; 16850 } 16851 } 16852 } 16853 16854 @Override 16855 public int stopUser(final int userId, final IStopUserCallback callback) { 16856 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16857 != PackageManager.PERMISSION_GRANTED) { 16858 String msg = "Permission Denial: switchUser() from pid=" 16859 + Binder.getCallingPid() 16860 + ", uid=" + Binder.getCallingUid() 16861 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16862 Slog.w(TAG, msg); 16863 throw new SecurityException(msg); 16864 } 16865 if (userId <= 0) { 16866 throw new IllegalArgumentException("Can't stop primary user " + userId); 16867 } 16868 synchronized (this) { 16869 return stopUserLocked(userId, callback); 16870 } 16871 } 16872 16873 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16874 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16875 if (mCurrentUserId == userId) { 16876 return ActivityManager.USER_OP_IS_CURRENT; 16877 } 16878 16879 final UserStartedState uss = mStartedUsers.get(userId); 16880 if (uss == null) { 16881 // User is not started, nothing to do... but we do need to 16882 // callback if requested. 16883 if (callback != null) { 16884 mHandler.post(new Runnable() { 16885 @Override 16886 public void run() { 16887 try { 16888 callback.userStopped(userId); 16889 } catch (RemoteException e) { 16890 } 16891 } 16892 }); 16893 } 16894 return ActivityManager.USER_OP_SUCCESS; 16895 } 16896 16897 if (callback != null) { 16898 uss.mStopCallbacks.add(callback); 16899 } 16900 16901 if (uss.mState != UserStartedState.STATE_STOPPING 16902 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16903 uss.mState = UserStartedState.STATE_STOPPING; 16904 updateStartedUserArrayLocked(); 16905 16906 long ident = Binder.clearCallingIdentity(); 16907 try { 16908 // We are going to broadcast ACTION_USER_STOPPING and then 16909 // once that is done send a final ACTION_SHUTDOWN and then 16910 // stop the user. 16911 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16912 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16913 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16914 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16915 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16916 // This is the result receiver for the final shutdown broadcast. 16917 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16918 @Override 16919 public void performReceive(Intent intent, int resultCode, String data, 16920 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16921 finishUserStop(uss); 16922 } 16923 }; 16924 // This is the result receiver for the initial stopping broadcast. 16925 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16926 @Override 16927 public void performReceive(Intent intent, int resultCode, String data, 16928 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16929 // On to the next. 16930 synchronized (ActivityManagerService.this) { 16931 if (uss.mState != UserStartedState.STATE_STOPPING) { 16932 // Whoops, we are being started back up. Abort, abort! 16933 return; 16934 } 16935 uss.mState = UserStartedState.STATE_SHUTDOWN; 16936 } 16937 mSystemServiceManager.stopUser(userId); 16938 broadcastIntentLocked(null, null, shutdownIntent, 16939 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16940 true, false, MY_PID, Process.SYSTEM_UID, userId); 16941 } 16942 }; 16943 // Kick things off. 16944 broadcastIntentLocked(null, null, stoppingIntent, 16945 null, stoppingReceiver, 0, null, null, 16946 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16947 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16948 } finally { 16949 Binder.restoreCallingIdentity(ident); 16950 } 16951 } 16952 16953 return ActivityManager.USER_OP_SUCCESS; 16954 } 16955 16956 void finishUserStop(UserStartedState uss) { 16957 final int userId = uss.mHandle.getIdentifier(); 16958 boolean stopped; 16959 ArrayList<IStopUserCallback> callbacks; 16960 synchronized (this) { 16961 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16962 if (mStartedUsers.get(userId) != uss) { 16963 stopped = false; 16964 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16965 stopped = false; 16966 } else { 16967 stopped = true; 16968 // User can no longer run. 16969 mStartedUsers.remove(userId); 16970 mUserLru.remove(Integer.valueOf(userId)); 16971 updateStartedUserArrayLocked(); 16972 16973 // Clean up all state and processes associated with the user. 16974 // Kill all the processes for the user. 16975 forceStopUserLocked(userId, "finish user"); 16976 } 16977 } 16978 16979 for (int i=0; i<callbacks.size(); i++) { 16980 try { 16981 if (stopped) callbacks.get(i).userStopped(userId); 16982 else callbacks.get(i).userStopAborted(userId); 16983 } catch (RemoteException e) { 16984 } 16985 } 16986 16987 if (stopped) { 16988 mSystemServiceManager.cleanupUser(userId); 16989 synchronized (this) { 16990 mStackSupervisor.removeUserLocked(userId); 16991 } 16992 } 16993 } 16994 16995 @Override 16996 public UserInfo getCurrentUser() { 16997 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16998 != PackageManager.PERMISSION_GRANTED) && ( 16999 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17000 != PackageManager.PERMISSION_GRANTED)) { 17001 String msg = "Permission Denial: getCurrentUser() from pid=" 17002 + Binder.getCallingPid() 17003 + ", uid=" + Binder.getCallingUid() 17004 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17005 Slog.w(TAG, msg); 17006 throw new SecurityException(msg); 17007 } 17008 synchronized (this) { 17009 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17010 } 17011 } 17012 17013 int getCurrentUserIdLocked() { 17014 return mCurrentUserId; 17015 } 17016 17017 @Override 17018 public boolean isUserRunning(int userId, boolean orStopped) { 17019 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17020 != PackageManager.PERMISSION_GRANTED) { 17021 String msg = "Permission Denial: isUserRunning() from pid=" 17022 + Binder.getCallingPid() 17023 + ", uid=" + Binder.getCallingUid() 17024 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17025 Slog.w(TAG, msg); 17026 throw new SecurityException(msg); 17027 } 17028 synchronized (this) { 17029 return isUserRunningLocked(userId, orStopped); 17030 } 17031 } 17032 17033 boolean isUserRunningLocked(int userId, boolean orStopped) { 17034 UserStartedState state = mStartedUsers.get(userId); 17035 if (state == null) { 17036 return false; 17037 } 17038 if (orStopped) { 17039 return true; 17040 } 17041 return state.mState != UserStartedState.STATE_STOPPING 17042 && state.mState != UserStartedState.STATE_SHUTDOWN; 17043 } 17044 17045 @Override 17046 public int[] getRunningUserIds() { 17047 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17048 != PackageManager.PERMISSION_GRANTED) { 17049 String msg = "Permission Denial: isUserRunning() from pid=" 17050 + Binder.getCallingPid() 17051 + ", uid=" + Binder.getCallingUid() 17052 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17053 Slog.w(TAG, msg); 17054 throw new SecurityException(msg); 17055 } 17056 synchronized (this) { 17057 return mStartedUserArray; 17058 } 17059 } 17060 17061 private void updateStartedUserArrayLocked() { 17062 int num = 0; 17063 for (int i=0; i<mStartedUsers.size(); i++) { 17064 UserStartedState uss = mStartedUsers.valueAt(i); 17065 // This list does not include stopping users. 17066 if (uss.mState != UserStartedState.STATE_STOPPING 17067 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17068 num++; 17069 } 17070 } 17071 mStartedUserArray = new int[num]; 17072 num = 0; 17073 for (int i=0; i<mStartedUsers.size(); i++) { 17074 UserStartedState uss = mStartedUsers.valueAt(i); 17075 if (uss.mState != UserStartedState.STATE_STOPPING 17076 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17077 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17078 num++; 17079 } 17080 } 17081 } 17082 17083 @Override 17084 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17085 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17086 != PackageManager.PERMISSION_GRANTED) { 17087 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17088 + Binder.getCallingPid() 17089 + ", uid=" + Binder.getCallingUid() 17090 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17091 Slog.w(TAG, msg); 17092 throw new SecurityException(msg); 17093 } 17094 17095 mUserSwitchObservers.register(observer); 17096 } 17097 17098 @Override 17099 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17100 mUserSwitchObservers.unregister(observer); 17101 } 17102 17103 private boolean userExists(int userId) { 17104 if (userId == 0) { 17105 return true; 17106 } 17107 UserManagerService ums = getUserManagerLocked(); 17108 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17109 } 17110 17111 int[] getUsersLocked() { 17112 UserManagerService ums = getUserManagerLocked(); 17113 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17114 } 17115 17116 UserManagerService getUserManagerLocked() { 17117 if (mUserManager == null) { 17118 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17119 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17120 } 17121 return mUserManager; 17122 } 17123 17124 private int applyUserId(int uid, int userId) { 17125 return UserHandle.getUid(userId, uid); 17126 } 17127 17128 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17129 if (info == null) return null; 17130 ApplicationInfo newInfo = new ApplicationInfo(info); 17131 newInfo.uid = applyUserId(info.uid, userId); 17132 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17133 + info.packageName; 17134 return newInfo; 17135 } 17136 17137 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17138 if (aInfo == null 17139 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17140 return aInfo; 17141 } 17142 17143 ActivityInfo info = new ActivityInfo(aInfo); 17144 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17145 return info; 17146 } 17147 17148 private final class LocalService extends ActivityManagerInternal { 17149 @Override 17150 public void goingToSleep() { 17151 ActivityManagerService.this.goingToSleep(); 17152 } 17153 17154 @Override 17155 public void wakingUp() { 17156 ActivityManagerService.this.wakingUp(); 17157 } 17158 } 17159} 17160