ActivityManagerService.java revision 41cd577c12a3525663101ff9217ded509bb869d6
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.net.Proxy; 142import android.net.ProxyInfo; 143import android.net.Uri; 144import android.os.Binder; 145import android.os.Build; 146import android.os.Bundle; 147import android.os.Debug; 148import android.os.DropBoxManager; 149import android.os.Environment; 150import android.os.FactoryTest; 151import android.os.FileObserver; 152import android.os.FileUtils; 153import android.os.Handler; 154import android.os.IBinder; 155import android.os.IPermissionController; 156import android.os.IRemoteCallback; 157import android.os.IUserManager; 158import android.os.Looper; 159import android.os.Message; 160import android.os.Parcel; 161import android.os.ParcelFileDescriptor; 162import android.os.Process; 163import android.os.RemoteCallbackList; 164import android.os.RemoteException; 165import android.os.SELinux; 166import android.os.ServiceManager; 167import android.os.StrictMode; 168import android.os.SystemClock; 169import android.os.SystemProperties; 170import android.os.UpdateLock; 171import android.os.UserHandle; 172import android.provider.Settings; 173import android.text.format.DateUtils; 174import android.text.format.Time; 175import android.util.AtomicFile; 176import android.util.EventLog; 177import android.util.Log; 178import android.util.Pair; 179import android.util.PrintWriterPrinter; 180import android.util.Slog; 181import android.util.SparseArray; 182import android.util.TimeUtils; 183import android.util.Xml; 184import android.view.Gravity; 185import android.view.LayoutInflater; 186import android.view.View; 187import android.view.WindowManager; 188 189import java.io.BufferedInputStream; 190import java.io.BufferedOutputStream; 191import java.io.DataInputStream; 192import java.io.DataOutputStream; 193import java.io.File; 194import java.io.FileDescriptor; 195import java.io.FileInputStream; 196import java.io.FileNotFoundException; 197import java.io.FileOutputStream; 198import java.io.IOException; 199import java.io.InputStreamReader; 200import java.io.PrintWriter; 201import java.io.StringWriter; 202import java.lang.ref.WeakReference; 203import java.util.ArrayList; 204import java.util.Arrays; 205import java.util.Collections; 206import java.util.Comparator; 207import java.util.HashMap; 208import java.util.HashSet; 209import java.util.Iterator; 210import java.util.List; 211import java.util.Locale; 212import java.util.Map; 213import java.util.Set; 214import java.util.concurrent.atomic.AtomicBoolean; 215import java.util.concurrent.atomic.AtomicLong; 216 217public final class ActivityManagerService extends ActivityManagerNative 218 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 219 private static final String USER_DATA_DIR = "/data/user/"; 220 static final String TAG = "ActivityManager"; 221 static final String TAG_MU = "ActivityManagerServiceMU"; 222 static final boolean DEBUG = false; 223 static final boolean localLOGV = DEBUG; 224 static final boolean DEBUG_BACKUP = localLOGV || false; 225 static final boolean DEBUG_BROADCAST = localLOGV || false; 226 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_CLEANUP = localLOGV || false; 229 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 230 static final boolean DEBUG_FOCUS = false; 231 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 232 static final boolean DEBUG_MU = localLOGV || false; 233 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 234 static final boolean DEBUG_LRU = localLOGV || false; 235 static final boolean DEBUG_PAUSE = localLOGV || false; 236 static final boolean DEBUG_POWER = localLOGV || false; 237 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 238 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 239 static final boolean DEBUG_PROCESSES = localLOGV || false; 240 static final boolean DEBUG_PROVIDER = localLOGV || false; 241 static final boolean DEBUG_RESULTS = localLOGV || false; 242 static final boolean DEBUG_SERVICE = localLOGV || false; 243 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 244 static final boolean DEBUG_STACK = localLOGV || false; 245 static final boolean DEBUG_SWITCH = localLOGV || false; 246 static final boolean DEBUG_TASKS = localLOGV || false; 247 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 248 static final boolean DEBUG_TRANSITION = localLOGV || false; 249 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 250 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 251 static final boolean DEBUG_VISBILITY = localLOGV || false; 252 static final boolean DEBUG_PSS = localLOGV || false; 253 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 254 static final boolean VALIDATE_TOKENS = false; 255 static final boolean SHOW_ACTIVITY_START_TIME = true; 256 257 // Control over CPU and battery monitoring. 258 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 259 static final boolean MONITOR_CPU_USAGE = true; 260 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 261 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 262 static final boolean MONITOR_THREAD_CPU_USAGE = false; 263 264 // The flags that are set for all calls we make to the package manager. 265 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 266 267 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 268 269 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 270 271 // Maximum number of recent tasks that we can remember. 272 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 273 274 // Maximum number recent bitmaps to keep in memory. 275 static final int MAX_RECENT_BITMAPS = 5; 276 277 // Amount of time after a call to stopAppSwitches() during which we will 278 // prevent further untrusted switches from happening. 279 static final long APP_SWITCH_DELAY_TIME = 5*1000; 280 281 // How long we wait for a launched process to attach to the activity manager 282 // before we decide it's never going to come up for real. 283 static final int PROC_START_TIMEOUT = 10*1000; 284 285 // How long we wait for a launched process to attach to the activity manager 286 // before we decide it's never going to come up for real, when the process was 287 // started with a wrapper for instrumentation (such as Valgrind) because it 288 // could take much longer than usual. 289 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 290 291 // How long to wait after going idle before forcing apps to GC. 292 static final int GC_TIMEOUT = 5*1000; 293 294 // The minimum amount of time between successive GC requests for a process. 295 static final int GC_MIN_INTERVAL = 60*1000; 296 297 // The minimum amount of time between successive PSS requests for a process. 298 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 299 300 // The minimum amount of time between successive PSS requests for a process 301 // when the request is due to the memory state being lowered. 302 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 303 304 // The rate at which we check for apps using excessive power -- 15 mins. 305 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 306 307 // The minimum sample duration we will allow before deciding we have 308 // enough data on wake locks to start killing things. 309 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 310 311 // The minimum sample duration we will allow before deciding we have 312 // enough data on CPU usage to start killing things. 313 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 314 315 // How long we allow a receiver to run before giving up on it. 316 static final int BROADCAST_FG_TIMEOUT = 10*1000; 317 static final int BROADCAST_BG_TIMEOUT = 60*1000; 318 319 // How long we wait until we timeout on key dispatching. 320 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 321 322 // How long we wait until we timeout on key dispatching during instrumentation. 323 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 324 325 // Amount of time we wait for observers to handle a user switch before 326 // giving up on them and unfreezing the screen. 327 static final int USER_SWITCH_TIMEOUT = 2*1000; 328 329 // Maximum number of users we allow to be running at a time. 330 static final int MAX_RUNNING_USERS = 3; 331 332 // How long to wait in getAssistContextExtras for the activity and foreground services 333 // to respond with the result. 334 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 335 336 // Maximum number of persisted Uri grants a package is allowed 337 static final int MAX_PERSISTED_URI_GRANTS = 128; 338 339 static final int MY_PID = Process.myPid(); 340 341 static final String[] EMPTY_STRING_ARRAY = new String[0]; 342 343 // How many bytes to write into the dropbox log before truncating 344 static final int DROPBOX_MAX_SIZE = 256 * 1024; 345 346 /** All system services */ 347 SystemServiceManager mSystemServiceManager; 348 349 /** Run all ActivityStacks through this */ 350 ActivityStackSupervisor mStackSupervisor; 351 352 public IntentFirewall mIntentFirewall; 353 354 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 355 // default actuion automatically. Important for devices without direct input 356 // devices. 357 private boolean mShowDialogs = true; 358 359 /** 360 * Description of a request to start a new activity, which has been held 361 * due to app switches being disabled. 362 */ 363 static class PendingActivityLaunch { 364 final ActivityRecord r; 365 final ActivityRecord sourceRecord; 366 final int startFlags; 367 final ActivityStack stack; 368 369 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 370 int _startFlags, ActivityStack _stack) { 371 r = _r; 372 sourceRecord = _sourceRecord; 373 startFlags = _startFlags; 374 stack = _stack; 375 } 376 } 377 378 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 379 = new ArrayList<PendingActivityLaunch>(); 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 417 public class PendingAssistExtras extends Binder implements Runnable { 418 public final ActivityRecord activity; 419 public boolean haveResult = false; 420 public Bundle result = null; 421 public PendingAssistExtras(ActivityRecord _activity) { 422 activity = _activity; 423 } 424 @Override 425 public void run() { 426 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 427 synchronized (this) { 428 haveResult = true; 429 notifyAll(); 430 } 431 } 432 } 433 434 final ArrayList<PendingAssistExtras> mPendingAssistExtras 435 = new ArrayList<PendingAssistExtras>(); 436 437 /** 438 * Process management. 439 */ 440 final ProcessList mProcessList = new ProcessList(); 441 442 /** 443 * All of the applications we currently have running organized by name. 444 * The keys are strings of the application package name (as 445 * returned by the package manager), and the keys are ApplicationRecord 446 * objects. 447 */ 448 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 449 450 /** 451 * Tracking long-term execution of processes to look for abuse and other 452 * bad app behavior. 453 */ 454 final ProcessStatsService mProcessStats; 455 456 /** 457 * The currently running isolated processes. 458 */ 459 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 460 461 /** 462 * Counter for assigning isolated process uids, to avoid frequently reusing the 463 * same ones. 464 */ 465 int mNextIsolatedProcessUid = 0; 466 467 /** 468 * The currently running heavy-weight process, if any. 469 */ 470 ProcessRecord mHeavyWeightProcess = null; 471 472 /** 473 * The last time that various processes have crashed. 474 */ 475 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 476 477 /** 478 * Information about a process that is currently marked as bad. 479 */ 480 static final class BadProcessInfo { 481 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 482 this.time = time; 483 this.shortMsg = shortMsg; 484 this.longMsg = longMsg; 485 this.stack = stack; 486 } 487 488 final long time; 489 final String shortMsg; 490 final String longMsg; 491 final String stack; 492 } 493 494 /** 495 * Set of applications that we consider to be bad, and will reject 496 * incoming broadcasts from (which the user has no control over). 497 * Processes are added to this set when they have crashed twice within 498 * a minimum amount of time; they are removed from it when they are 499 * later restarted (hopefully due to some user action). The value is the 500 * time it was added to the list. 501 */ 502 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 503 504 /** 505 * All of the processes we currently have running organized by pid. 506 * The keys are the pid running the application. 507 * 508 * <p>NOTE: This object is protected by its own lock, NOT the global 509 * activity manager lock! 510 */ 511 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 512 513 /** 514 * All of the processes that have been forced to be foreground. The key 515 * is the pid of the caller who requested it (we hold a death 516 * link on it). 517 */ 518 abstract class ForegroundToken implements IBinder.DeathRecipient { 519 int pid; 520 IBinder token; 521 } 522 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 523 524 /** 525 * List of records for processes that someone had tried to start before the 526 * system was ready. We don't start them at that point, but ensure they 527 * are started by the time booting is complete. 528 */ 529 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 530 531 /** 532 * List of persistent applications that are in the process 533 * of being started. 534 */ 535 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * Processes that are being forcibly torn down. 539 */ 540 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * List of running applications, sorted by recent usage. 544 * The first entry in the list is the least recently used. 545 */ 546 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Where in mLruProcesses that the processes hosting activities start. 550 */ 551 int mLruProcessActivityStart = 0; 552 553 /** 554 * Where in mLruProcesses that the processes hosting services start. 555 * This is after (lower index) than mLruProcessesActivityStart. 556 */ 557 int mLruProcessServiceStart = 0; 558 559 /** 560 * List of processes that should gc as soon as things are idle. 561 */ 562 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes we want to collect PSS data from. 566 */ 567 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * Last time we requested PSS data of all processes. 571 */ 572 long mLastFullPssTime = SystemClock.uptimeMillis(); 573 574 /** 575 * If set, the next time we collect PSS data we should do a full collection 576 * with data from native processes and the kernel. 577 */ 578 boolean mFullPssPending = false; 579 580 /** 581 * This is the process holding what we currently consider to be 582 * the "home" activity. 583 */ 584 ProcessRecord mHomeProcess; 585 586 /** 587 * This is the process holding the activity the user last visited that 588 * is in a different process from the one they are currently in. 589 */ 590 ProcessRecord mPreviousProcess; 591 592 /** 593 * The time at which the previous process was last visible. 594 */ 595 long mPreviousProcessVisibleTime; 596 597 /** 598 * Which uses have been started, so are allowed to run code. 599 */ 600 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 601 602 /** 603 * LRU list of history of current users. Most recently current is at the end. 604 */ 605 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 606 607 /** 608 * Constant array of the users that are currently started. 609 */ 610 int[] mStartedUserArray = new int[] { 0 }; 611 612 /** 613 * Registered observers of the user switching mechanics. 614 */ 615 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 616 = new RemoteCallbackList<IUserSwitchObserver>(); 617 618 /** 619 * Currently active user switch. 620 */ 621 Object mCurUserSwitchCallback; 622 623 /** 624 * Packages that the user has asked to have run in screen size 625 * compatibility mode instead of filling the screen. 626 */ 627 final CompatModePackages mCompatModePackages; 628 629 /** 630 * Set of IntentSenderRecord objects that are currently active. 631 */ 632 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 633 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 634 635 /** 636 * Fingerprints (hashCode()) of stack traces that we've 637 * already logged DropBox entries for. Guarded by itself. If 638 * something (rogue user app) forces this over 639 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 640 */ 641 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 642 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 643 644 /** 645 * Strict Mode background batched logging state. 646 * 647 * The string buffer is guarded by itself, and its lock is also 648 * used to determine if another batched write is already 649 * in-flight. 650 */ 651 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 652 653 /** 654 * Keeps track of all IIntentReceivers that have been registered for 655 * broadcasts. Hash keys are the receiver IBinder, hash value is 656 * a ReceiverList. 657 */ 658 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 659 new HashMap<IBinder, ReceiverList>(); 660 661 /** 662 * Resolver for broadcast intents to registered receivers. 663 * Holds BroadcastFilter (subclass of IntentFilter). 664 */ 665 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 666 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 667 @Override 668 protected boolean allowFilterResult( 669 BroadcastFilter filter, List<BroadcastFilter> dest) { 670 IBinder target = filter.receiverList.receiver.asBinder(); 671 for (int i=dest.size()-1; i>=0; i--) { 672 if (dest.get(i).receiverList.receiver.asBinder() == target) { 673 return false; 674 } 675 } 676 return true; 677 } 678 679 @Override 680 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 681 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 682 || userId == filter.owningUserId) { 683 return super.newResult(filter, match, userId); 684 } 685 return null; 686 } 687 688 @Override 689 protected BroadcastFilter[] newArray(int size) { 690 return new BroadcastFilter[size]; 691 } 692 693 @Override 694 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 695 return packageName.equals(filter.packageName); 696 } 697 }; 698 699 /** 700 * State of all active sticky broadcasts per user. Keys are the action of the 701 * sticky Intent, values are an ArrayList of all broadcasted intents with 702 * that action (which should usually be one). The SparseArray is keyed 703 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 704 * for stickies that are sent to all users. 705 */ 706 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 707 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 708 709 final ActiveServices mServices; 710 711 /** 712 * Backup/restore process management 713 */ 714 String mBackupAppName = null; 715 BackupRecord mBackupTarget = null; 716 717 final ProviderMap mProviderMap; 718 719 /** 720 * List of content providers who have clients waiting for them. The 721 * application is currently being launched and the provider will be 722 * removed from this list once it is published. 723 */ 724 final ArrayList<ContentProviderRecord> mLaunchingProviders 725 = new ArrayList<ContentProviderRecord>(); 726 727 /** 728 * File storing persisted {@link #mGrantedUriPermissions}. 729 */ 730 private final AtomicFile mGrantFile; 731 732 /** XML constants used in {@link #mGrantFile} */ 733 private static final String TAG_URI_GRANTS = "uri-grants"; 734 private static final String TAG_URI_GRANT = "uri-grant"; 735 private static final String ATTR_USER_HANDLE = "userHandle"; 736 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 737 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 738 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 739 private static final String ATTR_TARGET_PKG = "targetPkg"; 740 private static final String ATTR_URI = "uri"; 741 private static final String ATTR_MODE_FLAGS = "modeFlags"; 742 private static final String ATTR_CREATED_TIME = "createdTime"; 743 private static final String ATTR_PREFIX = "prefix"; 744 745 /** 746 * Global set of specific {@link Uri} permissions that have been granted. 747 * This optimized lookup structure maps from {@link UriPermission#targetUid} 748 * to {@link UriPermission#uri} to {@link UriPermission}. 749 */ 750 @GuardedBy("this") 751 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 752 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 753 754 public static class GrantUri { 755 public final int sourceUserId; 756 public final Uri uri; 757 public boolean prefix; 758 759 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 760 this.sourceUserId = sourceUserId; 761 this.uri = uri; 762 this.prefix = prefix; 763 } 764 765 @Override 766 public int hashCode() { 767 return toString().hashCode(); 768 } 769 770 @Override 771 public boolean equals(Object o) { 772 if (o instanceof GrantUri) { 773 GrantUri other = (GrantUri) o; 774 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 775 && prefix == other.prefix; 776 } 777 return false; 778 } 779 780 @Override 781 public String toString() { 782 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 783 if (prefix) result += " [prefix]"; 784 return result; 785 } 786 787 public String toSafeString() { 788 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 789 if (prefix) result += " [prefix]"; 790 return result; 791 } 792 793 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 794 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 795 ContentProvider.getUriWithoutUserId(uri), false); 796 } 797 } 798 799 CoreSettingsObserver mCoreSettingsObserver; 800 801 /** 802 * Thread-local storage used to carry caller permissions over through 803 * indirect content-provider access. 804 */ 805 private class Identity { 806 public int pid; 807 public int uid; 808 809 Identity(int _pid, int _uid) { 810 pid = _pid; 811 uid = _uid; 812 } 813 } 814 815 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 816 817 /** 818 * All information we have collected about the runtime performance of 819 * any user id that can impact battery performance. 820 */ 821 final BatteryStatsService mBatteryStatsService; 822 823 /** 824 * Information about component usage 825 */ 826 final UsageStatsService mUsageStatsService; 827 828 /** 829 * Information about and control over application operations 830 */ 831 final AppOpsService mAppOpsService; 832 833 /** 834 * Save recent tasks information across reboots. 835 */ 836 final TaskPersister mTaskPersister; 837 838 /** 839 * Current configuration information. HistoryRecord objects are given 840 * a reference to this object to indicate which configuration they are 841 * currently running in, so this object must be kept immutable. 842 */ 843 Configuration mConfiguration = new Configuration(); 844 845 /** 846 * Current sequencing integer of the configuration, for skipping old 847 * configurations. 848 */ 849 int mConfigurationSeq = 0; 850 851 /** 852 * Hardware-reported OpenGLES version. 853 */ 854 final int GL_ES_VERSION; 855 856 /** 857 * List of initialization arguments to pass to all processes when binding applications to them. 858 * For example, references to the commonly used services. 859 */ 860 HashMap<String, IBinder> mAppBindArgs; 861 862 /** 863 * Temporary to avoid allocations. Protected by main lock. 864 */ 865 final StringBuilder mStringBuilder = new StringBuilder(256); 866 867 /** 868 * Used to control how we initialize the service. 869 */ 870 ComponentName mTopComponent; 871 String mTopAction = Intent.ACTION_MAIN; 872 String mTopData; 873 boolean mProcessesReady = false; 874 boolean mSystemReady = false; 875 boolean mBooting = false; 876 boolean mWaitingUpdate = false; 877 boolean mDidUpdate = false; 878 boolean mOnBattery = false; 879 boolean mLaunchWarningShown = false; 880 881 Context mContext; 882 883 int mFactoryTest; 884 885 boolean mCheckedForSetup; 886 887 /** 888 * The time at which we will allow normal application switches again, 889 * after a call to {@link #stopAppSwitches()}. 890 */ 891 long mAppSwitchesAllowedTime; 892 893 /** 894 * This is set to true after the first switch after mAppSwitchesAllowedTime 895 * is set; any switches after that will clear the time. 896 */ 897 boolean mDidAppSwitch; 898 899 /** 900 * Last time (in realtime) at which we checked for power usage. 901 */ 902 long mLastPowerCheckRealtime; 903 904 /** 905 * Last time (in uptime) at which we checked for power usage. 906 */ 907 long mLastPowerCheckUptime; 908 909 /** 910 * Set while we are wanting to sleep, to prevent any 911 * activities from being started/resumed. 912 */ 913 private boolean mSleeping = false; 914 915 /** 916 * Set while we are running a voice interaction. This overrides 917 * sleeping while it is active. 918 */ 919 private boolean mRunningVoice = false; 920 921 /** 922 * State of external calls telling us if the device is asleep. 923 */ 924 private boolean mWentToSleep = false; 925 926 /** 927 * State of external call telling us if the lock screen is shown. 928 */ 929 private boolean mLockScreenShown = false; 930 931 /** 932 * Set if we are shutting down the system, similar to sleeping. 933 */ 934 boolean mShuttingDown = false; 935 936 /** 937 * Current sequence id for oom_adj computation traversal. 938 */ 939 int mAdjSeq = 0; 940 941 /** 942 * Current sequence id for process LRU updating. 943 */ 944 int mLruSeq = 0; 945 946 /** 947 * Keep track of the non-cached/empty process we last found, to help 948 * determine how to distribute cached/empty processes next time. 949 */ 950 int mNumNonCachedProcs = 0; 951 952 /** 953 * Keep track of the number of cached hidden procs, to balance oom adj 954 * distribution between those and empty procs. 955 */ 956 int mNumCachedHiddenProcs = 0; 957 958 /** 959 * Keep track of the number of service processes we last found, to 960 * determine on the next iteration which should be B services. 961 */ 962 int mNumServiceProcs = 0; 963 int mNewNumAServiceProcs = 0; 964 int mNewNumServiceProcs = 0; 965 966 /** 967 * Allow the current computed overall memory level of the system to go down? 968 * This is set to false when we are killing processes for reasons other than 969 * memory management, so that the now smaller process list will not be taken as 970 * an indication that memory is tighter. 971 */ 972 boolean mAllowLowerMemLevel = false; 973 974 /** 975 * The last computed memory level, for holding when we are in a state that 976 * processes are going away for other reasons. 977 */ 978 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 979 980 /** 981 * The last total number of process we have, to determine if changes actually look 982 * like a shrinking number of process due to lower RAM. 983 */ 984 int mLastNumProcesses; 985 986 /** 987 * The uptime of the last time we performed idle maintenance. 988 */ 989 long mLastIdleTime = SystemClock.uptimeMillis(); 990 991 /** 992 * Total time spent with RAM that has been added in the past since the last idle time. 993 */ 994 long mLowRamTimeSinceLastIdle = 0; 995 996 /** 997 * If RAM is currently low, when that horrible situation started. 998 */ 999 long mLowRamStartTime = 0; 1000 1001 /** 1002 * For reporting to battery stats the current top application. 1003 */ 1004 private String mCurResumedPackage = null; 1005 private int mCurResumedUid = -1; 1006 1007 /** 1008 * For reporting to battery stats the apps currently running foreground 1009 * service. The ProcessMap is package/uid tuples; each of these contain 1010 * an array of the currently foreground processes. 1011 */ 1012 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1013 = new ProcessMap<ArrayList<ProcessRecord>>(); 1014 1015 /** 1016 * This is set if we had to do a delayed dexopt of an app before launching 1017 * it, to increase the ANR timeouts in that case. 1018 */ 1019 boolean mDidDexOpt; 1020 1021 /** 1022 * Set if the systemServer made a call to enterSafeMode. 1023 */ 1024 boolean mSafeMode; 1025 1026 String mDebugApp = null; 1027 boolean mWaitForDebugger = false; 1028 boolean mDebugTransient = false; 1029 String mOrigDebugApp = null; 1030 boolean mOrigWaitForDebugger = false; 1031 boolean mAlwaysFinishActivities = false; 1032 IActivityController mController = null; 1033 String mProfileApp = null; 1034 ProcessRecord mProfileProc = null; 1035 String mProfileFile; 1036 ParcelFileDescriptor mProfileFd; 1037 int mProfileType = 0; 1038 boolean mAutoStopProfiler = false; 1039 String mOpenGlTraceApp = null; 1040 1041 static class ProcessChangeItem { 1042 static final int CHANGE_ACTIVITIES = 1<<0; 1043 static final int CHANGE_PROCESS_STATE = 1<<1; 1044 int changes; 1045 int uid; 1046 int pid; 1047 int processState; 1048 boolean foregroundActivities; 1049 } 1050 1051 final RemoteCallbackList<IProcessObserver> mProcessObservers 1052 = new RemoteCallbackList<IProcessObserver>(); 1053 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1054 1055 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1056 = new ArrayList<ProcessChangeItem>(); 1057 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1058 = new ArrayList<ProcessChangeItem>(); 1059 1060 /** 1061 * Runtime CPU use collection thread. This object's lock is used to 1062 * protect all related state. 1063 */ 1064 final Thread mProcessCpuThread; 1065 1066 /** 1067 * Used to collect process stats when showing not responding dialog. 1068 * Protected by mProcessCpuThread. 1069 */ 1070 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1071 MONITOR_THREAD_CPU_USAGE); 1072 final AtomicLong mLastCpuTime = new AtomicLong(0); 1073 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1074 1075 long mLastWriteTime = 0; 1076 1077 /** 1078 * Used to retain an update lock when the foreground activity is in 1079 * immersive mode. 1080 */ 1081 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1082 1083 /** 1084 * Set to true after the system has finished booting. 1085 */ 1086 boolean mBooted = false; 1087 1088 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1089 int mProcessLimitOverride = -1; 1090 1091 WindowManagerService mWindowManager; 1092 1093 final ActivityThread mSystemThread; 1094 1095 int mCurrentUserId = 0; 1096 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1097 private UserManagerService mUserManager; 1098 1099 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1100 final ProcessRecord mApp; 1101 final int mPid; 1102 final IApplicationThread mAppThread; 1103 1104 AppDeathRecipient(ProcessRecord app, int pid, 1105 IApplicationThread thread) { 1106 if (localLOGV) Slog.v( 1107 TAG, "New death recipient " + this 1108 + " for thread " + thread.asBinder()); 1109 mApp = app; 1110 mPid = pid; 1111 mAppThread = thread; 1112 } 1113 1114 @Override 1115 public void binderDied() { 1116 if (localLOGV) Slog.v( 1117 TAG, "Death received in " + this 1118 + " for thread " + mAppThread.asBinder()); 1119 synchronized(ActivityManagerService.this) { 1120 appDiedLocked(mApp, mPid, mAppThread); 1121 } 1122 } 1123 } 1124 1125 static final int SHOW_ERROR_MSG = 1; 1126 static final int SHOW_NOT_RESPONDING_MSG = 2; 1127 static final int SHOW_FACTORY_ERROR_MSG = 3; 1128 static final int UPDATE_CONFIGURATION_MSG = 4; 1129 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1130 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1131 static final int SERVICE_TIMEOUT_MSG = 12; 1132 static final int UPDATE_TIME_ZONE = 13; 1133 static final int SHOW_UID_ERROR_MSG = 14; 1134 static final int IM_FEELING_LUCKY_MSG = 15; 1135 static final int PROC_START_TIMEOUT_MSG = 20; 1136 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1137 static final int KILL_APPLICATION_MSG = 22; 1138 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1139 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1140 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1141 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1142 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1143 static final int CLEAR_DNS_CACHE_MSG = 28; 1144 static final int UPDATE_HTTP_PROXY_MSG = 29; 1145 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1146 static final int DISPATCH_PROCESSES_CHANGED = 31; 1147 static final int DISPATCH_PROCESS_DIED = 32; 1148 static final int REPORT_MEM_USAGE_MSG = 33; 1149 static final int REPORT_USER_SWITCH_MSG = 34; 1150 static final int CONTINUE_USER_SWITCH_MSG = 35; 1151 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1152 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1153 static final int PERSIST_URI_GRANTS_MSG = 38; 1154 static final int REQUEST_ALL_PSS_MSG = 39; 1155 static final int START_PROFILES_MSG = 40; 1156 static final int UPDATE_TIME = 41; 1157 static final int SYSTEM_USER_START_MSG = 42; 1158 static final int SYSTEM_USER_CURRENT_MSG = 43; 1159 1160 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1161 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1162 static final int FIRST_COMPAT_MODE_MSG = 300; 1163 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1164 1165 AlertDialog mUidAlert; 1166 CompatModeDialog mCompatModeDialog; 1167 long mLastMemUsageReportTime = 0; 1168 1169 private LockToAppRequestDialog mLockToAppRequest; 1170 1171 /** 1172 * Flag whether the current user is a "monkey", i.e. whether 1173 * the UI is driven by a UI automation tool. 1174 */ 1175 private boolean mUserIsMonkey; 1176 1177 final ServiceThread mHandlerThread; 1178 final MainHandler mHandler; 1179 1180 final class MainHandler extends Handler { 1181 public MainHandler(Looper looper) { 1182 super(looper, null, true); 1183 } 1184 1185 @Override 1186 public void handleMessage(Message msg) { 1187 switch (msg.what) { 1188 case SHOW_ERROR_MSG: { 1189 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1190 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1191 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1192 synchronized (ActivityManagerService.this) { 1193 ProcessRecord proc = (ProcessRecord)data.get("app"); 1194 AppErrorResult res = (AppErrorResult) data.get("result"); 1195 if (proc != null && proc.crashDialog != null) { 1196 Slog.e(TAG, "App already has crash dialog: " + proc); 1197 if (res != null) { 1198 res.set(0); 1199 } 1200 return; 1201 } 1202 if (!showBackground && UserHandle.getAppId(proc.uid) 1203 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1204 && proc.pid != MY_PID) { 1205 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1206 if (res != null) { 1207 res.set(0); 1208 } 1209 return; 1210 } 1211 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1212 Dialog d = new AppErrorDialog(mContext, 1213 ActivityManagerService.this, res, proc); 1214 d.show(); 1215 proc.crashDialog = d; 1216 } else { 1217 // The device is asleep, so just pretend that the user 1218 // saw a crash dialog and hit "force quit". 1219 if (res != null) { 1220 res.set(0); 1221 } 1222 } 1223 } 1224 1225 ensureBootCompleted(); 1226 } break; 1227 case SHOW_NOT_RESPONDING_MSG: { 1228 synchronized (ActivityManagerService.this) { 1229 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1230 ProcessRecord proc = (ProcessRecord)data.get("app"); 1231 if (proc != null && proc.anrDialog != null) { 1232 Slog.e(TAG, "App already has anr dialog: " + proc); 1233 return; 1234 } 1235 1236 Intent intent = new Intent("android.intent.action.ANR"); 1237 if (!mProcessesReady) { 1238 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1239 | Intent.FLAG_RECEIVER_FOREGROUND); 1240 } 1241 broadcastIntentLocked(null, null, intent, 1242 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1243 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1244 1245 if (mShowDialogs) { 1246 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1247 mContext, proc, (ActivityRecord)data.get("activity"), 1248 msg.arg1 != 0); 1249 d.show(); 1250 proc.anrDialog = d; 1251 } else { 1252 // Just kill the app if there is no dialog to be shown. 1253 killAppAtUsersRequest(proc, null); 1254 } 1255 } 1256 1257 ensureBootCompleted(); 1258 } break; 1259 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1260 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1261 synchronized (ActivityManagerService.this) { 1262 ProcessRecord proc = (ProcessRecord) data.get("app"); 1263 if (proc == null) { 1264 Slog.e(TAG, "App not found when showing strict mode dialog."); 1265 break; 1266 } 1267 if (proc.crashDialog != null) { 1268 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1269 return; 1270 } 1271 AppErrorResult res = (AppErrorResult) data.get("result"); 1272 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1273 Dialog d = new StrictModeViolationDialog(mContext, 1274 ActivityManagerService.this, res, proc); 1275 d.show(); 1276 proc.crashDialog = d; 1277 } else { 1278 // The device is asleep, so just pretend that the user 1279 // saw a crash dialog and hit "force quit". 1280 res.set(0); 1281 } 1282 } 1283 ensureBootCompleted(); 1284 } break; 1285 case SHOW_FACTORY_ERROR_MSG: { 1286 Dialog d = new FactoryErrorDialog( 1287 mContext, msg.getData().getCharSequence("msg")); 1288 d.show(); 1289 ensureBootCompleted(); 1290 } break; 1291 case UPDATE_CONFIGURATION_MSG: { 1292 final ContentResolver resolver = mContext.getContentResolver(); 1293 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1294 } break; 1295 case GC_BACKGROUND_PROCESSES_MSG: { 1296 synchronized (ActivityManagerService.this) { 1297 performAppGcsIfAppropriateLocked(); 1298 } 1299 } break; 1300 case WAIT_FOR_DEBUGGER_MSG: { 1301 synchronized (ActivityManagerService.this) { 1302 ProcessRecord app = (ProcessRecord)msg.obj; 1303 if (msg.arg1 != 0) { 1304 if (!app.waitedForDebugger) { 1305 Dialog d = new AppWaitingForDebuggerDialog( 1306 ActivityManagerService.this, 1307 mContext, app); 1308 app.waitDialog = d; 1309 app.waitedForDebugger = true; 1310 d.show(); 1311 } 1312 } else { 1313 if (app.waitDialog != null) { 1314 app.waitDialog.dismiss(); 1315 app.waitDialog = null; 1316 } 1317 } 1318 } 1319 } break; 1320 case SERVICE_TIMEOUT_MSG: { 1321 if (mDidDexOpt) { 1322 mDidDexOpt = false; 1323 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1324 nmsg.obj = msg.obj; 1325 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1326 return; 1327 } 1328 mServices.serviceTimeout((ProcessRecord)msg.obj); 1329 } break; 1330 case UPDATE_TIME_ZONE: { 1331 synchronized (ActivityManagerService.this) { 1332 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1333 ProcessRecord r = mLruProcesses.get(i); 1334 if (r.thread != null) { 1335 try { 1336 r.thread.updateTimeZone(); 1337 } catch (RemoteException ex) { 1338 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1339 } 1340 } 1341 } 1342 } 1343 } break; 1344 case CLEAR_DNS_CACHE_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1347 ProcessRecord r = mLruProcesses.get(i); 1348 if (r.thread != null) { 1349 try { 1350 r.thread.clearDnsCache(); 1351 } catch (RemoteException ex) { 1352 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1353 } 1354 } 1355 } 1356 } 1357 } break; 1358 case UPDATE_HTTP_PROXY_MSG: { 1359 ProxyInfo proxy = (ProxyInfo)msg.obj; 1360 String host = ""; 1361 String port = ""; 1362 String exclList = ""; 1363 Uri pacFileUrl = Uri.EMPTY; 1364 if (proxy != null) { 1365 host = proxy.getHost(); 1366 port = Integer.toString(proxy.getPort()); 1367 exclList = proxy.getExclusionListAsString(); 1368 pacFileUrl = proxy.getPacFileUrl(); 1369 } 1370 synchronized (ActivityManagerService.this) { 1371 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1372 ProcessRecord r = mLruProcesses.get(i); 1373 if (r.thread != null) { 1374 try { 1375 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1376 } catch (RemoteException ex) { 1377 Slog.w(TAG, "Failed to update http proxy for: " + 1378 r.info.processName); 1379 } 1380 } 1381 } 1382 } 1383 } break; 1384 case SHOW_UID_ERROR_MSG: { 1385 String title = "System UIDs Inconsistent"; 1386 String text = "UIDs on the system are inconsistent, you need to wipe your" 1387 + " data partition or your device will be unstable."; 1388 Log.e(TAG, title + ": " + text); 1389 if (mShowDialogs) { 1390 // XXX This is a temporary dialog, no need to localize. 1391 AlertDialog d = new BaseErrorDialog(mContext); 1392 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1393 d.setCancelable(false); 1394 d.setTitle(title); 1395 d.setMessage(text); 1396 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1397 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1398 mUidAlert = d; 1399 d.show(); 1400 } 1401 } break; 1402 case IM_FEELING_LUCKY_MSG: { 1403 if (mUidAlert != null) { 1404 mUidAlert.dismiss(); 1405 mUidAlert = null; 1406 } 1407 } break; 1408 case PROC_START_TIMEOUT_MSG: { 1409 if (mDidDexOpt) { 1410 mDidDexOpt = false; 1411 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1412 nmsg.obj = msg.obj; 1413 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1414 return; 1415 } 1416 ProcessRecord app = (ProcessRecord)msg.obj; 1417 synchronized (ActivityManagerService.this) { 1418 processStartTimedOutLocked(app); 1419 } 1420 } break; 1421 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1422 synchronized (ActivityManagerService.this) { 1423 doPendingActivityLaunchesLocked(true); 1424 } 1425 } break; 1426 case KILL_APPLICATION_MSG: { 1427 synchronized (ActivityManagerService.this) { 1428 int appid = msg.arg1; 1429 boolean restart = (msg.arg2 == 1); 1430 Bundle bundle = (Bundle)msg.obj; 1431 String pkg = bundle.getString("pkg"); 1432 String reason = bundle.getString("reason"); 1433 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1434 false, UserHandle.USER_ALL, reason); 1435 } 1436 } break; 1437 case FINALIZE_PENDING_INTENT_MSG: { 1438 ((PendingIntentRecord)msg.obj).completeFinalize(); 1439 } break; 1440 case POST_HEAVY_NOTIFICATION_MSG: { 1441 INotificationManager inm = NotificationManager.getService(); 1442 if (inm == null) { 1443 return; 1444 } 1445 1446 ActivityRecord root = (ActivityRecord)msg.obj; 1447 ProcessRecord process = root.app; 1448 if (process == null) { 1449 return; 1450 } 1451 1452 try { 1453 Context context = mContext.createPackageContext(process.info.packageName, 0); 1454 String text = mContext.getString(R.string.heavy_weight_notification, 1455 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1456 Notification notification = new Notification(); 1457 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1458 notification.when = 0; 1459 notification.flags = Notification.FLAG_ONGOING_EVENT; 1460 notification.tickerText = text; 1461 notification.defaults = 0; // please be quiet 1462 notification.sound = null; 1463 notification.vibrate = null; 1464 notification.setLatestEventInfo(context, text, 1465 mContext.getText(R.string.heavy_weight_notification_detail), 1466 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1467 PendingIntent.FLAG_CANCEL_CURRENT, null, 1468 new UserHandle(root.userId))); 1469 1470 try { 1471 int[] outId = new int[1]; 1472 inm.enqueueNotificationWithTag("android", "android", null, 1473 R.string.heavy_weight_notification, 1474 notification, outId, root.userId); 1475 } catch (RuntimeException e) { 1476 Slog.w(ActivityManagerService.TAG, 1477 "Error showing notification for heavy-weight app", e); 1478 } catch (RemoteException e) { 1479 } 1480 } catch (NameNotFoundException e) { 1481 Slog.w(TAG, "Unable to create context for heavy notification", e); 1482 } 1483 } break; 1484 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1485 INotificationManager inm = NotificationManager.getService(); 1486 if (inm == null) { 1487 return; 1488 } 1489 try { 1490 inm.cancelNotificationWithTag("android", null, 1491 R.string.heavy_weight_notification, msg.arg1); 1492 } catch (RuntimeException e) { 1493 Slog.w(ActivityManagerService.TAG, 1494 "Error canceling notification for service", e); 1495 } catch (RemoteException e) { 1496 } 1497 } break; 1498 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1499 synchronized (ActivityManagerService.this) { 1500 checkExcessivePowerUsageLocked(true); 1501 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1502 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1503 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1504 } 1505 } break; 1506 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1507 synchronized (ActivityManagerService.this) { 1508 ActivityRecord ar = (ActivityRecord)msg.obj; 1509 if (mCompatModeDialog != null) { 1510 if (mCompatModeDialog.mAppInfo.packageName.equals( 1511 ar.info.applicationInfo.packageName)) { 1512 return; 1513 } 1514 mCompatModeDialog.dismiss(); 1515 mCompatModeDialog = null; 1516 } 1517 if (ar != null && false) { 1518 if (mCompatModePackages.getPackageAskCompatModeLocked( 1519 ar.packageName)) { 1520 int mode = mCompatModePackages.computeCompatModeLocked( 1521 ar.info.applicationInfo); 1522 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1523 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1524 mCompatModeDialog = new CompatModeDialog( 1525 ActivityManagerService.this, mContext, 1526 ar.info.applicationInfo); 1527 mCompatModeDialog.show(); 1528 } 1529 } 1530 } 1531 } 1532 break; 1533 } 1534 case DISPATCH_PROCESSES_CHANGED: { 1535 dispatchProcessesChanged(); 1536 break; 1537 } 1538 case DISPATCH_PROCESS_DIED: { 1539 final int pid = msg.arg1; 1540 final int uid = msg.arg2; 1541 dispatchProcessDied(pid, uid); 1542 break; 1543 } 1544 case REPORT_MEM_USAGE_MSG: { 1545 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1546 Thread thread = new Thread() { 1547 @Override public void run() { 1548 final SparseArray<ProcessMemInfo> infoMap 1549 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1550 for (int i=0, N=memInfos.size(); i<N; i++) { 1551 ProcessMemInfo mi = memInfos.get(i); 1552 infoMap.put(mi.pid, mi); 1553 } 1554 updateCpuStatsNow(); 1555 synchronized (mProcessCpuThread) { 1556 final int N = mProcessCpuTracker.countStats(); 1557 for (int i=0; i<N; i++) { 1558 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1559 if (st.vsize > 0) { 1560 long pss = Debug.getPss(st.pid, null); 1561 if (pss > 0) { 1562 if (infoMap.indexOfKey(st.pid) < 0) { 1563 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1564 ProcessList.NATIVE_ADJ, -1, "native", null); 1565 mi.pss = pss; 1566 memInfos.add(mi); 1567 } 1568 } 1569 } 1570 } 1571 } 1572 1573 long totalPss = 0; 1574 for (int i=0, N=memInfos.size(); i<N; i++) { 1575 ProcessMemInfo mi = memInfos.get(i); 1576 if (mi.pss == 0) { 1577 mi.pss = Debug.getPss(mi.pid, null); 1578 } 1579 totalPss += mi.pss; 1580 } 1581 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1582 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1583 if (lhs.oomAdj != rhs.oomAdj) { 1584 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1585 } 1586 if (lhs.pss != rhs.pss) { 1587 return lhs.pss < rhs.pss ? 1 : -1; 1588 } 1589 return 0; 1590 } 1591 }); 1592 1593 StringBuilder tag = new StringBuilder(128); 1594 StringBuilder stack = new StringBuilder(128); 1595 tag.append("Low on memory -- "); 1596 appendMemBucket(tag, totalPss, "total", false); 1597 appendMemBucket(stack, totalPss, "total", true); 1598 1599 StringBuilder logBuilder = new StringBuilder(1024); 1600 logBuilder.append("Low on memory:\n"); 1601 1602 boolean firstLine = true; 1603 int lastOomAdj = Integer.MIN_VALUE; 1604 for (int i=0, N=memInfos.size(); i<N; i++) { 1605 ProcessMemInfo mi = memInfos.get(i); 1606 1607 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1608 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1609 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1610 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1611 if (lastOomAdj != mi.oomAdj) { 1612 lastOomAdj = mi.oomAdj; 1613 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1614 tag.append(" / "); 1615 } 1616 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1617 if (firstLine) { 1618 stack.append(":"); 1619 firstLine = false; 1620 } 1621 stack.append("\n\t at "); 1622 } else { 1623 stack.append("$"); 1624 } 1625 } else { 1626 tag.append(" "); 1627 stack.append("$"); 1628 } 1629 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1630 appendMemBucket(tag, mi.pss, mi.name, false); 1631 } 1632 appendMemBucket(stack, mi.pss, mi.name, true); 1633 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1634 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1635 stack.append("("); 1636 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1637 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1638 stack.append(DUMP_MEM_OOM_LABEL[k]); 1639 stack.append(":"); 1640 stack.append(DUMP_MEM_OOM_ADJ[k]); 1641 } 1642 } 1643 stack.append(")"); 1644 } 1645 } 1646 1647 logBuilder.append(" "); 1648 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1649 logBuilder.append(' '); 1650 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1651 logBuilder.append(' '); 1652 ProcessList.appendRamKb(logBuilder, mi.pss); 1653 logBuilder.append(" kB: "); 1654 logBuilder.append(mi.name); 1655 logBuilder.append(" ("); 1656 logBuilder.append(mi.pid); 1657 logBuilder.append(") "); 1658 logBuilder.append(mi.adjType); 1659 logBuilder.append('\n'); 1660 if (mi.adjReason != null) { 1661 logBuilder.append(" "); 1662 logBuilder.append(mi.adjReason); 1663 logBuilder.append('\n'); 1664 } 1665 } 1666 1667 logBuilder.append(" "); 1668 ProcessList.appendRamKb(logBuilder, totalPss); 1669 logBuilder.append(" kB: TOTAL\n"); 1670 1671 long[] infos = new long[Debug.MEMINFO_COUNT]; 1672 Debug.getMemInfo(infos); 1673 logBuilder.append(" MemInfo: "); 1674 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1675 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1676 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1677 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1678 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1679 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1680 logBuilder.append(" ZRAM: "); 1681 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1682 logBuilder.append(" kB RAM, "); 1683 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1684 logBuilder.append(" kB swap total, "); 1685 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1686 logBuilder.append(" kB swap free\n"); 1687 } 1688 Slog.i(TAG, logBuilder.toString()); 1689 1690 StringBuilder dropBuilder = new StringBuilder(1024); 1691 /* 1692 StringWriter oomSw = new StringWriter(); 1693 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1694 StringWriter catSw = new StringWriter(); 1695 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1696 String[] emptyArgs = new String[] { }; 1697 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1698 oomPw.flush(); 1699 String oomString = oomSw.toString(); 1700 */ 1701 dropBuilder.append(stack); 1702 dropBuilder.append('\n'); 1703 dropBuilder.append('\n'); 1704 dropBuilder.append(logBuilder); 1705 dropBuilder.append('\n'); 1706 /* 1707 dropBuilder.append(oomString); 1708 dropBuilder.append('\n'); 1709 */ 1710 StringWriter catSw = new StringWriter(); 1711 synchronized (ActivityManagerService.this) { 1712 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1713 String[] emptyArgs = new String[] { }; 1714 catPw.println(); 1715 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1716 catPw.println(); 1717 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1718 false, false, null); 1719 catPw.println(); 1720 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1721 catPw.flush(); 1722 } 1723 dropBuilder.append(catSw.toString()); 1724 addErrorToDropBox("lowmem", null, "system_server", null, 1725 null, tag.toString(), dropBuilder.toString(), null, null); 1726 //Slog.i(TAG, "Sent to dropbox:"); 1727 //Slog.i(TAG, dropBuilder.toString()); 1728 synchronized (ActivityManagerService.this) { 1729 long now = SystemClock.uptimeMillis(); 1730 if (mLastMemUsageReportTime < now) { 1731 mLastMemUsageReportTime = now; 1732 } 1733 } 1734 } 1735 }; 1736 thread.start(); 1737 break; 1738 } 1739 case REPORT_USER_SWITCH_MSG: { 1740 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1741 break; 1742 } 1743 case CONTINUE_USER_SWITCH_MSG: { 1744 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1745 break; 1746 } 1747 case USER_SWITCH_TIMEOUT_MSG: { 1748 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1749 break; 1750 } 1751 case IMMERSIVE_MODE_LOCK_MSG: { 1752 final boolean nextState = (msg.arg1 != 0); 1753 if (mUpdateLock.isHeld() != nextState) { 1754 if (DEBUG_IMMERSIVE) { 1755 final ActivityRecord r = (ActivityRecord) msg.obj; 1756 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1757 } 1758 if (nextState) { 1759 mUpdateLock.acquire(); 1760 } else { 1761 mUpdateLock.release(); 1762 } 1763 } 1764 break; 1765 } 1766 case PERSIST_URI_GRANTS_MSG: { 1767 writeGrantedUriPermissions(); 1768 break; 1769 } 1770 case REQUEST_ALL_PSS_MSG: { 1771 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1772 break; 1773 } 1774 case START_PROFILES_MSG: { 1775 synchronized (ActivityManagerService.this) { 1776 startProfilesLocked(); 1777 } 1778 break; 1779 } 1780 case UPDATE_TIME: { 1781 synchronized (ActivityManagerService.this) { 1782 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1783 ProcessRecord r = mLruProcesses.get(i); 1784 if (r.thread != null) { 1785 try { 1786 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1787 } catch (RemoteException ex) { 1788 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1789 } 1790 } 1791 } 1792 } 1793 break; 1794 } 1795 case SYSTEM_USER_START_MSG: { 1796 mSystemServiceManager.startUser(msg.arg1); 1797 break; 1798 } 1799 case SYSTEM_USER_CURRENT_MSG: { 1800 mSystemServiceManager.switchUser(msg.arg1); 1801 break; 1802 } 1803 } 1804 } 1805 }; 1806 1807 static final int COLLECT_PSS_BG_MSG = 1; 1808 1809 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1810 @Override 1811 public void handleMessage(Message msg) { 1812 switch (msg.what) { 1813 case COLLECT_PSS_BG_MSG: { 1814 long start = SystemClock.uptimeMillis(); 1815 MemInfoReader memInfo = null; 1816 synchronized (ActivityManagerService.this) { 1817 if (mFullPssPending) { 1818 mFullPssPending = false; 1819 memInfo = new MemInfoReader(); 1820 } 1821 } 1822 if (memInfo != null) { 1823 updateCpuStatsNow(); 1824 long nativeTotalPss = 0; 1825 synchronized (mProcessCpuThread) { 1826 final int N = mProcessCpuTracker.countStats(); 1827 for (int j=0; j<N; j++) { 1828 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1829 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1830 // This is definitely an application process; skip it. 1831 continue; 1832 } 1833 synchronized (mPidsSelfLocked) { 1834 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1835 // This is one of our own processes; skip it. 1836 continue; 1837 } 1838 } 1839 nativeTotalPss += Debug.getPss(st.pid, null); 1840 } 1841 } 1842 memInfo.readMemInfo(); 1843 synchronized (this) { 1844 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1845 + (SystemClock.uptimeMillis()-start) + "ms"); 1846 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1847 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1848 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1849 +memInfo.getSlabSizeKb(), 1850 nativeTotalPss); 1851 } 1852 } 1853 1854 int i=0, num=0; 1855 long[] tmp = new long[1]; 1856 do { 1857 ProcessRecord proc; 1858 int procState; 1859 int pid; 1860 synchronized (ActivityManagerService.this) { 1861 if (i >= mPendingPssProcesses.size()) { 1862 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1863 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1864 mPendingPssProcesses.clear(); 1865 return; 1866 } 1867 proc = mPendingPssProcesses.get(i); 1868 procState = proc.pssProcState; 1869 if (proc.thread != null && procState == proc.setProcState) { 1870 pid = proc.pid; 1871 } else { 1872 proc = null; 1873 pid = 0; 1874 } 1875 i++; 1876 } 1877 if (proc != null) { 1878 long pss = Debug.getPss(pid, tmp); 1879 synchronized (ActivityManagerService.this) { 1880 if (proc.thread != null && proc.setProcState == procState 1881 && proc.pid == pid) { 1882 num++; 1883 proc.lastPssTime = SystemClock.uptimeMillis(); 1884 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1885 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1886 + ": " + pss + " lastPss=" + proc.lastPss 1887 + " state=" + ProcessList.makeProcStateString(procState)); 1888 if (proc.initialIdlePss == 0) { 1889 proc.initialIdlePss = pss; 1890 } 1891 proc.lastPss = pss; 1892 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1893 proc.lastCachedPss = pss; 1894 } 1895 } 1896 } 1897 } 1898 } while (true); 1899 } 1900 } 1901 } 1902 }; 1903 1904 /** 1905 * Monitor for package changes and update our internal state. 1906 */ 1907 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1908 @Override 1909 public void onPackageRemoved(String packageName, int uid) { 1910 // Remove all tasks with activities in the specified package from the list of recent tasks 1911 synchronized (ActivityManagerService.this) { 1912 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1913 TaskRecord tr = mRecentTasks.get(i); 1914 ComponentName cn = tr.intent.getComponent(); 1915 if (cn != null && cn.getPackageName().equals(packageName)) { 1916 // If the package name matches, remove the task and kill the process 1917 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1918 } 1919 } 1920 } 1921 } 1922 1923 @Override 1924 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1925 onPackageModified(packageName); 1926 return true; 1927 } 1928 1929 @Override 1930 public void onPackageModified(String packageName) { 1931 final PackageManager pm = mContext.getPackageManager(); 1932 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1933 new ArrayList<Pair<Intent, Integer>>(); 1934 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1935 // Copy the list of recent tasks so that we don't hold onto the lock on 1936 // ActivityManagerService for long periods while checking if components exist. 1937 synchronized (ActivityManagerService.this) { 1938 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1939 TaskRecord tr = mRecentTasks.get(i); 1940 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1941 } 1942 } 1943 // Check the recent tasks and filter out all tasks with components that no longer exist. 1944 Intent tmpI = new Intent(); 1945 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1946 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1947 ComponentName cn = p.first.getComponent(); 1948 if (cn != null && cn.getPackageName().equals(packageName)) { 1949 try { 1950 // Add the task to the list to remove if the component no longer exists 1951 tmpI.setComponent(cn); 1952 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1953 tasksToRemove.add(p.second); 1954 } 1955 } catch (Exception e) {} 1956 } 1957 } 1958 // Prune all the tasks with removed components from the list of recent tasks 1959 synchronized (ActivityManagerService.this) { 1960 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1961 // Remove the task but don't kill the process (since other components in that 1962 // package may still be running and in the background) 1963 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1964 } 1965 } 1966 } 1967 1968 @Override 1969 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1970 // Force stop the specified packages 1971 if (packages != null) { 1972 for (String pkg : packages) { 1973 synchronized (ActivityManagerService.this) { 1974 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1975 "finished booting")) { 1976 return true; 1977 } 1978 } 1979 } 1980 } 1981 return false; 1982 } 1983 }; 1984 1985 public void setSystemProcess() { 1986 try { 1987 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1988 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1989 ServiceManager.addService("meminfo", new MemBinder(this)); 1990 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1991 ServiceManager.addService("dbinfo", new DbBinder(this)); 1992 if (MONITOR_CPU_USAGE) { 1993 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1994 } 1995 ServiceManager.addService("permission", new PermissionController(this)); 1996 1997 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1998 "android", STOCK_PM_FLAGS); 1999 mSystemThread.installSystemApplicationInfo(info); 2000 2001 synchronized (this) { 2002 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2003 app.persistent = true; 2004 app.pid = MY_PID; 2005 app.maxAdj = ProcessList.SYSTEM_ADJ; 2006 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2007 mProcessNames.put(app.processName, app.uid, app); 2008 synchronized (mPidsSelfLocked) { 2009 mPidsSelfLocked.put(app.pid, app); 2010 } 2011 updateLruProcessLocked(app, false, null); 2012 updateOomAdjLocked(); 2013 } 2014 } catch (PackageManager.NameNotFoundException e) { 2015 throw new RuntimeException( 2016 "Unable to find android system package", e); 2017 } 2018 } 2019 2020 public void setWindowManager(WindowManagerService wm) { 2021 mWindowManager = wm; 2022 mStackSupervisor.setWindowManager(wm); 2023 } 2024 2025 public void startObservingNativeCrashes() { 2026 final NativeCrashListener ncl = new NativeCrashListener(this); 2027 ncl.start(); 2028 } 2029 2030 public IAppOpsService getAppOpsService() { 2031 return mAppOpsService; 2032 } 2033 2034 static class MemBinder extends Binder { 2035 ActivityManagerService mActivityManagerService; 2036 MemBinder(ActivityManagerService activityManagerService) { 2037 mActivityManagerService = activityManagerService; 2038 } 2039 2040 @Override 2041 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2042 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2043 != PackageManager.PERMISSION_GRANTED) { 2044 pw.println("Permission Denial: can't dump meminfo from from pid=" 2045 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2046 + " without permission " + android.Manifest.permission.DUMP); 2047 return; 2048 } 2049 2050 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2051 } 2052 } 2053 2054 static class GraphicsBinder extends Binder { 2055 ActivityManagerService mActivityManagerService; 2056 GraphicsBinder(ActivityManagerService activityManagerService) { 2057 mActivityManagerService = activityManagerService; 2058 } 2059 2060 @Override 2061 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2062 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2063 != PackageManager.PERMISSION_GRANTED) { 2064 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2065 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2066 + " without permission " + android.Manifest.permission.DUMP); 2067 return; 2068 } 2069 2070 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2071 } 2072 } 2073 2074 static class DbBinder extends Binder { 2075 ActivityManagerService mActivityManagerService; 2076 DbBinder(ActivityManagerService activityManagerService) { 2077 mActivityManagerService = activityManagerService; 2078 } 2079 2080 @Override 2081 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2082 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2083 != PackageManager.PERMISSION_GRANTED) { 2084 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2085 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2086 + " without permission " + android.Manifest.permission.DUMP); 2087 return; 2088 } 2089 2090 mActivityManagerService.dumpDbInfo(fd, pw, args); 2091 } 2092 } 2093 2094 static class CpuBinder extends Binder { 2095 ActivityManagerService mActivityManagerService; 2096 CpuBinder(ActivityManagerService activityManagerService) { 2097 mActivityManagerService = activityManagerService; 2098 } 2099 2100 @Override 2101 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2102 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2103 != PackageManager.PERMISSION_GRANTED) { 2104 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2105 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2106 + " without permission " + android.Manifest.permission.DUMP); 2107 return; 2108 } 2109 2110 synchronized (mActivityManagerService.mProcessCpuThread) { 2111 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2112 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2113 SystemClock.uptimeMillis())); 2114 } 2115 } 2116 } 2117 2118 public static final class Lifecycle extends SystemService { 2119 private final ActivityManagerService mService; 2120 2121 public Lifecycle(Context context) { 2122 super(context); 2123 mService = new ActivityManagerService(context); 2124 } 2125 2126 @Override 2127 public void onStart() { 2128 mService.start(); 2129 } 2130 2131 public ActivityManagerService getService() { 2132 return mService; 2133 } 2134 } 2135 2136 // Note: This method is invoked on the main thread but may need to attach various 2137 // handlers to other threads. So take care to be explicit about the looper. 2138 public ActivityManagerService(Context systemContext) { 2139 mContext = systemContext; 2140 mFactoryTest = FactoryTest.getMode(); 2141 mSystemThread = ActivityThread.currentActivityThread(); 2142 2143 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2144 2145 mHandlerThread = new ServiceThread(TAG, 2146 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2147 mHandlerThread.start(); 2148 mHandler = new MainHandler(mHandlerThread.getLooper()); 2149 2150 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2151 "foreground", BROADCAST_FG_TIMEOUT, false); 2152 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2153 "background", BROADCAST_BG_TIMEOUT, true); 2154 mBroadcastQueues[0] = mFgBroadcastQueue; 2155 mBroadcastQueues[1] = mBgBroadcastQueue; 2156 2157 mServices = new ActiveServices(this); 2158 mProviderMap = new ProviderMap(this); 2159 2160 // TODO: Move creation of battery stats service outside of activity manager service. 2161 File dataDir = Environment.getDataDirectory(); 2162 File systemDir = new File(dataDir, "system"); 2163 systemDir.mkdirs(); 2164 mBatteryStatsService = new BatteryStatsService(new File( 2165 systemDir, "batterystats.bin").toString(), mHandler); 2166 mBatteryStatsService.getActiveStatistics().readLocked(); 2167 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2168 mOnBattery = DEBUG_POWER ? true 2169 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2170 mBatteryStatsService.getActiveStatistics().setCallback(this); 2171 2172 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2173 2174 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2175 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2176 2177 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2178 2179 // User 0 is the first and only user that runs at boot. 2180 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2181 mUserLru.add(Integer.valueOf(0)); 2182 updateStartedUserArrayLocked(); 2183 2184 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2185 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2186 2187 mConfiguration.setToDefaults(); 2188 mConfiguration.setLocale(Locale.getDefault()); 2189 2190 mConfigurationSeq = mConfiguration.seq = 1; 2191 mProcessCpuTracker.init(); 2192 2193 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2194 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2195 mStackSupervisor = new ActivityStackSupervisor(this); 2196 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2197 2198 mProcessCpuThread = new Thread("CpuTracker") { 2199 @Override 2200 public void run() { 2201 while (true) { 2202 try { 2203 try { 2204 synchronized(this) { 2205 final long now = SystemClock.uptimeMillis(); 2206 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2207 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2208 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2209 // + ", write delay=" + nextWriteDelay); 2210 if (nextWriteDelay < nextCpuDelay) { 2211 nextCpuDelay = nextWriteDelay; 2212 } 2213 if (nextCpuDelay > 0) { 2214 mProcessCpuMutexFree.set(true); 2215 this.wait(nextCpuDelay); 2216 } 2217 } 2218 } catch (InterruptedException e) { 2219 } 2220 updateCpuStatsNow(); 2221 } catch (Exception e) { 2222 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2223 } 2224 } 2225 } 2226 }; 2227 2228 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2229 2230 Watchdog.getInstance().addMonitor(this); 2231 Watchdog.getInstance().addThread(mHandler); 2232 } 2233 2234 public void setSystemServiceManager(SystemServiceManager mgr) { 2235 mSystemServiceManager = mgr; 2236 } 2237 2238 private void start() { 2239 Process.removeAllProcessGroups(); 2240 mProcessCpuThread.start(); 2241 2242 mBatteryStatsService.publish(mContext); 2243 mUsageStatsService.publish(mContext); 2244 mAppOpsService.publish(mContext); 2245 Slog.d("AppOps", "AppOpsService published"); 2246 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2247 } 2248 2249 public void initPowerManagement() { 2250 mStackSupervisor.initPowerManagement(); 2251 mBatteryStatsService.initPowerManagement(); 2252 } 2253 2254 @Override 2255 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2256 throws RemoteException { 2257 if (code == SYSPROPS_TRANSACTION) { 2258 // We need to tell all apps about the system property change. 2259 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2260 synchronized(this) { 2261 final int NP = mProcessNames.getMap().size(); 2262 for (int ip=0; ip<NP; ip++) { 2263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2264 final int NA = apps.size(); 2265 for (int ia=0; ia<NA; ia++) { 2266 ProcessRecord app = apps.valueAt(ia); 2267 if (app.thread != null) { 2268 procs.add(app.thread.asBinder()); 2269 } 2270 } 2271 } 2272 } 2273 2274 int N = procs.size(); 2275 for (int i=0; i<N; i++) { 2276 Parcel data2 = Parcel.obtain(); 2277 try { 2278 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2279 } catch (RemoteException e) { 2280 } 2281 data2.recycle(); 2282 } 2283 } 2284 try { 2285 return super.onTransact(code, data, reply, flags); 2286 } catch (RuntimeException e) { 2287 // The activity manager only throws security exceptions, so let's 2288 // log all others. 2289 if (!(e instanceof SecurityException)) { 2290 Slog.wtf(TAG, "Activity Manager Crash", e); 2291 } 2292 throw e; 2293 } 2294 } 2295 2296 void updateCpuStats() { 2297 final long now = SystemClock.uptimeMillis(); 2298 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2299 return; 2300 } 2301 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2302 synchronized (mProcessCpuThread) { 2303 mProcessCpuThread.notify(); 2304 } 2305 } 2306 } 2307 2308 void updateCpuStatsNow() { 2309 synchronized (mProcessCpuThread) { 2310 mProcessCpuMutexFree.set(false); 2311 final long now = SystemClock.uptimeMillis(); 2312 boolean haveNewCpuStats = false; 2313 2314 if (MONITOR_CPU_USAGE && 2315 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2316 mLastCpuTime.set(now); 2317 haveNewCpuStats = true; 2318 mProcessCpuTracker.update(); 2319 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2320 //Slog.i(TAG, "Total CPU usage: " 2321 // + mProcessCpu.getTotalCpuPercent() + "%"); 2322 2323 // Slog the cpu usage if the property is set. 2324 if ("true".equals(SystemProperties.get("events.cpu"))) { 2325 int user = mProcessCpuTracker.getLastUserTime(); 2326 int system = mProcessCpuTracker.getLastSystemTime(); 2327 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2328 int irq = mProcessCpuTracker.getLastIrqTime(); 2329 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2330 int idle = mProcessCpuTracker.getLastIdleTime(); 2331 2332 int total = user + system + iowait + irq + softIrq + idle; 2333 if (total == 0) total = 1; 2334 2335 EventLog.writeEvent(EventLogTags.CPU, 2336 ((user+system+iowait+irq+softIrq) * 100) / total, 2337 (user * 100) / total, 2338 (system * 100) / total, 2339 (iowait * 100) / total, 2340 (irq * 100) / total, 2341 (softIrq * 100) / total); 2342 } 2343 } 2344 2345 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2346 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2347 synchronized(bstats) { 2348 synchronized(mPidsSelfLocked) { 2349 if (haveNewCpuStats) { 2350 if (mOnBattery) { 2351 int perc = bstats.startAddingCpuLocked(); 2352 int totalUTime = 0; 2353 int totalSTime = 0; 2354 final int N = mProcessCpuTracker.countStats(); 2355 for (int i=0; i<N; i++) { 2356 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2357 if (!st.working) { 2358 continue; 2359 } 2360 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2361 int otherUTime = (st.rel_utime*perc)/100; 2362 int otherSTime = (st.rel_stime*perc)/100; 2363 totalUTime += otherUTime; 2364 totalSTime += otherSTime; 2365 if (pr != null) { 2366 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2367 if (ps == null || !ps.isActive()) { 2368 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2369 pr.info.uid, pr.processName); 2370 } 2371 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2372 st.rel_stime-otherSTime); 2373 ps.addSpeedStepTimes(cpuSpeedTimes); 2374 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2375 } else { 2376 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2377 if (ps == null || !ps.isActive()) { 2378 st.batteryStats = ps = bstats.getProcessStatsLocked( 2379 bstats.mapUid(st.uid), st.name); 2380 } 2381 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2382 st.rel_stime-otherSTime); 2383 ps.addSpeedStepTimes(cpuSpeedTimes); 2384 } 2385 } 2386 bstats.finishAddingCpuLocked(perc, totalUTime, 2387 totalSTime, cpuSpeedTimes); 2388 } 2389 } 2390 } 2391 2392 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2393 mLastWriteTime = now; 2394 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2395 } 2396 } 2397 } 2398 } 2399 2400 @Override 2401 public void batteryNeedsCpuUpdate() { 2402 updateCpuStatsNow(); 2403 } 2404 2405 @Override 2406 public void batteryPowerChanged(boolean onBattery) { 2407 // When plugging in, update the CPU stats first before changing 2408 // the plug state. 2409 updateCpuStatsNow(); 2410 synchronized (this) { 2411 synchronized(mPidsSelfLocked) { 2412 mOnBattery = DEBUG_POWER ? true : onBattery; 2413 } 2414 } 2415 } 2416 2417 /** 2418 * Initialize the application bind args. These are passed to each 2419 * process when the bindApplication() IPC is sent to the process. They're 2420 * lazily setup to make sure the services are running when they're asked for. 2421 */ 2422 private HashMap<String, IBinder> getCommonServicesLocked() { 2423 if (mAppBindArgs == null) { 2424 mAppBindArgs = new HashMap<String, IBinder>(); 2425 2426 // Setup the application init args 2427 mAppBindArgs.put("package", ServiceManager.getService("package")); 2428 mAppBindArgs.put("window", ServiceManager.getService("window")); 2429 mAppBindArgs.put(Context.ALARM_SERVICE, 2430 ServiceManager.getService(Context.ALARM_SERVICE)); 2431 } 2432 return mAppBindArgs; 2433 } 2434 2435 final void setFocusedActivityLocked(ActivityRecord r) { 2436 if (mFocusedActivity != r) { 2437 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2438 mFocusedActivity = r; 2439 if (r.task != null && r.task.voiceInteractor != null) { 2440 startRunningVoiceLocked(); 2441 } else { 2442 finishRunningVoiceLocked(); 2443 } 2444 mStackSupervisor.setFocusedStack(r); 2445 if (r != null) { 2446 mWindowManager.setFocusedApp(r.appToken, true); 2447 } 2448 applyUpdateLockStateLocked(r); 2449 } 2450 } 2451 2452 final void clearFocusedActivity(ActivityRecord r) { 2453 if (mFocusedActivity == r) { 2454 mFocusedActivity = null; 2455 } 2456 } 2457 2458 @Override 2459 public void setFocusedStack(int stackId) { 2460 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2461 synchronized (ActivityManagerService.this) { 2462 ActivityStack stack = mStackSupervisor.getStack(stackId); 2463 if (stack != null) { 2464 ActivityRecord r = stack.topRunningActivityLocked(null); 2465 if (r != null) { 2466 setFocusedActivityLocked(r); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void notifyActivityDrawn(IBinder token) { 2474 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2475 synchronized (this) { 2476 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2477 if (r != null) { 2478 r.task.stack.notifyActivityDrawnLocked(r); 2479 } 2480 } 2481 } 2482 2483 final void applyUpdateLockStateLocked(ActivityRecord r) { 2484 // Modifications to the UpdateLock state are done on our handler, outside 2485 // the activity manager's locks. The new state is determined based on the 2486 // state *now* of the relevant activity record. The object is passed to 2487 // the handler solely for logging detail, not to be consulted/modified. 2488 final boolean nextState = r != null && r.immersive; 2489 mHandler.sendMessage( 2490 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2491 } 2492 2493 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2494 Message msg = Message.obtain(); 2495 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2496 msg.obj = r.task.askedCompatMode ? null : r; 2497 mHandler.sendMessage(msg); 2498 } 2499 2500 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2501 String what, Object obj, ProcessRecord srcApp) { 2502 app.lastActivityTime = now; 2503 2504 if (app.activities.size() > 0) { 2505 // Don't want to touch dependent processes that are hosting activities. 2506 return index; 2507 } 2508 2509 int lrui = mLruProcesses.lastIndexOf(app); 2510 if (lrui < 0) { 2511 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2512 + what + " " + obj + " from " + srcApp); 2513 return index; 2514 } 2515 2516 if (lrui >= index) { 2517 // Don't want to cause this to move dependent processes *back* in the 2518 // list as if they were less frequently used. 2519 return index; 2520 } 2521 2522 if (lrui >= mLruProcessActivityStart) { 2523 // Don't want to touch dependent processes that are hosting activities. 2524 return index; 2525 } 2526 2527 mLruProcesses.remove(lrui); 2528 if (index > 0) { 2529 index--; 2530 } 2531 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2532 + " in LRU list: " + app); 2533 mLruProcesses.add(index, app); 2534 return index; 2535 } 2536 2537 final void removeLruProcessLocked(ProcessRecord app) { 2538 int lrui = mLruProcesses.lastIndexOf(app); 2539 if (lrui >= 0) { 2540 if (lrui <= mLruProcessActivityStart) { 2541 mLruProcessActivityStart--; 2542 } 2543 if (lrui <= mLruProcessServiceStart) { 2544 mLruProcessServiceStart--; 2545 } 2546 mLruProcesses.remove(lrui); 2547 } 2548 } 2549 2550 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2551 ProcessRecord client) { 2552 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2553 || app.treatLikeActivity; 2554 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2555 if (!activityChange && hasActivity) { 2556 // The process has activities, so we are only allowing activity-based adjustments 2557 // to move it. It should be kept in the front of the list with other 2558 // processes that have activities, and we don't want those to change their 2559 // order except due to activity operations. 2560 return; 2561 } 2562 2563 mLruSeq++; 2564 final long now = SystemClock.uptimeMillis(); 2565 app.lastActivityTime = now; 2566 2567 // First a quick reject: if the app is already at the position we will 2568 // put it, then there is nothing to do. 2569 if (hasActivity) { 2570 final int N = mLruProcesses.size(); 2571 if (N > 0 && mLruProcesses.get(N-1) == app) { 2572 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2573 return; 2574 } 2575 } else { 2576 if (mLruProcessServiceStart > 0 2577 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2579 return; 2580 } 2581 } 2582 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 2585 if (app.persistent && lrui >= 0) { 2586 // We don't care about the position of persistent processes, as long as 2587 // they are in the list. 2588 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2589 return; 2590 } 2591 2592 /* In progress: compute new position first, so we can avoid doing work 2593 if the process is not actually going to move. Not yet working. 2594 int addIndex; 2595 int nextIndex; 2596 boolean inActivity = false, inService = false; 2597 if (hasActivity) { 2598 // Process has activities, put it at the very tipsy-top. 2599 addIndex = mLruProcesses.size(); 2600 nextIndex = mLruProcessServiceStart; 2601 inActivity = true; 2602 } else if (hasService) { 2603 // Process has services, put it at the top of the service list. 2604 addIndex = mLruProcessActivityStart; 2605 nextIndex = mLruProcessServiceStart; 2606 inActivity = true; 2607 inService = true; 2608 } else { 2609 // Process not otherwise of interest, it goes to the top of the non-service area. 2610 addIndex = mLruProcessServiceStart; 2611 if (client != null) { 2612 int clientIndex = mLruProcesses.lastIndexOf(client); 2613 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2614 + app); 2615 if (clientIndex >= 0 && addIndex > clientIndex) { 2616 addIndex = clientIndex; 2617 } 2618 } 2619 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2620 } 2621 2622 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2623 + mLruProcessActivityStart + "): " + app); 2624 */ 2625 2626 if (lrui >= 0) { 2627 if (lrui < mLruProcessActivityStart) { 2628 mLruProcessActivityStart--; 2629 } 2630 if (lrui < mLruProcessServiceStart) { 2631 mLruProcessServiceStart--; 2632 } 2633 /* 2634 if (addIndex > lrui) { 2635 addIndex--; 2636 } 2637 if (nextIndex > lrui) { 2638 nextIndex--; 2639 } 2640 */ 2641 mLruProcesses.remove(lrui); 2642 } 2643 2644 /* 2645 mLruProcesses.add(addIndex, app); 2646 if (inActivity) { 2647 mLruProcessActivityStart++; 2648 } 2649 if (inService) { 2650 mLruProcessActivityStart++; 2651 } 2652 */ 2653 2654 int nextIndex; 2655 if (hasActivity) { 2656 final int N = mLruProcesses.size(); 2657 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2658 // Process doesn't have activities, but has clients with 2659 // activities... move it up, but one below the top (the top 2660 // should always have a real activity). 2661 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2662 mLruProcesses.add(N-1, app); 2663 // To keep it from spamming the LRU list (by making a bunch of clients), 2664 // we will push down any other entries owned by the app. 2665 final int uid = app.info.uid; 2666 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2667 ProcessRecord subProc = mLruProcesses.get(i); 2668 if (subProc.info.uid == uid) { 2669 // We want to push this one down the list. If the process after 2670 // it is for the same uid, however, don't do so, because we don't 2671 // want them internally to be re-ordered. 2672 if (mLruProcesses.get(i-1).info.uid != uid) { 2673 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2674 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2675 ProcessRecord tmp = mLruProcesses.get(i); 2676 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2677 mLruProcesses.set(i-1, tmp); 2678 i--; 2679 } 2680 } else { 2681 // A gap, we can stop here. 2682 break; 2683 } 2684 } 2685 } else { 2686 // Process has activities, put it at the very tipsy-top. 2687 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2688 mLruProcesses.add(app); 2689 } 2690 nextIndex = mLruProcessServiceStart; 2691 } else if (hasService) { 2692 // Process has services, put it at the top of the service list. 2693 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2694 mLruProcesses.add(mLruProcessActivityStart, app); 2695 nextIndex = mLruProcessServiceStart; 2696 mLruProcessActivityStart++; 2697 } else { 2698 // Process not otherwise of interest, it goes to the top of the non-service area. 2699 int index = mLruProcessServiceStart; 2700 if (client != null) { 2701 // If there is a client, don't allow the process to be moved up higher 2702 // in the list than that client. 2703 int clientIndex = mLruProcesses.lastIndexOf(client); 2704 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2705 + " when updating " + app); 2706 if (clientIndex <= lrui) { 2707 // Don't allow the client index restriction to push it down farther in the 2708 // list than it already is. 2709 clientIndex = lrui; 2710 } 2711 if (clientIndex >= 0 && index > clientIndex) { 2712 index = clientIndex; 2713 } 2714 } 2715 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2716 mLruProcesses.add(index, app); 2717 nextIndex = index-1; 2718 mLruProcessActivityStart++; 2719 mLruProcessServiceStart++; 2720 } 2721 2722 // If the app is currently using a content provider or service, 2723 // bump those processes as well. 2724 for (int j=app.connections.size()-1; j>=0; j--) { 2725 ConnectionRecord cr = app.connections.valueAt(j); 2726 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2727 && cr.binding.service.app != null 2728 && cr.binding.service.app.lruSeq != mLruSeq 2729 && !cr.binding.service.app.persistent) { 2730 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2731 "service connection", cr, app); 2732 } 2733 } 2734 for (int j=app.conProviders.size()-1; j>=0; j--) { 2735 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2736 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2737 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2738 "provider reference", cpr, app); 2739 } 2740 } 2741 } 2742 2743 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2744 if (uid == Process.SYSTEM_UID) { 2745 // The system gets to run in any process. If there are multiple 2746 // processes with the same uid, just pick the first (this 2747 // should never happen). 2748 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2749 if (procs == null) return null; 2750 final int N = procs.size(); 2751 for (int i = 0; i < N; i++) { 2752 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2753 } 2754 } 2755 ProcessRecord proc = mProcessNames.get(processName, uid); 2756 if (false && proc != null && !keepIfLarge 2757 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2758 && proc.lastCachedPss >= 4000) { 2759 // Turn this condition on to cause killing to happen regularly, for testing. 2760 if (proc.baseProcessTracker != null) { 2761 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2762 } 2763 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2764 + "k from cached"); 2765 } else if (proc != null && !keepIfLarge 2766 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2767 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2768 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2769 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2770 if (proc.baseProcessTracker != null) { 2771 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2772 } 2773 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2774 + "k from cached"); 2775 } 2776 } 2777 return proc; 2778 } 2779 2780 void ensurePackageDexOpt(String packageName) { 2781 IPackageManager pm = AppGlobals.getPackageManager(); 2782 try { 2783 if (pm.performDexOpt(packageName)) { 2784 mDidDexOpt = true; 2785 } 2786 } catch (RemoteException e) { 2787 } 2788 } 2789 2790 boolean isNextTransitionForward() { 2791 int transit = mWindowManager.getPendingAppTransition(); 2792 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2793 || transit == AppTransition.TRANSIT_TASK_OPEN 2794 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2795 } 2796 2797 final ProcessRecord startProcessLocked(String processName, 2798 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2799 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2800 boolean isolated, boolean keepIfLarge) { 2801 ProcessRecord app; 2802 if (!isolated) { 2803 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2804 } else { 2805 // If this is an isolated process, it can't re-use an existing process. 2806 app = null; 2807 } 2808 // We don't have to do anything more if: 2809 // (1) There is an existing application record; and 2810 // (2) The caller doesn't think it is dead, OR there is no thread 2811 // object attached to it so we know it couldn't have crashed; and 2812 // (3) There is a pid assigned to it, so it is either starting or 2813 // already running. 2814 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2815 + " app=" + app + " knownToBeDead=" + knownToBeDead 2816 + " thread=" + (app != null ? app.thread : null) 2817 + " pid=" + (app != null ? app.pid : -1)); 2818 if (app != null && app.pid > 0) { 2819 if (!knownToBeDead || app.thread == null) { 2820 // We already have the app running, or are waiting for it to 2821 // come up (we have a pid but not yet its thread), so keep it. 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 return app; 2826 } 2827 2828 // An application record is attached to a previous process, 2829 // clean it up now. 2830 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2831 Process.killProcessGroup(app.info.uid, app.pid); 2832 handleAppDiedLocked(app, true, true); 2833 } 2834 2835 String hostingNameStr = hostingName != null 2836 ? hostingName.flattenToShortString() : null; 2837 2838 if (!isolated) { 2839 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2840 // If we are in the background, then check to see if this process 2841 // is bad. If so, we will just silently fail. 2842 if (mBadProcesses.get(info.processName, info.uid) != null) { 2843 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2844 + "/" + info.processName); 2845 return null; 2846 } 2847 } else { 2848 // When the user is explicitly starting a process, then clear its 2849 // crash count so that we won't make it bad until they see at 2850 // least one crash dialog again, and make the process good again 2851 // if it had been bad. 2852 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2853 + "/" + info.processName); 2854 mProcessCrashTimes.remove(info.processName, info.uid); 2855 if (mBadProcesses.get(info.processName, info.uid) != null) { 2856 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2857 UserHandle.getUserId(info.uid), info.uid, 2858 info.processName); 2859 mBadProcesses.remove(info.processName, info.uid); 2860 if (app != null) { 2861 app.bad = false; 2862 } 2863 } 2864 } 2865 } 2866 2867 if (app == null) { 2868 app = newProcessRecordLocked(info, processName, isolated); 2869 if (app == null) { 2870 Slog.w(TAG, "Failed making new process record for " 2871 + processName + "/" + info.uid + " isolated=" + isolated); 2872 return null; 2873 } 2874 mProcessNames.put(processName, app.uid, app); 2875 if (isolated) { 2876 mIsolatedProcesses.put(app.uid, app); 2877 } 2878 } else { 2879 // If this is a new package in the process, add the package to the list 2880 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2881 } 2882 2883 // If the system is not ready yet, then hold off on starting this 2884 // process until it is. 2885 if (!mProcessesReady 2886 && !isAllowedWhileBooting(info) 2887 && !allowWhileBooting) { 2888 if (!mProcessesOnHold.contains(app)) { 2889 mProcessesOnHold.add(app); 2890 } 2891 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2892 return app; 2893 } 2894 2895 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2896 return (app.pid != 0) ? app : null; 2897 } 2898 2899 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2900 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2901 } 2902 2903 private final void startProcessLocked(ProcessRecord app, 2904 String hostingType, String hostingNameStr, String abiOverride) { 2905 if (app.pid > 0 && app.pid != MY_PID) { 2906 synchronized (mPidsSelfLocked) { 2907 mPidsSelfLocked.remove(app.pid); 2908 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2909 } 2910 app.setPid(0); 2911 } 2912 2913 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2914 "startProcessLocked removing on hold: " + app); 2915 mProcessesOnHold.remove(app); 2916 2917 updateCpuStats(); 2918 2919 try { 2920 int uid = app.uid; 2921 2922 int[] gids = null; 2923 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2924 if (!app.isolated) { 2925 int[] permGids = null; 2926 try { 2927 final PackageManager pm = mContext.getPackageManager(); 2928 permGids = pm.getPackageGids(app.info.packageName); 2929 2930 if (Environment.isExternalStorageEmulated()) { 2931 if (pm.checkPermission( 2932 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2933 app.info.packageName) == PERMISSION_GRANTED) { 2934 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2935 } else { 2936 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2937 } 2938 } 2939 } catch (PackageManager.NameNotFoundException e) { 2940 Slog.w(TAG, "Unable to retrieve gids", e); 2941 } 2942 2943 /* 2944 * Add shared application and profile GIDs so applications can share some 2945 * resources like shared libraries and access user-wide resources 2946 */ 2947 if (permGids == null) { 2948 gids = new int[2]; 2949 } else { 2950 gids = new int[permGids.length + 2]; 2951 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2952 } 2953 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2954 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2955 } 2956 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2957 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2958 && mTopComponent != null 2959 && app.processName.equals(mTopComponent.getPackageName())) { 2960 uid = 0; 2961 } 2962 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2963 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2964 uid = 0; 2965 } 2966 } 2967 int debugFlags = 0; 2968 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2969 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2970 // Also turn on CheckJNI for debuggable apps. It's quite 2971 // awkward to turn on otherwise. 2972 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2973 } 2974 // Run the app in safe mode if its manifest requests so or the 2975 // system is booted in safe mode. 2976 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2977 mSafeMode == true) { 2978 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2979 } 2980 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2982 } 2983 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2984 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2985 } 2986 if ("1".equals(SystemProperties.get("debug.assert"))) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2988 } 2989 2990 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2991 if (requiredAbi == null) { 2992 requiredAbi = Build.SUPPORTED_ABIS[0]; 2993 } 2994 2995 // Start the process. It will either succeed and return a result containing 2996 // the PID of the new process, or else throw a RuntimeException. 2997 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2998 app.processName, uid, uid, gids, debugFlags, mountExternal, 2999 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3000 3001 if (app.isolated) { 3002 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3003 } 3004 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3005 3006 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3007 UserHandle.getUserId(uid), startResult.pid, uid, 3008 app.processName, hostingType, 3009 hostingNameStr != null ? hostingNameStr : ""); 3010 3011 if (app.persistent) { 3012 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3013 } 3014 3015 StringBuilder buf = mStringBuilder; 3016 buf.setLength(0); 3017 buf.append("Start proc "); 3018 buf.append(app.processName); 3019 buf.append(" for "); 3020 buf.append(hostingType); 3021 if (hostingNameStr != null) { 3022 buf.append(" "); 3023 buf.append(hostingNameStr); 3024 } 3025 buf.append(": pid="); 3026 buf.append(startResult.pid); 3027 buf.append(" uid="); 3028 buf.append(uid); 3029 buf.append(" gids={"); 3030 if (gids != null) { 3031 for (int gi=0; gi<gids.length; gi++) { 3032 if (gi != 0) buf.append(", "); 3033 buf.append(gids[gi]); 3034 3035 } 3036 } 3037 buf.append("}"); 3038 if (requiredAbi != null) { 3039 buf.append(" abi="); 3040 buf.append(requiredAbi); 3041 } 3042 Slog.i(TAG, buf.toString()); 3043 app.setPid(startResult.pid); 3044 app.usingWrapper = startResult.usingWrapper; 3045 app.removed = false; 3046 app.killedByAm = false; 3047 synchronized (mPidsSelfLocked) { 3048 this.mPidsSelfLocked.put(startResult.pid, app); 3049 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3050 msg.obj = app; 3051 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3052 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3053 } 3054 } catch (RuntimeException e) { 3055 // XXX do better error recovery. 3056 app.setPid(0); 3057 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3058 if (app.isolated) { 3059 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3060 } 3061 Slog.e(TAG, "Failure starting process " + app.processName, e); 3062 } 3063 } 3064 3065 void updateUsageStats(ActivityRecord component, boolean resumed) { 3066 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3067 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3068 if (resumed) { 3069 mUsageStatsService.noteResumeComponent(component.realActivity); 3070 synchronized (stats) { 3071 stats.noteActivityResumedLocked(component.app.uid); 3072 } 3073 } else { 3074 mUsageStatsService.notePauseComponent(component.realActivity); 3075 synchronized (stats) { 3076 stats.noteActivityPausedLocked(component.app.uid); 3077 } 3078 } 3079 } 3080 3081 Intent getHomeIntent() { 3082 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3083 intent.setComponent(mTopComponent); 3084 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3085 intent.addCategory(Intent.CATEGORY_HOME); 3086 } 3087 return intent; 3088 } 3089 3090 boolean startHomeActivityLocked(int userId) { 3091 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3092 && mTopAction == null) { 3093 // We are running in factory test mode, but unable to find 3094 // the factory test app, so just sit around displaying the 3095 // error message and don't try to start anything. 3096 return false; 3097 } 3098 Intent intent = getHomeIntent(); 3099 ActivityInfo aInfo = 3100 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3101 if (aInfo != null) { 3102 intent.setComponent(new ComponentName( 3103 aInfo.applicationInfo.packageName, aInfo.name)); 3104 // Don't do this if the home app is currently being 3105 // instrumented. 3106 aInfo = new ActivityInfo(aInfo); 3107 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3108 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3109 aInfo.applicationInfo.uid, true); 3110 if (app == null || app.instrumentationClass == null) { 3111 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3112 mStackSupervisor.startHomeActivity(intent, aInfo); 3113 } 3114 } 3115 3116 return true; 3117 } 3118 3119 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3120 ActivityInfo ai = null; 3121 ComponentName comp = intent.getComponent(); 3122 try { 3123 if (comp != null) { 3124 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3125 } else { 3126 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3127 intent, 3128 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3129 flags, userId); 3130 3131 if (info != null) { 3132 ai = info.activityInfo; 3133 } 3134 } 3135 } catch (RemoteException e) { 3136 // ignore 3137 } 3138 3139 return ai; 3140 } 3141 3142 /** 3143 * Starts the "new version setup screen" if appropriate. 3144 */ 3145 void startSetupActivityLocked() { 3146 // Only do this once per boot. 3147 if (mCheckedForSetup) { 3148 return; 3149 } 3150 3151 // We will show this screen if the current one is a different 3152 // version than the last one shown, and we are not running in 3153 // low-level factory test mode. 3154 final ContentResolver resolver = mContext.getContentResolver(); 3155 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3156 Settings.Global.getInt(resolver, 3157 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3158 mCheckedForSetup = true; 3159 3160 // See if we should be showing the platform update setup UI. 3161 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3162 List<ResolveInfo> ris = mContext.getPackageManager() 3163 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3164 3165 // We don't allow third party apps to replace this. 3166 ResolveInfo ri = null; 3167 for (int i=0; ris != null && i<ris.size(); i++) { 3168 if ((ris.get(i).activityInfo.applicationInfo.flags 3169 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3170 ri = ris.get(i); 3171 break; 3172 } 3173 } 3174 3175 if (ri != null) { 3176 String vers = ri.activityInfo.metaData != null 3177 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3178 : null; 3179 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3180 vers = ri.activityInfo.applicationInfo.metaData.getString( 3181 Intent.METADATA_SETUP_VERSION); 3182 } 3183 String lastVers = Settings.Secure.getString( 3184 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3185 if (vers != null && !vers.equals(lastVers)) { 3186 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3187 intent.setComponent(new ComponentName( 3188 ri.activityInfo.packageName, ri.activityInfo.name)); 3189 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3190 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3191 } 3192 } 3193 } 3194 } 3195 3196 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3197 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3198 } 3199 3200 void enforceNotIsolatedCaller(String caller) { 3201 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3202 throw new SecurityException("Isolated process not allowed to call " + caller); 3203 } 3204 } 3205 3206 @Override 3207 public int getFrontActivityScreenCompatMode() { 3208 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3209 synchronized (this) { 3210 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3211 } 3212 } 3213 3214 @Override 3215 public void setFrontActivityScreenCompatMode(int mode) { 3216 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3217 "setFrontActivityScreenCompatMode"); 3218 synchronized (this) { 3219 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3220 } 3221 } 3222 3223 @Override 3224 public int getPackageScreenCompatMode(String packageName) { 3225 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3226 synchronized (this) { 3227 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3228 } 3229 } 3230 3231 @Override 3232 public void setPackageScreenCompatMode(String packageName, int mode) { 3233 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3234 "setPackageScreenCompatMode"); 3235 synchronized (this) { 3236 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3237 } 3238 } 3239 3240 @Override 3241 public boolean getPackageAskScreenCompat(String packageName) { 3242 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3243 synchronized (this) { 3244 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3245 } 3246 } 3247 3248 @Override 3249 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3250 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3251 "setPackageAskScreenCompat"); 3252 synchronized (this) { 3253 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3254 } 3255 } 3256 3257 private void dispatchProcessesChanged() { 3258 int N; 3259 synchronized (this) { 3260 N = mPendingProcessChanges.size(); 3261 if (mActiveProcessChanges.length < N) { 3262 mActiveProcessChanges = new ProcessChangeItem[N]; 3263 } 3264 mPendingProcessChanges.toArray(mActiveProcessChanges); 3265 mAvailProcessChanges.addAll(mPendingProcessChanges); 3266 mPendingProcessChanges.clear(); 3267 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3268 } 3269 3270 int i = mProcessObservers.beginBroadcast(); 3271 while (i > 0) { 3272 i--; 3273 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3274 if (observer != null) { 3275 try { 3276 for (int j=0; j<N; j++) { 3277 ProcessChangeItem item = mActiveProcessChanges[j]; 3278 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3279 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3280 + item.pid + " uid=" + item.uid + ": " 3281 + item.foregroundActivities); 3282 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3283 item.foregroundActivities); 3284 } 3285 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3286 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3287 + item.pid + " uid=" + item.uid + ": " + item.processState); 3288 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3289 } 3290 } 3291 } catch (RemoteException e) { 3292 } 3293 } 3294 } 3295 mProcessObservers.finishBroadcast(); 3296 } 3297 3298 private void dispatchProcessDied(int pid, int uid) { 3299 int i = mProcessObservers.beginBroadcast(); 3300 while (i > 0) { 3301 i--; 3302 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3303 if (observer != null) { 3304 try { 3305 observer.onProcessDied(pid, uid); 3306 } catch (RemoteException e) { 3307 } 3308 } 3309 } 3310 mProcessObservers.finishBroadcast(); 3311 } 3312 3313 final void doPendingActivityLaunchesLocked(boolean doResume) { 3314 final int N = mPendingActivityLaunches.size(); 3315 if (N <= 0) { 3316 return; 3317 } 3318 for (int i=0; i<N; i++) { 3319 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3320 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3321 doResume && i == (N-1), null); 3322 } 3323 mPendingActivityLaunches.clear(); 3324 } 3325 3326 @Override 3327 public final int startActivity(IApplicationThread caller, String callingPackage, 3328 Intent intent, String resolvedType, IBinder resultTo, 3329 String resultWho, int requestCode, int startFlags, 3330 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3331 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3332 resultWho, requestCode, 3333 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3334 } 3335 3336 @Override 3337 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3338 Intent intent, String resolvedType, IBinder resultTo, 3339 String resultWho, int requestCode, int startFlags, 3340 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3341 enforceNotIsolatedCaller("startActivity"); 3342 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3343 false, true, "startActivity", null); 3344 // TODO: Switch to user app stacks here. 3345 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3346 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3347 null, null, options, userId, null); 3348 } 3349 3350 @Override 3351 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3352 Intent intent, String resolvedType, IBinder resultTo, 3353 String resultWho, int requestCode, int startFlags, String profileFile, 3354 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3355 enforceNotIsolatedCaller("startActivityAndWait"); 3356 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3357 false, true, "startActivityAndWait", null); 3358 WaitResult res = new WaitResult(); 3359 // TODO: Switch to user app stacks here. 3360 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3361 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3362 res, null, options, UserHandle.getCallingUserId(), null); 3363 return res; 3364 } 3365 3366 @Override 3367 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3368 Intent intent, String resolvedType, IBinder resultTo, 3369 String resultWho, int requestCode, int startFlags, Configuration config, 3370 Bundle options, int userId) { 3371 enforceNotIsolatedCaller("startActivityWithConfig"); 3372 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3373 false, true, "startActivityWithConfig", null); 3374 // TODO: Switch to user app stacks here. 3375 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3376 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3377 null, null, null, config, options, userId, null); 3378 return ret; 3379 } 3380 3381 @Override 3382 public int startActivityIntentSender(IApplicationThread caller, 3383 IntentSender intent, Intent fillInIntent, String resolvedType, 3384 IBinder resultTo, String resultWho, int requestCode, 3385 int flagsMask, int flagsValues, Bundle options) { 3386 enforceNotIsolatedCaller("startActivityIntentSender"); 3387 // Refuse possible leaked file descriptors 3388 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3389 throw new IllegalArgumentException("File descriptors passed in Intent"); 3390 } 3391 3392 IIntentSender sender = intent.getTarget(); 3393 if (!(sender instanceof PendingIntentRecord)) { 3394 throw new IllegalArgumentException("Bad PendingIntent object"); 3395 } 3396 3397 PendingIntentRecord pir = (PendingIntentRecord)sender; 3398 3399 synchronized (this) { 3400 // If this is coming from the currently resumed activity, it is 3401 // effectively saying that app switches are allowed at this point. 3402 final ActivityStack stack = getFocusedStack(); 3403 if (stack.mResumedActivity != null && 3404 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3405 mAppSwitchesAllowedTime = 0; 3406 } 3407 } 3408 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3409 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3410 return ret; 3411 } 3412 3413 @Override 3414 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3415 Intent intent, String resolvedType, IVoiceInteractionSession session, 3416 IVoiceInteractor interactor, int startFlags, String profileFile, 3417 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3418 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3419 != PackageManager.PERMISSION_GRANTED) { 3420 String msg = "Permission Denial: startVoiceActivity() from pid=" 3421 + Binder.getCallingPid() 3422 + ", uid=" + Binder.getCallingUid() 3423 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3424 Slog.w(TAG, msg); 3425 throw new SecurityException(msg); 3426 } 3427 if (session == null || interactor == null) { 3428 throw new NullPointerException("null session or interactor"); 3429 } 3430 userId = handleIncomingUser(callingPid, callingUid, userId, 3431 false, true, "startVoiceActivity", null); 3432 // TODO: Switch to user app stacks here. 3433 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3434 resolvedType, session, interactor, null, null, 0, startFlags, 3435 profileFile, profileFd, null, null, options, userId, null); 3436 } 3437 3438 @Override 3439 public boolean startNextMatchingActivity(IBinder callingActivity, 3440 Intent intent, Bundle options) { 3441 // Refuse possible leaked file descriptors 3442 if (intent != null && intent.hasFileDescriptors() == true) { 3443 throw new IllegalArgumentException("File descriptors passed in Intent"); 3444 } 3445 3446 synchronized (this) { 3447 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3448 if (r == null) { 3449 ActivityOptions.abort(options); 3450 return false; 3451 } 3452 if (r.app == null || r.app.thread == null) { 3453 // The caller is not running... d'oh! 3454 ActivityOptions.abort(options); 3455 return false; 3456 } 3457 intent = new Intent(intent); 3458 // The caller is not allowed to change the data. 3459 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3460 // And we are resetting to find the next component... 3461 intent.setComponent(null); 3462 3463 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3464 3465 ActivityInfo aInfo = null; 3466 try { 3467 List<ResolveInfo> resolves = 3468 AppGlobals.getPackageManager().queryIntentActivities( 3469 intent, r.resolvedType, 3470 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3471 UserHandle.getCallingUserId()); 3472 3473 // Look for the original activity in the list... 3474 final int N = resolves != null ? resolves.size() : 0; 3475 for (int i=0; i<N; i++) { 3476 ResolveInfo rInfo = resolves.get(i); 3477 if (rInfo.activityInfo.packageName.equals(r.packageName) 3478 && rInfo.activityInfo.name.equals(r.info.name)) { 3479 // We found the current one... the next matching is 3480 // after it. 3481 i++; 3482 if (i<N) { 3483 aInfo = resolves.get(i).activityInfo; 3484 } 3485 if (debug) { 3486 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3487 + "/" + r.info.name); 3488 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3489 + "/" + aInfo.name); 3490 } 3491 break; 3492 } 3493 } 3494 } catch (RemoteException e) { 3495 } 3496 3497 if (aInfo == null) { 3498 // Nobody who is next! 3499 ActivityOptions.abort(options); 3500 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3501 return false; 3502 } 3503 3504 intent.setComponent(new ComponentName( 3505 aInfo.applicationInfo.packageName, aInfo.name)); 3506 intent.setFlags(intent.getFlags()&~( 3507 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3508 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3509 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3510 Intent.FLAG_ACTIVITY_NEW_TASK)); 3511 3512 // Okay now we need to start the new activity, replacing the 3513 // currently running activity. This is a little tricky because 3514 // we want to start the new one as if the current one is finished, 3515 // but not finish the current one first so that there is no flicker. 3516 // And thus... 3517 final boolean wasFinishing = r.finishing; 3518 r.finishing = true; 3519 3520 // Propagate reply information over to the new activity. 3521 final ActivityRecord resultTo = r.resultTo; 3522 final String resultWho = r.resultWho; 3523 final int requestCode = r.requestCode; 3524 r.resultTo = null; 3525 if (resultTo != null) { 3526 resultTo.removeResultsLocked(r, resultWho, requestCode); 3527 } 3528 3529 final long origId = Binder.clearCallingIdentity(); 3530 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3531 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3532 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3533 options, false, null, null); 3534 Binder.restoreCallingIdentity(origId); 3535 3536 r.finishing = wasFinishing; 3537 if (res != ActivityManager.START_SUCCESS) { 3538 return false; 3539 } 3540 return true; 3541 } 3542 } 3543 3544 final int startActivityInPackage(int uid, String callingPackage, 3545 Intent intent, String resolvedType, IBinder resultTo, 3546 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3547 IActivityContainer container) { 3548 3549 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3550 false, true, "startActivityInPackage", null); 3551 3552 // TODO: Switch to user app stacks here. 3553 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3554 null, null, resultTo, resultWho, requestCode, startFlags, 3555 null, null, null, null, options, userId, container); 3556 return ret; 3557 } 3558 3559 @Override 3560 public final int startActivities(IApplicationThread caller, String callingPackage, 3561 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3562 int userId) { 3563 enforceNotIsolatedCaller("startActivities"); 3564 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3565 false, true, "startActivity", null); 3566 // TODO: Switch to user app stacks here. 3567 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3568 resolvedTypes, resultTo, options, userId); 3569 return ret; 3570 } 3571 3572 final int startActivitiesInPackage(int uid, String callingPackage, 3573 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3574 Bundle options, int userId) { 3575 3576 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3577 false, true, "startActivityInPackage", null); 3578 // TODO: Switch to user app stacks here. 3579 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3580 resultTo, options, userId); 3581 return ret; 3582 } 3583 3584 final void addRecentTaskLocked(TaskRecord task) { 3585 int N = mRecentTasks.size(); 3586 // Quick case: check if the top-most recent task is the same. 3587 if (N > 0 && mRecentTasks.get(0) == task) { 3588 return; 3589 } 3590 // Another quick case: never add voice sessions. 3591 if (task.voiceSession != null) { 3592 return; 3593 } 3594 // Remove any existing entries that are the same kind of task. 3595 final Intent intent = task.intent; 3596 final boolean document = intent != null && intent.isDocument(); 3597 final ComponentName comp = intent.getComponent(); 3598 3599 int maxRecents = task.maxRecents - 1; 3600 for (int i=0; i<N; i++) { 3601 TaskRecord tr = mRecentTasks.get(i); 3602 if (task != tr) { 3603 if (task.userId != tr.userId) { 3604 continue; 3605 } 3606 if (i > MAX_RECENT_BITMAPS) { 3607 tr.freeLastThumbnail(); 3608 } 3609 final Intent trIntent = tr.intent; 3610 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3611 (intent == null || !intent.filterEquals(trIntent))) { 3612 continue; 3613 } 3614 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3615 if (document && trIsDocument) { 3616 // These are the same document activity (not necessarily the same doc). 3617 if (maxRecents > 0) { 3618 --maxRecents; 3619 continue; 3620 } 3621 // Hit the maximum number of documents for this task. Fall through 3622 // and remove this document from recents. 3623 } else if (document || trIsDocument) { 3624 // Only one of these is a document. Not the droid we're looking for. 3625 continue; 3626 } 3627 } 3628 3629 // Either task and tr are the same or, their affinities match or their intents match 3630 // and neither of them is a document, or they are documents using the same activity 3631 // and their maxRecents has been reached. 3632 tr.disposeThumbnail(); 3633 mRecentTasks.remove(i); 3634 i--; 3635 N--; 3636 if (task.intent == null) { 3637 // If the new recent task we are adding is not fully 3638 // specified, then replace it with the existing recent task. 3639 task = tr; 3640 } 3641 mTaskPersister.notify(tr, false); 3642 } 3643 if (N >= MAX_RECENT_TASKS) { 3644 mRecentTasks.remove(N-1).disposeThumbnail(); 3645 } 3646 mRecentTasks.add(0, task); 3647 } 3648 3649 @Override 3650 public void reportActivityFullyDrawn(IBinder token) { 3651 synchronized (this) { 3652 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3653 if (r == null) { 3654 return; 3655 } 3656 r.reportFullyDrawnLocked(); 3657 } 3658 } 3659 3660 @Override 3661 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3662 synchronized (this) { 3663 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3664 if (r == null) { 3665 return; 3666 } 3667 final long origId = Binder.clearCallingIdentity(); 3668 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3669 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3670 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3671 if (config != null) { 3672 r.frozenBeforeDestroy = true; 3673 if (!updateConfigurationLocked(config, r, false, false)) { 3674 mStackSupervisor.resumeTopActivitiesLocked(); 3675 } 3676 } 3677 Binder.restoreCallingIdentity(origId); 3678 } 3679 } 3680 3681 @Override 3682 public int getRequestedOrientation(IBinder token) { 3683 synchronized (this) { 3684 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3685 if (r == null) { 3686 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3687 } 3688 return mWindowManager.getAppOrientation(r.appToken); 3689 } 3690 } 3691 3692 /** 3693 * This is the internal entry point for handling Activity.finish(). 3694 * 3695 * @param token The Binder token referencing the Activity we want to finish. 3696 * @param resultCode Result code, if any, from this Activity. 3697 * @param resultData Result data (Intent), if any, from this Activity. 3698 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3699 * the root Activity in the task. 3700 * 3701 * @return Returns true if the activity successfully finished, or false if it is still running. 3702 */ 3703 @Override 3704 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3705 boolean finishTask) { 3706 // Refuse possible leaked file descriptors 3707 if (resultData != null && resultData.hasFileDescriptors() == true) { 3708 throw new IllegalArgumentException("File descriptors passed in Intent"); 3709 } 3710 3711 synchronized(this) { 3712 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3713 if (r == null) { 3714 return true; 3715 } 3716 // Keep track of the root activity of the task before we finish it 3717 TaskRecord tr = r.task; 3718 ActivityRecord rootR = tr.getRootActivity(); 3719 // Do not allow task to finish in Lock Task mode. 3720 if (tr == mStackSupervisor.mLockTaskModeTask) { 3721 if (rootR == r) { 3722 mStackSupervisor.showLockTaskToast(); 3723 return false; 3724 } 3725 } 3726 if (mController != null) { 3727 // Find the first activity that is not finishing. 3728 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3729 if (next != null) { 3730 // ask watcher if this is allowed 3731 boolean resumeOK = true; 3732 try { 3733 resumeOK = mController.activityResuming(next.packageName); 3734 } catch (RemoteException e) { 3735 mController = null; 3736 Watchdog.getInstance().setActivityController(null); 3737 } 3738 3739 if (!resumeOK) { 3740 return false; 3741 } 3742 } 3743 } 3744 final long origId = Binder.clearCallingIdentity(); 3745 try { 3746 boolean res; 3747 if (finishTask && r == rootR) { 3748 // If requested, remove the task that is associated to this activity only if it 3749 // was the root activity in the task. The result code and data is ignored because 3750 // we don't support returning them across task boundaries. 3751 res = removeTaskByIdLocked(tr.taskId, 0); 3752 } else { 3753 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3754 resultData, "app-request", true); 3755 } 3756 return res; 3757 } finally { 3758 Binder.restoreCallingIdentity(origId); 3759 } 3760 } 3761 } 3762 3763 @Override 3764 public final void finishHeavyWeightApp() { 3765 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3766 != PackageManager.PERMISSION_GRANTED) { 3767 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3768 + Binder.getCallingPid() 3769 + ", uid=" + Binder.getCallingUid() 3770 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3771 Slog.w(TAG, msg); 3772 throw new SecurityException(msg); 3773 } 3774 3775 synchronized(this) { 3776 if (mHeavyWeightProcess == null) { 3777 return; 3778 } 3779 3780 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3781 mHeavyWeightProcess.activities); 3782 for (int i=0; i<activities.size(); i++) { 3783 ActivityRecord r = activities.get(i); 3784 if (!r.finishing) { 3785 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3786 null, "finish-heavy", true); 3787 } 3788 } 3789 3790 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3791 mHeavyWeightProcess.userId, 0)); 3792 mHeavyWeightProcess = null; 3793 } 3794 } 3795 3796 @Override 3797 public void crashApplication(int uid, int initialPid, String packageName, 3798 String message) { 3799 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3800 != PackageManager.PERMISSION_GRANTED) { 3801 String msg = "Permission Denial: crashApplication() from pid=" 3802 + Binder.getCallingPid() 3803 + ", uid=" + Binder.getCallingUid() 3804 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3805 Slog.w(TAG, msg); 3806 throw new SecurityException(msg); 3807 } 3808 3809 synchronized(this) { 3810 ProcessRecord proc = null; 3811 3812 // Figure out which process to kill. We don't trust that initialPid 3813 // still has any relation to current pids, so must scan through the 3814 // list. 3815 synchronized (mPidsSelfLocked) { 3816 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3817 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3818 if (p.uid != uid) { 3819 continue; 3820 } 3821 if (p.pid == initialPid) { 3822 proc = p; 3823 break; 3824 } 3825 if (p.pkgList.containsKey(packageName)) { 3826 proc = p; 3827 } 3828 } 3829 } 3830 3831 if (proc == null) { 3832 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3833 + " initialPid=" + initialPid 3834 + " packageName=" + packageName); 3835 return; 3836 } 3837 3838 if (proc.thread != null) { 3839 if (proc.pid == Process.myPid()) { 3840 Log.w(TAG, "crashApplication: trying to crash self!"); 3841 return; 3842 } 3843 long ident = Binder.clearCallingIdentity(); 3844 try { 3845 proc.thread.scheduleCrash(message); 3846 } catch (RemoteException e) { 3847 } 3848 Binder.restoreCallingIdentity(ident); 3849 } 3850 } 3851 } 3852 3853 @Override 3854 public final void finishSubActivity(IBinder token, String resultWho, 3855 int requestCode) { 3856 synchronized(this) { 3857 final long origId = Binder.clearCallingIdentity(); 3858 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3859 if (r != null) { 3860 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3861 } 3862 Binder.restoreCallingIdentity(origId); 3863 } 3864 } 3865 3866 @Override 3867 public boolean finishActivityAffinity(IBinder token) { 3868 synchronized(this) { 3869 final long origId = Binder.clearCallingIdentity(); 3870 try { 3871 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3872 3873 ActivityRecord rootR = r.task.getRootActivity(); 3874 // Do not allow task to finish in Lock Task mode. 3875 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3876 if (rootR == r) { 3877 mStackSupervisor.showLockTaskToast(); 3878 return false; 3879 } 3880 } 3881 boolean res = false; 3882 if (r != null) { 3883 res = r.task.stack.finishActivityAffinityLocked(r); 3884 } 3885 return res; 3886 } finally { 3887 Binder.restoreCallingIdentity(origId); 3888 } 3889 } 3890 } 3891 3892 @Override 3893 public void finishVoiceTask(IVoiceInteractionSession session) { 3894 synchronized(this) { 3895 final long origId = Binder.clearCallingIdentity(); 3896 try { 3897 mStackSupervisor.finishVoiceTask(session); 3898 } finally { 3899 Binder.restoreCallingIdentity(origId); 3900 } 3901 } 3902 3903 } 3904 3905 @Override 3906 public boolean willActivityBeVisible(IBinder token) { 3907 synchronized(this) { 3908 ActivityStack stack = ActivityRecord.getStackLocked(token); 3909 if (stack != null) { 3910 return stack.willActivityBeVisibleLocked(token); 3911 } 3912 return false; 3913 } 3914 } 3915 3916 @Override 3917 public void overridePendingTransition(IBinder token, String packageName, 3918 int enterAnim, int exitAnim) { 3919 synchronized(this) { 3920 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3921 if (self == null) { 3922 return; 3923 } 3924 3925 final long origId = Binder.clearCallingIdentity(); 3926 3927 if (self.state == ActivityState.RESUMED 3928 || self.state == ActivityState.PAUSING) { 3929 mWindowManager.overridePendingAppTransition(packageName, 3930 enterAnim, exitAnim, null); 3931 } 3932 3933 Binder.restoreCallingIdentity(origId); 3934 } 3935 } 3936 3937 /** 3938 * Main function for removing an existing process from the activity manager 3939 * as a result of that process going away. Clears out all connections 3940 * to the process. 3941 */ 3942 private final void handleAppDiedLocked(ProcessRecord app, 3943 boolean restarting, boolean allowRestart) { 3944 int pid = app.pid; 3945 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3946 if (!restarting) { 3947 removeLruProcessLocked(app); 3948 if (pid > 0) { 3949 ProcessList.remove(pid); 3950 } 3951 } 3952 3953 if (mProfileProc == app) { 3954 clearProfilerLocked(); 3955 } 3956 3957 // Remove this application's activities from active lists. 3958 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3959 3960 app.activities.clear(); 3961 3962 if (app.instrumentationClass != null) { 3963 Slog.w(TAG, "Crash of app " + app.processName 3964 + " running instrumentation " + app.instrumentationClass); 3965 Bundle info = new Bundle(); 3966 info.putString("shortMsg", "Process crashed."); 3967 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3968 } 3969 3970 if (!restarting) { 3971 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3972 // If there was nothing to resume, and we are not already 3973 // restarting this process, but there is a visible activity that 3974 // is hosted by the process... then make sure all visible 3975 // activities are running, taking care of restarting this 3976 // process. 3977 if (hasVisibleActivities) { 3978 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3979 } 3980 } 3981 } 3982 } 3983 3984 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3985 IBinder threadBinder = thread.asBinder(); 3986 // Find the application record. 3987 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3988 ProcessRecord rec = mLruProcesses.get(i); 3989 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3990 return i; 3991 } 3992 } 3993 return -1; 3994 } 3995 3996 final ProcessRecord getRecordForAppLocked( 3997 IApplicationThread thread) { 3998 if (thread == null) { 3999 return null; 4000 } 4001 4002 int appIndex = getLRURecordIndexForAppLocked(thread); 4003 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4004 } 4005 4006 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4007 // If there are no longer any background processes running, 4008 // and the app that died was not running instrumentation, 4009 // then tell everyone we are now low on memory. 4010 boolean haveBg = false; 4011 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4012 ProcessRecord rec = mLruProcesses.get(i); 4013 if (rec.thread != null 4014 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4015 haveBg = true; 4016 break; 4017 } 4018 } 4019 4020 if (!haveBg) { 4021 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4022 if (doReport) { 4023 long now = SystemClock.uptimeMillis(); 4024 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4025 doReport = false; 4026 } else { 4027 mLastMemUsageReportTime = now; 4028 } 4029 } 4030 final ArrayList<ProcessMemInfo> memInfos 4031 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4032 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4033 long now = SystemClock.uptimeMillis(); 4034 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4035 ProcessRecord rec = mLruProcesses.get(i); 4036 if (rec == dyingProc || rec.thread == null) { 4037 continue; 4038 } 4039 if (doReport) { 4040 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4041 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4042 } 4043 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4044 // The low memory report is overriding any current 4045 // state for a GC request. Make sure to do 4046 // heavy/important/visible/foreground processes first. 4047 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4048 rec.lastRequestedGc = 0; 4049 } else { 4050 rec.lastRequestedGc = rec.lastLowMemory; 4051 } 4052 rec.reportLowMemory = true; 4053 rec.lastLowMemory = now; 4054 mProcessesToGc.remove(rec); 4055 addProcessToGcListLocked(rec); 4056 } 4057 } 4058 if (doReport) { 4059 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4060 mHandler.sendMessage(msg); 4061 } 4062 scheduleAppGcsLocked(); 4063 } 4064 } 4065 4066 final void appDiedLocked(ProcessRecord app, int pid, 4067 IApplicationThread thread) { 4068 4069 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4070 synchronized (stats) { 4071 stats.noteProcessDiedLocked(app.info.uid, pid); 4072 } 4073 4074 Process.killProcessGroup(app.info.uid, pid); 4075 4076 // Clean up already done if the process has been re-started. 4077 if (app.pid == pid && app.thread != null && 4078 app.thread.asBinder() == thread.asBinder()) { 4079 boolean doLowMem = app.instrumentationClass == null; 4080 boolean doOomAdj = doLowMem; 4081 if (!app.killedByAm) { 4082 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4083 + ") has died."); 4084 mAllowLowerMemLevel = true; 4085 } else { 4086 // Note that we always want to do oom adj to update our state with the 4087 // new number of procs. 4088 mAllowLowerMemLevel = false; 4089 doLowMem = false; 4090 } 4091 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4092 if (DEBUG_CLEANUP) Slog.v( 4093 TAG, "Dying app: " + app + ", pid: " + pid 4094 + ", thread: " + thread.asBinder()); 4095 handleAppDiedLocked(app, false, true); 4096 4097 if (doOomAdj) { 4098 updateOomAdjLocked(); 4099 } 4100 if (doLowMem) { 4101 doLowMemReportIfNeededLocked(app); 4102 } 4103 } else if (app.pid != pid) { 4104 // A new process has already been started. 4105 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4106 + ") has died and restarted (pid " + app.pid + ")."); 4107 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4108 } else if (DEBUG_PROCESSES) { 4109 Slog.d(TAG, "Received spurious death notification for thread " 4110 + thread.asBinder()); 4111 } 4112 } 4113 4114 /** 4115 * If a stack trace dump file is configured, dump process stack traces. 4116 * @param clearTraces causes the dump file to be erased prior to the new 4117 * traces being written, if true; when false, the new traces will be 4118 * appended to any existing file content. 4119 * @param firstPids of dalvik VM processes to dump stack traces for first 4120 * @param lastPids of dalvik VM processes to dump stack traces for last 4121 * @param nativeProcs optional list of native process names to dump stack crawls 4122 * @return file containing stack traces, or null if no dump file is configured 4123 */ 4124 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4125 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4126 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4127 if (tracesPath == null || tracesPath.length() == 0) { 4128 return null; 4129 } 4130 4131 File tracesFile = new File(tracesPath); 4132 try { 4133 File tracesDir = tracesFile.getParentFile(); 4134 if (!tracesDir.exists()) { 4135 tracesFile.mkdirs(); 4136 if (!SELinux.restorecon(tracesDir)) { 4137 return null; 4138 } 4139 } 4140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4141 4142 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4143 tracesFile.createNewFile(); 4144 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4145 } catch (IOException e) { 4146 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4147 return null; 4148 } 4149 4150 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4151 return tracesFile; 4152 } 4153 4154 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4155 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4156 // Use a FileObserver to detect when traces finish writing. 4157 // The order of traces is considered important to maintain for legibility. 4158 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4159 @Override 4160 public synchronized void onEvent(int event, String path) { notify(); } 4161 }; 4162 4163 try { 4164 observer.startWatching(); 4165 4166 // First collect all of the stacks of the most important pids. 4167 if (firstPids != null) { 4168 try { 4169 int num = firstPids.size(); 4170 for (int i = 0; i < num; i++) { 4171 synchronized (observer) { 4172 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4173 observer.wait(200); // Wait for write-close, give up after 200msec 4174 } 4175 } 4176 } catch (InterruptedException e) { 4177 Log.wtf(TAG, e); 4178 } 4179 } 4180 4181 // Next collect the stacks of the native pids 4182 if (nativeProcs != null) { 4183 int[] pids = Process.getPidsForCommands(nativeProcs); 4184 if (pids != null) { 4185 for (int pid : pids) { 4186 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4187 } 4188 } 4189 } 4190 4191 // Lastly, measure CPU usage. 4192 if (processCpuTracker != null) { 4193 processCpuTracker.init(); 4194 System.gc(); 4195 processCpuTracker.update(); 4196 try { 4197 synchronized (processCpuTracker) { 4198 processCpuTracker.wait(500); // measure over 1/2 second. 4199 } 4200 } catch (InterruptedException e) { 4201 } 4202 processCpuTracker.update(); 4203 4204 // We'll take the stack crawls of just the top apps using CPU. 4205 final int N = processCpuTracker.countWorkingStats(); 4206 int numProcs = 0; 4207 for (int i=0; i<N && numProcs<5; i++) { 4208 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4209 if (lastPids.indexOfKey(stats.pid) >= 0) { 4210 numProcs++; 4211 try { 4212 synchronized (observer) { 4213 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4214 observer.wait(200); // Wait for write-close, give up after 200msec 4215 } 4216 } catch (InterruptedException e) { 4217 Log.wtf(TAG, e); 4218 } 4219 4220 } 4221 } 4222 } 4223 } finally { 4224 observer.stopWatching(); 4225 } 4226 } 4227 4228 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4229 if (true || IS_USER_BUILD) { 4230 return; 4231 } 4232 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4233 if (tracesPath == null || tracesPath.length() == 0) { 4234 return; 4235 } 4236 4237 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4238 StrictMode.allowThreadDiskWrites(); 4239 try { 4240 final File tracesFile = new File(tracesPath); 4241 final File tracesDir = tracesFile.getParentFile(); 4242 final File tracesTmp = new File(tracesDir, "__tmp__"); 4243 try { 4244 if (!tracesDir.exists()) { 4245 tracesFile.mkdirs(); 4246 if (!SELinux.restorecon(tracesDir.getPath())) { 4247 return; 4248 } 4249 } 4250 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4251 4252 if (tracesFile.exists()) { 4253 tracesTmp.delete(); 4254 tracesFile.renameTo(tracesTmp); 4255 } 4256 StringBuilder sb = new StringBuilder(); 4257 Time tobj = new Time(); 4258 tobj.set(System.currentTimeMillis()); 4259 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4260 sb.append(": "); 4261 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4262 sb.append(" since "); 4263 sb.append(msg); 4264 FileOutputStream fos = new FileOutputStream(tracesFile); 4265 fos.write(sb.toString().getBytes()); 4266 if (app == null) { 4267 fos.write("\n*** No application process!".getBytes()); 4268 } 4269 fos.close(); 4270 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4271 } catch (IOException e) { 4272 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4273 return; 4274 } 4275 4276 if (app != null) { 4277 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4278 firstPids.add(app.pid); 4279 dumpStackTraces(tracesPath, firstPids, null, null, null); 4280 } 4281 4282 File lastTracesFile = null; 4283 File curTracesFile = null; 4284 for (int i=9; i>=0; i--) { 4285 String name = String.format(Locale.US, "slow%02d.txt", i); 4286 curTracesFile = new File(tracesDir, name); 4287 if (curTracesFile.exists()) { 4288 if (lastTracesFile != null) { 4289 curTracesFile.renameTo(lastTracesFile); 4290 } else { 4291 curTracesFile.delete(); 4292 } 4293 } 4294 lastTracesFile = curTracesFile; 4295 } 4296 tracesFile.renameTo(curTracesFile); 4297 if (tracesTmp.exists()) { 4298 tracesTmp.renameTo(tracesFile); 4299 } 4300 } finally { 4301 StrictMode.setThreadPolicy(oldPolicy); 4302 } 4303 } 4304 4305 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4306 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4307 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4308 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4309 4310 if (mController != null) { 4311 try { 4312 // 0 == continue, -1 = kill process immediately 4313 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4314 if (res < 0 && app.pid != MY_PID) { 4315 Process.killProcess(app.pid); 4316 Process.killProcessGroup(app.info.uid, app.pid); 4317 } 4318 } catch (RemoteException e) { 4319 mController = null; 4320 Watchdog.getInstance().setActivityController(null); 4321 } 4322 } 4323 4324 long anrTime = SystemClock.uptimeMillis(); 4325 if (MONITOR_CPU_USAGE) { 4326 updateCpuStatsNow(); 4327 } 4328 4329 synchronized (this) { 4330 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4331 if (mShuttingDown) { 4332 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4333 return; 4334 } else if (app.notResponding) { 4335 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4336 return; 4337 } else if (app.crashing) { 4338 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4339 return; 4340 } 4341 4342 // In case we come through here for the same app before completing 4343 // this one, mark as anring now so we will bail out. 4344 app.notResponding = true; 4345 4346 // Log the ANR to the event log. 4347 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4348 app.processName, app.info.flags, annotation); 4349 4350 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4351 firstPids.add(app.pid); 4352 4353 int parentPid = app.pid; 4354 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4355 if (parentPid != app.pid) firstPids.add(parentPid); 4356 4357 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4358 4359 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4360 ProcessRecord r = mLruProcesses.get(i); 4361 if (r != null && r.thread != null) { 4362 int pid = r.pid; 4363 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4364 if (r.persistent) { 4365 firstPids.add(pid); 4366 } else { 4367 lastPids.put(pid, Boolean.TRUE); 4368 } 4369 } 4370 } 4371 } 4372 } 4373 4374 // Log the ANR to the main log. 4375 StringBuilder info = new StringBuilder(); 4376 info.setLength(0); 4377 info.append("ANR in ").append(app.processName); 4378 if (activity != null && activity.shortComponentName != null) { 4379 info.append(" (").append(activity.shortComponentName).append(")"); 4380 } 4381 info.append("\n"); 4382 info.append("PID: ").append(app.pid).append("\n"); 4383 if (annotation != null) { 4384 info.append("Reason: ").append(annotation).append("\n"); 4385 } 4386 if (parent != null && parent != activity) { 4387 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4388 } 4389 4390 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4391 4392 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4393 NATIVE_STACKS_OF_INTEREST); 4394 4395 String cpuInfo = null; 4396 if (MONITOR_CPU_USAGE) { 4397 updateCpuStatsNow(); 4398 synchronized (mProcessCpuThread) { 4399 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4400 } 4401 info.append(processCpuTracker.printCurrentLoad()); 4402 info.append(cpuInfo); 4403 } 4404 4405 info.append(processCpuTracker.printCurrentState(anrTime)); 4406 4407 Slog.e(TAG, info.toString()); 4408 if (tracesFile == null) { 4409 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4410 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4411 } 4412 4413 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4414 cpuInfo, tracesFile, null); 4415 4416 if (mController != null) { 4417 try { 4418 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4419 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4420 if (res != 0) { 4421 if (res < 0 && app.pid != MY_PID) { 4422 Process.killProcess(app.pid); 4423 Process.killProcessGroup(app.info.uid, app.pid); 4424 } else { 4425 synchronized (this) { 4426 mServices.scheduleServiceTimeoutLocked(app); 4427 } 4428 } 4429 return; 4430 } 4431 } catch (RemoteException e) { 4432 mController = null; 4433 Watchdog.getInstance().setActivityController(null); 4434 } 4435 } 4436 4437 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4438 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4439 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4440 4441 synchronized (this) { 4442 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4443 killUnneededProcessLocked(app, "background ANR"); 4444 return; 4445 } 4446 4447 // Set the app's notResponding state, and look up the errorReportReceiver 4448 makeAppNotRespondingLocked(app, 4449 activity != null ? activity.shortComponentName : null, 4450 annotation != null ? "ANR " + annotation : "ANR", 4451 info.toString()); 4452 4453 // Bring up the infamous App Not Responding dialog 4454 Message msg = Message.obtain(); 4455 HashMap<String, Object> map = new HashMap<String, Object>(); 4456 msg.what = SHOW_NOT_RESPONDING_MSG; 4457 msg.obj = map; 4458 msg.arg1 = aboveSystem ? 1 : 0; 4459 map.put("app", app); 4460 if (activity != null) { 4461 map.put("activity", activity); 4462 } 4463 4464 mHandler.sendMessage(msg); 4465 } 4466 } 4467 4468 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4469 if (!mLaunchWarningShown) { 4470 mLaunchWarningShown = true; 4471 mHandler.post(new Runnable() { 4472 @Override 4473 public void run() { 4474 synchronized (ActivityManagerService.this) { 4475 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4476 d.show(); 4477 mHandler.postDelayed(new Runnable() { 4478 @Override 4479 public void run() { 4480 synchronized (ActivityManagerService.this) { 4481 d.dismiss(); 4482 mLaunchWarningShown = false; 4483 } 4484 } 4485 }, 4000); 4486 } 4487 } 4488 }); 4489 } 4490 } 4491 4492 @Override 4493 public boolean clearApplicationUserData(final String packageName, 4494 final IPackageDataObserver observer, int userId) { 4495 enforceNotIsolatedCaller("clearApplicationUserData"); 4496 int uid = Binder.getCallingUid(); 4497 int pid = Binder.getCallingPid(); 4498 userId = handleIncomingUser(pid, uid, 4499 userId, false, true, "clearApplicationUserData", null); 4500 long callingId = Binder.clearCallingIdentity(); 4501 try { 4502 IPackageManager pm = AppGlobals.getPackageManager(); 4503 int pkgUid = -1; 4504 synchronized(this) { 4505 try { 4506 pkgUid = pm.getPackageUid(packageName, userId); 4507 } catch (RemoteException e) { 4508 } 4509 if (pkgUid == -1) { 4510 Slog.w(TAG, "Invalid packageName: " + packageName); 4511 if (observer != null) { 4512 try { 4513 observer.onRemoveCompleted(packageName, false); 4514 } catch (RemoteException e) { 4515 Slog.i(TAG, "Observer no longer exists."); 4516 } 4517 } 4518 return false; 4519 } 4520 if (uid == pkgUid || checkComponentPermission( 4521 android.Manifest.permission.CLEAR_APP_USER_DATA, 4522 pid, uid, -1, true) 4523 == PackageManager.PERMISSION_GRANTED) { 4524 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4525 } else { 4526 throw new SecurityException("PID " + pid + " does not have permission " 4527 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4528 + " of package " + packageName); 4529 } 4530 } 4531 4532 try { 4533 // Clear application user data 4534 pm.clearApplicationUserData(packageName, observer, userId); 4535 4536 // Remove all permissions granted from/to this package 4537 removeUriPermissionsForPackageLocked(packageName, userId, true); 4538 4539 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4540 Uri.fromParts("package", packageName, null)); 4541 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4542 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4543 null, null, 0, null, null, null, false, false, userId); 4544 } catch (RemoteException e) { 4545 } 4546 } finally { 4547 Binder.restoreCallingIdentity(callingId); 4548 } 4549 return true; 4550 } 4551 4552 @Override 4553 public void killBackgroundProcesses(final String packageName, int userId) { 4554 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4555 != PackageManager.PERMISSION_GRANTED && 4556 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4557 != PackageManager.PERMISSION_GRANTED) { 4558 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4559 + Binder.getCallingPid() 4560 + ", uid=" + Binder.getCallingUid() 4561 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4562 Slog.w(TAG, msg); 4563 throw new SecurityException(msg); 4564 } 4565 4566 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4567 userId, true, true, "killBackgroundProcesses", null); 4568 long callingId = Binder.clearCallingIdentity(); 4569 try { 4570 IPackageManager pm = AppGlobals.getPackageManager(); 4571 synchronized(this) { 4572 int appId = -1; 4573 try { 4574 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4575 } catch (RemoteException e) { 4576 } 4577 if (appId == -1) { 4578 Slog.w(TAG, "Invalid packageName: " + packageName); 4579 return; 4580 } 4581 killPackageProcessesLocked(packageName, appId, userId, 4582 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4583 } 4584 } finally { 4585 Binder.restoreCallingIdentity(callingId); 4586 } 4587 } 4588 4589 @Override 4590 public void killAllBackgroundProcesses() { 4591 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4592 != PackageManager.PERMISSION_GRANTED) { 4593 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4594 + Binder.getCallingPid() 4595 + ", uid=" + Binder.getCallingUid() 4596 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4597 Slog.w(TAG, msg); 4598 throw new SecurityException(msg); 4599 } 4600 4601 long callingId = Binder.clearCallingIdentity(); 4602 try { 4603 synchronized(this) { 4604 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4605 final int NP = mProcessNames.getMap().size(); 4606 for (int ip=0; ip<NP; ip++) { 4607 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4608 final int NA = apps.size(); 4609 for (int ia=0; ia<NA; ia++) { 4610 ProcessRecord app = apps.valueAt(ia); 4611 if (app.persistent) { 4612 // we don't kill persistent processes 4613 continue; 4614 } 4615 if (app.removed) { 4616 procs.add(app); 4617 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4618 app.removed = true; 4619 procs.add(app); 4620 } 4621 } 4622 } 4623 4624 int N = procs.size(); 4625 for (int i=0; i<N; i++) { 4626 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4627 } 4628 mAllowLowerMemLevel = true; 4629 updateOomAdjLocked(); 4630 doLowMemReportIfNeededLocked(null); 4631 } 4632 } finally { 4633 Binder.restoreCallingIdentity(callingId); 4634 } 4635 } 4636 4637 @Override 4638 public void forceStopPackage(final String packageName, int userId) { 4639 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4640 != PackageManager.PERMISSION_GRANTED) { 4641 String msg = "Permission Denial: forceStopPackage() from pid=" 4642 + Binder.getCallingPid() 4643 + ", uid=" + Binder.getCallingUid() 4644 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4645 Slog.w(TAG, msg); 4646 throw new SecurityException(msg); 4647 } 4648 final int callingPid = Binder.getCallingPid(); 4649 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4650 userId, true, true, "forceStopPackage", null); 4651 long callingId = Binder.clearCallingIdentity(); 4652 try { 4653 IPackageManager pm = AppGlobals.getPackageManager(); 4654 synchronized(this) { 4655 int[] users = userId == UserHandle.USER_ALL 4656 ? getUsersLocked() : new int[] { userId }; 4657 for (int user : users) { 4658 int pkgUid = -1; 4659 try { 4660 pkgUid = pm.getPackageUid(packageName, user); 4661 } catch (RemoteException e) { 4662 } 4663 if (pkgUid == -1) { 4664 Slog.w(TAG, "Invalid packageName: " + packageName); 4665 continue; 4666 } 4667 try { 4668 pm.setPackageStoppedState(packageName, true, user); 4669 } catch (RemoteException e) { 4670 } catch (IllegalArgumentException e) { 4671 Slog.w(TAG, "Failed trying to unstop package " 4672 + packageName + ": " + e); 4673 } 4674 if (isUserRunningLocked(user, false)) { 4675 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4676 } 4677 } 4678 } 4679 } finally { 4680 Binder.restoreCallingIdentity(callingId); 4681 } 4682 } 4683 4684 /* 4685 * The pkg name and app id have to be specified. 4686 */ 4687 @Override 4688 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4689 if (pkg == null) { 4690 return; 4691 } 4692 // Make sure the uid is valid. 4693 if (appid < 0) { 4694 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4695 return; 4696 } 4697 int callerUid = Binder.getCallingUid(); 4698 // Only the system server can kill an application 4699 if (callerUid == Process.SYSTEM_UID) { 4700 // Post an aysnc message to kill the application 4701 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4702 msg.arg1 = appid; 4703 msg.arg2 = 0; 4704 Bundle bundle = new Bundle(); 4705 bundle.putString("pkg", pkg); 4706 bundle.putString("reason", reason); 4707 msg.obj = bundle; 4708 mHandler.sendMessage(msg); 4709 } else { 4710 throw new SecurityException(callerUid + " cannot kill pkg: " + 4711 pkg); 4712 } 4713 } 4714 4715 @Override 4716 public void closeSystemDialogs(String reason) { 4717 enforceNotIsolatedCaller("closeSystemDialogs"); 4718 4719 final int pid = Binder.getCallingPid(); 4720 final int uid = Binder.getCallingUid(); 4721 final long origId = Binder.clearCallingIdentity(); 4722 try { 4723 synchronized (this) { 4724 // Only allow this from foreground processes, so that background 4725 // applications can't abuse it to prevent system UI from being shown. 4726 if (uid >= Process.FIRST_APPLICATION_UID) { 4727 ProcessRecord proc; 4728 synchronized (mPidsSelfLocked) { 4729 proc = mPidsSelfLocked.get(pid); 4730 } 4731 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4732 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4733 + " from background process " + proc); 4734 return; 4735 } 4736 } 4737 closeSystemDialogsLocked(reason); 4738 } 4739 } finally { 4740 Binder.restoreCallingIdentity(origId); 4741 } 4742 } 4743 4744 void closeSystemDialogsLocked(String reason) { 4745 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4746 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4747 | Intent.FLAG_RECEIVER_FOREGROUND); 4748 if (reason != null) { 4749 intent.putExtra("reason", reason); 4750 } 4751 mWindowManager.closeSystemDialogs(reason); 4752 4753 mStackSupervisor.closeSystemDialogsLocked(); 4754 4755 broadcastIntentLocked(null, null, intent, null, 4756 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4757 Process.SYSTEM_UID, UserHandle.USER_ALL); 4758 } 4759 4760 @Override 4761 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4762 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4763 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4764 for (int i=pids.length-1; i>=0; i--) { 4765 ProcessRecord proc; 4766 int oomAdj; 4767 synchronized (this) { 4768 synchronized (mPidsSelfLocked) { 4769 proc = mPidsSelfLocked.get(pids[i]); 4770 oomAdj = proc != null ? proc.setAdj : 0; 4771 } 4772 } 4773 infos[i] = new Debug.MemoryInfo(); 4774 Debug.getMemoryInfo(pids[i], infos[i]); 4775 if (proc != null) { 4776 synchronized (this) { 4777 if (proc.thread != null && proc.setAdj == oomAdj) { 4778 // Record this for posterity if the process has been stable. 4779 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4780 infos[i].getTotalUss(), false, proc.pkgList); 4781 } 4782 } 4783 } 4784 } 4785 return infos; 4786 } 4787 4788 @Override 4789 public long[] getProcessPss(int[] pids) { 4790 enforceNotIsolatedCaller("getProcessPss"); 4791 long[] pss = new long[pids.length]; 4792 for (int i=pids.length-1; i>=0; i--) { 4793 ProcessRecord proc; 4794 int oomAdj; 4795 synchronized (this) { 4796 synchronized (mPidsSelfLocked) { 4797 proc = mPidsSelfLocked.get(pids[i]); 4798 oomAdj = proc != null ? proc.setAdj : 0; 4799 } 4800 } 4801 long[] tmpUss = new long[1]; 4802 pss[i] = Debug.getPss(pids[i], tmpUss); 4803 if (proc != null) { 4804 synchronized (this) { 4805 if (proc.thread != null && proc.setAdj == oomAdj) { 4806 // Record this for posterity if the process has been stable. 4807 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4808 } 4809 } 4810 } 4811 } 4812 return pss; 4813 } 4814 4815 @Override 4816 public void killApplicationProcess(String processName, int uid) { 4817 if (processName == null) { 4818 return; 4819 } 4820 4821 int callerUid = Binder.getCallingUid(); 4822 // Only the system server can kill an application 4823 if (callerUid == Process.SYSTEM_UID) { 4824 synchronized (this) { 4825 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4826 if (app != null && app.thread != null) { 4827 try { 4828 app.thread.scheduleSuicide(); 4829 } catch (RemoteException e) { 4830 // If the other end already died, then our work here is done. 4831 } 4832 } else { 4833 Slog.w(TAG, "Process/uid not found attempting kill of " 4834 + processName + " / " + uid); 4835 } 4836 } 4837 } else { 4838 throw new SecurityException(callerUid + " cannot kill app process: " + 4839 processName); 4840 } 4841 } 4842 4843 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4844 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4845 false, true, false, false, UserHandle.getUserId(uid), reason); 4846 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4847 Uri.fromParts("package", packageName, null)); 4848 if (!mProcessesReady) { 4849 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4850 | Intent.FLAG_RECEIVER_FOREGROUND); 4851 } 4852 intent.putExtra(Intent.EXTRA_UID, uid); 4853 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4854 broadcastIntentLocked(null, null, intent, 4855 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4856 false, false, 4857 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4858 } 4859 4860 private void forceStopUserLocked(int userId, String reason) { 4861 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4862 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4863 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4864 | Intent.FLAG_RECEIVER_FOREGROUND); 4865 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4866 broadcastIntentLocked(null, null, intent, 4867 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4868 false, false, 4869 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4870 } 4871 4872 private final boolean killPackageProcessesLocked(String packageName, int appId, 4873 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4874 boolean doit, boolean evenPersistent, String reason) { 4875 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4876 4877 // Remove all processes this package may have touched: all with the 4878 // same UID (except for the system or root user), and all whose name 4879 // matches the package name. 4880 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4881 final int NP = mProcessNames.getMap().size(); 4882 for (int ip=0; ip<NP; ip++) { 4883 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4884 final int NA = apps.size(); 4885 for (int ia=0; ia<NA; ia++) { 4886 ProcessRecord app = apps.valueAt(ia); 4887 if (app.persistent && !evenPersistent) { 4888 // we don't kill persistent processes 4889 continue; 4890 } 4891 if (app.removed) { 4892 if (doit) { 4893 procs.add(app); 4894 } 4895 continue; 4896 } 4897 4898 // Skip process if it doesn't meet our oom adj requirement. 4899 if (app.setAdj < minOomAdj) { 4900 continue; 4901 } 4902 4903 // If no package is specified, we call all processes under the 4904 // give user id. 4905 if (packageName == null) { 4906 if (app.userId != userId) { 4907 continue; 4908 } 4909 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4910 continue; 4911 } 4912 // Package has been specified, we want to hit all processes 4913 // that match it. We need to qualify this by the processes 4914 // that are running under the specified app and user ID. 4915 } else { 4916 if (UserHandle.getAppId(app.uid) != appId) { 4917 continue; 4918 } 4919 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4920 continue; 4921 } 4922 if (!app.pkgList.containsKey(packageName)) { 4923 continue; 4924 } 4925 } 4926 4927 // Process has passed all conditions, kill it! 4928 if (!doit) { 4929 return true; 4930 } 4931 app.removed = true; 4932 procs.add(app); 4933 } 4934 } 4935 4936 int N = procs.size(); 4937 for (int i=0; i<N; i++) { 4938 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4939 } 4940 updateOomAdjLocked(); 4941 return N > 0; 4942 } 4943 4944 private final boolean forceStopPackageLocked(String name, int appId, 4945 boolean callerWillRestart, boolean purgeCache, boolean doit, 4946 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4947 int i; 4948 int N; 4949 4950 if (userId == UserHandle.USER_ALL && name == null) { 4951 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4952 } 4953 4954 if (appId < 0 && name != null) { 4955 try { 4956 appId = UserHandle.getAppId( 4957 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4958 } catch (RemoteException e) { 4959 } 4960 } 4961 4962 if (doit) { 4963 if (name != null) { 4964 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4965 + " user=" + userId + ": " + reason); 4966 } else { 4967 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4968 } 4969 4970 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4971 for (int ip=pmap.size()-1; ip>=0; ip--) { 4972 SparseArray<Long> ba = pmap.valueAt(ip); 4973 for (i=ba.size()-1; i>=0; i--) { 4974 boolean remove = false; 4975 final int entUid = ba.keyAt(i); 4976 if (name != null) { 4977 if (userId == UserHandle.USER_ALL) { 4978 if (UserHandle.getAppId(entUid) == appId) { 4979 remove = true; 4980 } 4981 } else { 4982 if (entUid == UserHandle.getUid(userId, appId)) { 4983 remove = true; 4984 } 4985 } 4986 } else if (UserHandle.getUserId(entUid) == userId) { 4987 remove = true; 4988 } 4989 if (remove) { 4990 ba.removeAt(i); 4991 } 4992 } 4993 if (ba.size() == 0) { 4994 pmap.removeAt(ip); 4995 } 4996 } 4997 } 4998 4999 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5000 -100, callerWillRestart, true, doit, evenPersistent, 5001 name == null ? ("stop user " + userId) : ("stop " + name)); 5002 5003 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5004 if (!doit) { 5005 return true; 5006 } 5007 didSomething = true; 5008 } 5009 5010 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5011 if (!doit) { 5012 return true; 5013 } 5014 didSomething = true; 5015 } 5016 5017 if (name == null) { 5018 // Remove all sticky broadcasts from this user. 5019 mStickyBroadcasts.remove(userId); 5020 } 5021 5022 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5023 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5024 userId, providers)) { 5025 if (!doit) { 5026 return true; 5027 } 5028 didSomething = true; 5029 } 5030 N = providers.size(); 5031 for (i=0; i<N; i++) { 5032 removeDyingProviderLocked(null, providers.get(i), true); 5033 } 5034 5035 // Remove transient permissions granted from/to this package/user 5036 removeUriPermissionsForPackageLocked(name, userId, false); 5037 5038 if (name == null || uninstalling) { 5039 // Remove pending intents. For now we only do this when force 5040 // stopping users, because we have some problems when doing this 5041 // for packages -- app widgets are not currently cleaned up for 5042 // such packages, so they can be left with bad pending intents. 5043 if (mIntentSenderRecords.size() > 0) { 5044 Iterator<WeakReference<PendingIntentRecord>> it 5045 = mIntentSenderRecords.values().iterator(); 5046 while (it.hasNext()) { 5047 WeakReference<PendingIntentRecord> wpir = it.next(); 5048 if (wpir == null) { 5049 it.remove(); 5050 continue; 5051 } 5052 PendingIntentRecord pir = wpir.get(); 5053 if (pir == null) { 5054 it.remove(); 5055 continue; 5056 } 5057 if (name == null) { 5058 // Stopping user, remove all objects for the user. 5059 if (pir.key.userId != userId) { 5060 // Not the same user, skip it. 5061 continue; 5062 } 5063 } else { 5064 if (UserHandle.getAppId(pir.uid) != appId) { 5065 // Different app id, skip it. 5066 continue; 5067 } 5068 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5069 // Different user, skip it. 5070 continue; 5071 } 5072 if (!pir.key.packageName.equals(name)) { 5073 // Different package, skip it. 5074 continue; 5075 } 5076 } 5077 if (!doit) { 5078 return true; 5079 } 5080 didSomething = true; 5081 it.remove(); 5082 pir.canceled = true; 5083 if (pir.key.activity != null) { 5084 pir.key.activity.pendingResults.remove(pir.ref); 5085 } 5086 } 5087 } 5088 } 5089 5090 if (doit) { 5091 if (purgeCache && name != null) { 5092 AttributeCache ac = AttributeCache.instance(); 5093 if (ac != null) { 5094 ac.removePackage(name); 5095 } 5096 } 5097 if (mBooted) { 5098 mStackSupervisor.resumeTopActivitiesLocked(); 5099 mStackSupervisor.scheduleIdleLocked(); 5100 } 5101 } 5102 5103 return didSomething; 5104 } 5105 5106 private final boolean removeProcessLocked(ProcessRecord app, 5107 boolean callerWillRestart, boolean allowRestart, String reason) { 5108 final String name = app.processName; 5109 final int uid = app.uid; 5110 if (DEBUG_PROCESSES) Slog.d( 5111 TAG, "Force removing proc " + app.toShortString() + " (" + name 5112 + "/" + uid + ")"); 5113 5114 mProcessNames.remove(name, uid); 5115 mIsolatedProcesses.remove(app.uid); 5116 if (mHeavyWeightProcess == app) { 5117 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5118 mHeavyWeightProcess.userId, 0)); 5119 mHeavyWeightProcess = null; 5120 } 5121 boolean needRestart = false; 5122 if (app.pid > 0 && app.pid != MY_PID) { 5123 int pid = app.pid; 5124 synchronized (mPidsSelfLocked) { 5125 mPidsSelfLocked.remove(pid); 5126 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5127 } 5128 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5129 if (app.isolated) { 5130 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5131 } 5132 killUnneededProcessLocked(app, reason); 5133 Process.killProcessGroup(app.info.uid, app.pid); 5134 handleAppDiedLocked(app, true, allowRestart); 5135 removeLruProcessLocked(app); 5136 5137 if (app.persistent && !app.isolated) { 5138 if (!callerWillRestart) { 5139 addAppLocked(app.info, false, null /* ABI override */); 5140 } else { 5141 needRestart = true; 5142 } 5143 } 5144 } else { 5145 mRemovedProcesses.add(app); 5146 } 5147 5148 return needRestart; 5149 } 5150 5151 private final void processStartTimedOutLocked(ProcessRecord app) { 5152 final int pid = app.pid; 5153 boolean gone = false; 5154 synchronized (mPidsSelfLocked) { 5155 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5156 if (knownApp != null && knownApp.thread == null) { 5157 mPidsSelfLocked.remove(pid); 5158 gone = true; 5159 } 5160 } 5161 5162 if (gone) { 5163 Slog.w(TAG, "Process " + app + " failed to attach"); 5164 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5165 pid, app.uid, app.processName); 5166 mProcessNames.remove(app.processName, app.uid); 5167 mIsolatedProcesses.remove(app.uid); 5168 if (mHeavyWeightProcess == app) { 5169 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5170 mHeavyWeightProcess.userId, 0)); 5171 mHeavyWeightProcess = null; 5172 } 5173 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5174 if (app.isolated) { 5175 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5176 } 5177 // Take care of any launching providers waiting for this process. 5178 checkAppInLaunchingProvidersLocked(app, true); 5179 // Take care of any services that are waiting for the process. 5180 mServices.processStartTimedOutLocked(app); 5181 killUnneededProcessLocked(app, "start timeout"); 5182 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5183 Slog.w(TAG, "Unattached app died before backup, skipping"); 5184 try { 5185 IBackupManager bm = IBackupManager.Stub.asInterface( 5186 ServiceManager.getService(Context.BACKUP_SERVICE)); 5187 bm.agentDisconnected(app.info.packageName); 5188 } catch (RemoteException e) { 5189 // Can't happen; the backup manager is local 5190 } 5191 } 5192 if (isPendingBroadcastProcessLocked(pid)) { 5193 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5194 skipPendingBroadcastLocked(pid); 5195 } 5196 } else { 5197 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5198 } 5199 } 5200 5201 private final boolean attachApplicationLocked(IApplicationThread thread, 5202 int pid) { 5203 5204 // Find the application record that is being attached... either via 5205 // the pid if we are running in multiple processes, or just pull the 5206 // next app record if we are emulating process with anonymous threads. 5207 ProcessRecord app; 5208 if (pid != MY_PID && pid >= 0) { 5209 synchronized (mPidsSelfLocked) { 5210 app = mPidsSelfLocked.get(pid); 5211 } 5212 } else { 5213 app = null; 5214 } 5215 5216 if (app == null) { 5217 Slog.w(TAG, "No pending application record for pid " + pid 5218 + " (IApplicationThread " + thread + "); dropping process"); 5219 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5220 if (pid > 0 && pid != MY_PID) { 5221 Process.killProcessQuiet(pid); 5222 //TODO: Process.killProcessGroup(app.info.uid, pid); 5223 } else { 5224 try { 5225 thread.scheduleExit(); 5226 } catch (Exception e) { 5227 // Ignore exceptions. 5228 } 5229 } 5230 return false; 5231 } 5232 5233 // If this application record is still attached to a previous 5234 // process, clean it up now. 5235 if (app.thread != null) { 5236 handleAppDiedLocked(app, true, true); 5237 } 5238 5239 // Tell the process all about itself. 5240 5241 if (localLOGV) Slog.v( 5242 TAG, "Binding process pid " + pid + " to record " + app); 5243 5244 final String processName = app.processName; 5245 try { 5246 AppDeathRecipient adr = new AppDeathRecipient( 5247 app, pid, thread); 5248 thread.asBinder().linkToDeath(adr, 0); 5249 app.deathRecipient = adr; 5250 } catch (RemoteException e) { 5251 app.resetPackageList(mProcessStats); 5252 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5253 return false; 5254 } 5255 5256 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5257 5258 app.makeActive(thread, mProcessStats); 5259 app.curAdj = app.setAdj = -100; 5260 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5261 app.forcingToForeground = null; 5262 updateProcessForegroundLocked(app, false, false); 5263 app.hasShownUi = false; 5264 app.debugging = false; 5265 app.cached = false; 5266 5267 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5268 5269 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5270 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5271 5272 if (!normalMode) { 5273 Slog.i(TAG, "Launching preboot mode app: " + app); 5274 } 5275 5276 if (localLOGV) Slog.v( 5277 TAG, "New app record " + app 5278 + " thread=" + thread.asBinder() + " pid=" + pid); 5279 try { 5280 int testMode = IApplicationThread.DEBUG_OFF; 5281 if (mDebugApp != null && mDebugApp.equals(processName)) { 5282 testMode = mWaitForDebugger 5283 ? IApplicationThread.DEBUG_WAIT 5284 : IApplicationThread.DEBUG_ON; 5285 app.debugging = true; 5286 if (mDebugTransient) { 5287 mDebugApp = mOrigDebugApp; 5288 mWaitForDebugger = mOrigWaitForDebugger; 5289 } 5290 } 5291 String profileFile = app.instrumentationProfileFile; 5292 ParcelFileDescriptor profileFd = null; 5293 boolean profileAutoStop = false; 5294 if (mProfileApp != null && mProfileApp.equals(processName)) { 5295 mProfileProc = app; 5296 profileFile = mProfileFile; 5297 profileFd = mProfileFd; 5298 profileAutoStop = mAutoStopProfiler; 5299 } 5300 boolean enableOpenGlTrace = false; 5301 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5302 enableOpenGlTrace = true; 5303 mOpenGlTraceApp = null; 5304 } 5305 5306 // If the app is being launched for restore or full backup, set it up specially 5307 boolean isRestrictedBackupMode = false; 5308 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5309 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5310 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5311 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5312 } 5313 5314 ensurePackageDexOpt(app.instrumentationInfo != null 5315 ? app.instrumentationInfo.packageName 5316 : app.info.packageName); 5317 if (app.instrumentationClass != null) { 5318 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5319 } 5320 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5321 + processName + " with config " + mConfiguration); 5322 ApplicationInfo appInfo = app.instrumentationInfo != null 5323 ? app.instrumentationInfo : app.info; 5324 app.compat = compatibilityInfoForPackageLocked(appInfo); 5325 if (profileFd != null) { 5326 profileFd = profileFd.dup(); 5327 } 5328 thread.bindApplication(processName, appInfo, providers, 5329 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5330 app.instrumentationArguments, app.instrumentationWatcher, 5331 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5332 isRestrictedBackupMode || !normalMode, app.persistent, 5333 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5334 mCoreSettingsObserver.getCoreSettingsLocked()); 5335 updateLruProcessLocked(app, false, null); 5336 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5337 } catch (Exception e) { 5338 // todo: Yikes! What should we do? For now we will try to 5339 // start another process, but that could easily get us in 5340 // an infinite loop of restarting processes... 5341 Slog.w(TAG, "Exception thrown during bind!", e); 5342 5343 app.resetPackageList(mProcessStats); 5344 app.unlinkDeathRecipient(); 5345 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5346 return false; 5347 } 5348 5349 // Remove this record from the list of starting applications. 5350 mPersistentStartingProcesses.remove(app); 5351 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5352 "Attach application locked removing on hold: " + app); 5353 mProcessesOnHold.remove(app); 5354 5355 boolean badApp = false; 5356 boolean didSomething = false; 5357 5358 // See if the top visible activity is waiting to run in this process... 5359 if (normalMode) { 5360 try { 5361 if (mStackSupervisor.attachApplicationLocked(app)) { 5362 didSomething = true; 5363 } 5364 } catch (Exception e) { 5365 badApp = true; 5366 } 5367 } 5368 5369 // Find any services that should be running in this process... 5370 if (!badApp) { 5371 try { 5372 didSomething |= mServices.attachApplicationLocked(app, processName); 5373 } catch (Exception e) { 5374 badApp = true; 5375 } 5376 } 5377 5378 // Check if a next-broadcast receiver is in this process... 5379 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5380 try { 5381 didSomething |= sendPendingBroadcastsLocked(app); 5382 } catch (Exception e) { 5383 // If the app died trying to launch the receiver we declare it 'bad' 5384 badApp = true; 5385 } 5386 } 5387 5388 // Check whether the next backup agent is in this process... 5389 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5390 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5391 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5392 try { 5393 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5394 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5395 mBackupTarget.backupMode); 5396 } catch (Exception e) { 5397 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5398 e.printStackTrace(); 5399 } 5400 } 5401 5402 if (badApp) { 5403 // todo: Also need to kill application to deal with all 5404 // kinds of exceptions. 5405 handleAppDiedLocked(app, false, true); 5406 return false; 5407 } 5408 5409 if (!didSomething) { 5410 updateOomAdjLocked(); 5411 } 5412 5413 return true; 5414 } 5415 5416 @Override 5417 public final void attachApplication(IApplicationThread thread) { 5418 synchronized (this) { 5419 int callingPid = Binder.getCallingPid(); 5420 final long origId = Binder.clearCallingIdentity(); 5421 attachApplicationLocked(thread, callingPid); 5422 Binder.restoreCallingIdentity(origId); 5423 } 5424 } 5425 5426 @Override 5427 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5428 final long origId = Binder.clearCallingIdentity(); 5429 synchronized (this) { 5430 ActivityStack stack = ActivityRecord.getStackLocked(token); 5431 if (stack != null) { 5432 ActivityRecord r = 5433 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5434 if (stopProfiling) { 5435 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5436 try { 5437 mProfileFd.close(); 5438 } catch (IOException e) { 5439 } 5440 clearProfilerLocked(); 5441 } 5442 } 5443 } 5444 } 5445 Binder.restoreCallingIdentity(origId); 5446 } 5447 5448 void enableScreenAfterBoot() { 5449 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5450 SystemClock.uptimeMillis()); 5451 mWindowManager.enableScreenAfterBoot(); 5452 5453 synchronized (this) { 5454 updateEventDispatchingLocked(); 5455 } 5456 } 5457 5458 @Override 5459 public void showBootMessage(final CharSequence msg, final boolean always) { 5460 enforceNotIsolatedCaller("showBootMessage"); 5461 mWindowManager.showBootMessage(msg, always); 5462 } 5463 5464 @Override 5465 public void dismissKeyguardOnNextActivity() { 5466 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5467 final long token = Binder.clearCallingIdentity(); 5468 try { 5469 synchronized (this) { 5470 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5471 if (mLockScreenShown) { 5472 mLockScreenShown = false; 5473 comeOutOfSleepIfNeededLocked(); 5474 } 5475 mStackSupervisor.setDismissKeyguard(true); 5476 } 5477 } finally { 5478 Binder.restoreCallingIdentity(token); 5479 } 5480 } 5481 5482 final void finishBooting() { 5483 // Register receivers to handle package update events 5484 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5485 5486 synchronized (this) { 5487 // Ensure that any processes we had put on hold are now started 5488 // up. 5489 final int NP = mProcessesOnHold.size(); 5490 if (NP > 0) { 5491 ArrayList<ProcessRecord> procs = 5492 new ArrayList<ProcessRecord>(mProcessesOnHold); 5493 for (int ip=0; ip<NP; ip++) { 5494 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5495 + procs.get(ip)); 5496 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5497 } 5498 } 5499 5500 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5501 // Start looking for apps that are abusing wake locks. 5502 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5503 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5504 // Tell anyone interested that we are done booting! 5505 SystemProperties.set("sys.boot_completed", "1"); 5506 SystemProperties.set("dev.bootcomplete", "1"); 5507 for (int i=0; i<mStartedUsers.size(); i++) { 5508 UserStartedState uss = mStartedUsers.valueAt(i); 5509 if (uss.mState == UserStartedState.STATE_BOOTING) { 5510 uss.mState = UserStartedState.STATE_RUNNING; 5511 final int userId = mStartedUsers.keyAt(i); 5512 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5513 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5514 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5515 broadcastIntentLocked(null, null, intent, null, 5516 new IIntentReceiver.Stub() { 5517 @Override 5518 public void performReceive(Intent intent, int resultCode, 5519 String data, Bundle extras, boolean ordered, 5520 boolean sticky, int sendingUser) { 5521 synchronized (ActivityManagerService.this) { 5522 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5523 true, false); 5524 } 5525 } 5526 }, 5527 0, null, null, 5528 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5529 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5530 userId); 5531 } 5532 } 5533 scheduleStartProfilesLocked(); 5534 } 5535 } 5536 } 5537 5538 final void ensureBootCompleted() { 5539 boolean booting; 5540 boolean enableScreen; 5541 synchronized (this) { 5542 booting = mBooting; 5543 mBooting = false; 5544 enableScreen = !mBooted; 5545 mBooted = true; 5546 } 5547 5548 if (booting) { 5549 finishBooting(); 5550 } 5551 5552 if (enableScreen) { 5553 enableScreenAfterBoot(); 5554 } 5555 } 5556 5557 @Override 5558 public final void activityResumed(IBinder token) { 5559 final long origId = Binder.clearCallingIdentity(); 5560 synchronized(this) { 5561 ActivityStack stack = ActivityRecord.getStackLocked(token); 5562 if (stack != null) { 5563 ActivityRecord.activityResumedLocked(token); 5564 } 5565 } 5566 Binder.restoreCallingIdentity(origId); 5567 } 5568 5569 @Override 5570 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5571 final long origId = Binder.clearCallingIdentity(); 5572 synchronized(this) { 5573 ActivityStack stack = ActivityRecord.getStackLocked(token); 5574 if (stack != null) { 5575 stack.activityPausedLocked(token, false, persistentState); 5576 } 5577 } 5578 Binder.restoreCallingIdentity(origId); 5579 } 5580 5581 @Override 5582 public final void activityStopped(IBinder token, Bundle icicle, 5583 PersistableBundle persistentState, CharSequence description) { 5584 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5585 5586 // Refuse possible leaked file descriptors 5587 if (icicle != null && icicle.hasFileDescriptors()) { 5588 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5589 } 5590 5591 final long origId = Binder.clearCallingIdentity(); 5592 5593 synchronized (this) { 5594 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5595 if (r != null) { 5596 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5597 } 5598 } 5599 5600 trimApplications(); 5601 5602 Binder.restoreCallingIdentity(origId); 5603 } 5604 5605 @Override 5606 public final void activityDestroyed(IBinder token) { 5607 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5608 synchronized (this) { 5609 ActivityStack stack = ActivityRecord.getStackLocked(token); 5610 if (stack != null) { 5611 stack.activityDestroyedLocked(token); 5612 } 5613 } 5614 } 5615 5616 @Override 5617 public final void mediaResourcesReleased(IBinder token) { 5618 final long origId = Binder.clearCallingIdentity(); 5619 try { 5620 synchronized (this) { 5621 ActivityStack stack = ActivityRecord.getStackLocked(token); 5622 if (stack != null) { 5623 stack.mediaResourcesReleased(token); 5624 } 5625 } 5626 } finally { 5627 Binder.restoreCallingIdentity(origId); 5628 } 5629 } 5630 5631 @Override 5632 public String getCallingPackage(IBinder token) { 5633 synchronized (this) { 5634 ActivityRecord r = getCallingRecordLocked(token); 5635 return r != null ? r.info.packageName : null; 5636 } 5637 } 5638 5639 @Override 5640 public ComponentName getCallingActivity(IBinder token) { 5641 synchronized (this) { 5642 ActivityRecord r = getCallingRecordLocked(token); 5643 return r != null ? r.intent.getComponent() : null; 5644 } 5645 } 5646 5647 private ActivityRecord getCallingRecordLocked(IBinder token) { 5648 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5649 if (r == null) { 5650 return null; 5651 } 5652 return r.resultTo; 5653 } 5654 5655 @Override 5656 public ComponentName getActivityClassForToken(IBinder token) { 5657 synchronized(this) { 5658 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5659 if (r == null) { 5660 return null; 5661 } 5662 return r.intent.getComponent(); 5663 } 5664 } 5665 5666 @Override 5667 public String getPackageForToken(IBinder token) { 5668 synchronized(this) { 5669 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5670 if (r == null) { 5671 return null; 5672 } 5673 return r.packageName; 5674 } 5675 } 5676 5677 @Override 5678 public IIntentSender getIntentSender(int type, 5679 String packageName, IBinder token, String resultWho, 5680 int requestCode, Intent[] intents, String[] resolvedTypes, 5681 int flags, Bundle options, int userId) { 5682 enforceNotIsolatedCaller("getIntentSender"); 5683 // Refuse possible leaked file descriptors 5684 if (intents != null) { 5685 if (intents.length < 1) { 5686 throw new IllegalArgumentException("Intents array length must be >= 1"); 5687 } 5688 for (int i=0; i<intents.length; i++) { 5689 Intent intent = intents[i]; 5690 if (intent != null) { 5691 if (intent.hasFileDescriptors()) { 5692 throw new IllegalArgumentException("File descriptors passed in Intent"); 5693 } 5694 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5695 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5696 throw new IllegalArgumentException( 5697 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5698 } 5699 intents[i] = new Intent(intent); 5700 } 5701 } 5702 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5703 throw new IllegalArgumentException( 5704 "Intent array length does not match resolvedTypes length"); 5705 } 5706 } 5707 if (options != null) { 5708 if (options.hasFileDescriptors()) { 5709 throw new IllegalArgumentException("File descriptors passed in options"); 5710 } 5711 } 5712 5713 synchronized(this) { 5714 int callingUid = Binder.getCallingUid(); 5715 int origUserId = userId; 5716 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5717 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5718 "getIntentSender", null); 5719 if (origUserId == UserHandle.USER_CURRENT) { 5720 // We don't want to evaluate this until the pending intent is 5721 // actually executed. However, we do want to always do the 5722 // security checking for it above. 5723 userId = UserHandle.USER_CURRENT; 5724 } 5725 try { 5726 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5727 int uid = AppGlobals.getPackageManager() 5728 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5729 if (!UserHandle.isSameApp(callingUid, uid)) { 5730 String msg = "Permission Denial: getIntentSender() from pid=" 5731 + Binder.getCallingPid() 5732 + ", uid=" + Binder.getCallingUid() 5733 + ", (need uid=" + uid + ")" 5734 + " is not allowed to send as package " + packageName; 5735 Slog.w(TAG, msg); 5736 throw new SecurityException(msg); 5737 } 5738 } 5739 5740 return getIntentSenderLocked(type, packageName, callingUid, userId, 5741 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5742 5743 } catch (RemoteException e) { 5744 throw new SecurityException(e); 5745 } 5746 } 5747 } 5748 5749 IIntentSender getIntentSenderLocked(int type, String packageName, 5750 int callingUid, int userId, IBinder token, String resultWho, 5751 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5752 Bundle options) { 5753 if (DEBUG_MU) 5754 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5755 ActivityRecord activity = null; 5756 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5757 activity = ActivityRecord.isInStackLocked(token); 5758 if (activity == null) { 5759 return null; 5760 } 5761 if (activity.finishing) { 5762 return null; 5763 } 5764 } 5765 5766 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5767 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5768 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5769 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5770 |PendingIntent.FLAG_UPDATE_CURRENT); 5771 5772 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5773 type, packageName, activity, resultWho, 5774 requestCode, intents, resolvedTypes, flags, options, userId); 5775 WeakReference<PendingIntentRecord> ref; 5776 ref = mIntentSenderRecords.get(key); 5777 PendingIntentRecord rec = ref != null ? ref.get() : null; 5778 if (rec != null) { 5779 if (!cancelCurrent) { 5780 if (updateCurrent) { 5781 if (rec.key.requestIntent != null) { 5782 rec.key.requestIntent.replaceExtras(intents != null ? 5783 intents[intents.length - 1] : null); 5784 } 5785 if (intents != null) { 5786 intents[intents.length-1] = rec.key.requestIntent; 5787 rec.key.allIntents = intents; 5788 rec.key.allResolvedTypes = resolvedTypes; 5789 } else { 5790 rec.key.allIntents = null; 5791 rec.key.allResolvedTypes = null; 5792 } 5793 } 5794 return rec; 5795 } 5796 rec.canceled = true; 5797 mIntentSenderRecords.remove(key); 5798 } 5799 if (noCreate) { 5800 return rec; 5801 } 5802 rec = new PendingIntentRecord(this, key, callingUid); 5803 mIntentSenderRecords.put(key, rec.ref); 5804 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5805 if (activity.pendingResults == null) { 5806 activity.pendingResults 5807 = new HashSet<WeakReference<PendingIntentRecord>>(); 5808 } 5809 activity.pendingResults.add(rec.ref); 5810 } 5811 return rec; 5812 } 5813 5814 @Override 5815 public void cancelIntentSender(IIntentSender sender) { 5816 if (!(sender instanceof PendingIntentRecord)) { 5817 return; 5818 } 5819 synchronized(this) { 5820 PendingIntentRecord rec = (PendingIntentRecord)sender; 5821 try { 5822 int uid = AppGlobals.getPackageManager() 5823 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5824 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5825 String msg = "Permission Denial: cancelIntentSender() from pid=" 5826 + Binder.getCallingPid() 5827 + ", uid=" + Binder.getCallingUid() 5828 + " is not allowed to cancel packges " 5829 + rec.key.packageName; 5830 Slog.w(TAG, msg); 5831 throw new SecurityException(msg); 5832 } 5833 } catch (RemoteException e) { 5834 throw new SecurityException(e); 5835 } 5836 cancelIntentSenderLocked(rec, true); 5837 } 5838 } 5839 5840 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5841 rec.canceled = true; 5842 mIntentSenderRecords.remove(rec.key); 5843 if (cleanActivity && rec.key.activity != null) { 5844 rec.key.activity.pendingResults.remove(rec.ref); 5845 } 5846 } 5847 5848 @Override 5849 public String getPackageForIntentSender(IIntentSender pendingResult) { 5850 if (!(pendingResult instanceof PendingIntentRecord)) { 5851 return null; 5852 } 5853 try { 5854 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5855 return res.key.packageName; 5856 } catch (ClassCastException e) { 5857 } 5858 return null; 5859 } 5860 5861 @Override 5862 public int getUidForIntentSender(IIntentSender sender) { 5863 if (sender instanceof PendingIntentRecord) { 5864 try { 5865 PendingIntentRecord res = (PendingIntentRecord)sender; 5866 return res.uid; 5867 } catch (ClassCastException e) { 5868 } 5869 } 5870 return -1; 5871 } 5872 5873 @Override 5874 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5875 if (!(pendingResult instanceof PendingIntentRecord)) { 5876 return false; 5877 } 5878 try { 5879 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5880 if (res.key.allIntents == null) { 5881 return false; 5882 } 5883 for (int i=0; i<res.key.allIntents.length; i++) { 5884 Intent intent = res.key.allIntents[i]; 5885 if (intent.getPackage() != null && intent.getComponent() != null) { 5886 return false; 5887 } 5888 } 5889 return true; 5890 } catch (ClassCastException e) { 5891 } 5892 return false; 5893 } 5894 5895 @Override 5896 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5897 if (!(pendingResult instanceof PendingIntentRecord)) { 5898 return false; 5899 } 5900 try { 5901 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5902 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5903 return true; 5904 } 5905 return false; 5906 } catch (ClassCastException e) { 5907 } 5908 return false; 5909 } 5910 5911 @Override 5912 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5913 if (!(pendingResult instanceof PendingIntentRecord)) { 5914 return null; 5915 } 5916 try { 5917 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5918 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5919 } catch (ClassCastException e) { 5920 } 5921 return null; 5922 } 5923 5924 @Override 5925 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5926 if (!(pendingResult instanceof PendingIntentRecord)) { 5927 return null; 5928 } 5929 try { 5930 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5931 Intent intent = res.key.requestIntent; 5932 if (intent != null) { 5933 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5934 || res.lastTagPrefix.equals(prefix))) { 5935 return res.lastTag; 5936 } 5937 res.lastTagPrefix = prefix; 5938 StringBuilder sb = new StringBuilder(128); 5939 if (prefix != null) { 5940 sb.append(prefix); 5941 } 5942 if (intent.getAction() != null) { 5943 sb.append(intent.getAction()); 5944 } else if (intent.getComponent() != null) { 5945 intent.getComponent().appendShortString(sb); 5946 } else { 5947 sb.append("?"); 5948 } 5949 return res.lastTag = sb.toString(); 5950 } 5951 } catch (ClassCastException e) { 5952 } 5953 return null; 5954 } 5955 5956 @Override 5957 public void setProcessLimit(int max) { 5958 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5959 "setProcessLimit()"); 5960 synchronized (this) { 5961 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5962 mProcessLimitOverride = max; 5963 } 5964 trimApplications(); 5965 } 5966 5967 @Override 5968 public int getProcessLimit() { 5969 synchronized (this) { 5970 return mProcessLimitOverride; 5971 } 5972 } 5973 5974 void foregroundTokenDied(ForegroundToken token) { 5975 synchronized (ActivityManagerService.this) { 5976 synchronized (mPidsSelfLocked) { 5977 ForegroundToken cur 5978 = mForegroundProcesses.get(token.pid); 5979 if (cur != token) { 5980 return; 5981 } 5982 mForegroundProcesses.remove(token.pid); 5983 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5984 if (pr == null) { 5985 return; 5986 } 5987 pr.forcingToForeground = null; 5988 updateProcessForegroundLocked(pr, false, false); 5989 } 5990 updateOomAdjLocked(); 5991 } 5992 } 5993 5994 @Override 5995 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5996 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5997 "setProcessForeground()"); 5998 synchronized(this) { 5999 boolean changed = false; 6000 6001 synchronized (mPidsSelfLocked) { 6002 ProcessRecord pr = mPidsSelfLocked.get(pid); 6003 if (pr == null && isForeground) { 6004 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6005 return; 6006 } 6007 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6008 if (oldToken != null) { 6009 oldToken.token.unlinkToDeath(oldToken, 0); 6010 mForegroundProcesses.remove(pid); 6011 if (pr != null) { 6012 pr.forcingToForeground = null; 6013 } 6014 changed = true; 6015 } 6016 if (isForeground && token != null) { 6017 ForegroundToken newToken = new ForegroundToken() { 6018 @Override 6019 public void binderDied() { 6020 foregroundTokenDied(this); 6021 } 6022 }; 6023 newToken.pid = pid; 6024 newToken.token = token; 6025 try { 6026 token.linkToDeath(newToken, 0); 6027 mForegroundProcesses.put(pid, newToken); 6028 pr.forcingToForeground = token; 6029 changed = true; 6030 } catch (RemoteException e) { 6031 // If the process died while doing this, we will later 6032 // do the cleanup with the process death link. 6033 } 6034 } 6035 } 6036 6037 if (changed) { 6038 updateOomAdjLocked(); 6039 } 6040 } 6041 } 6042 6043 // ========================================================= 6044 // PERMISSIONS 6045 // ========================================================= 6046 6047 static class PermissionController extends IPermissionController.Stub { 6048 ActivityManagerService mActivityManagerService; 6049 PermissionController(ActivityManagerService activityManagerService) { 6050 mActivityManagerService = activityManagerService; 6051 } 6052 6053 @Override 6054 public boolean checkPermission(String permission, int pid, int uid) { 6055 return mActivityManagerService.checkPermission(permission, pid, 6056 uid) == PackageManager.PERMISSION_GRANTED; 6057 } 6058 } 6059 6060 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6061 @Override 6062 public int checkComponentPermission(String permission, int pid, int uid, 6063 int owningUid, boolean exported) { 6064 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6065 owningUid, exported); 6066 } 6067 6068 @Override 6069 public Object getAMSLock() { 6070 return ActivityManagerService.this; 6071 } 6072 } 6073 6074 /** 6075 * This can be called with or without the global lock held. 6076 */ 6077 int checkComponentPermission(String permission, int pid, int uid, 6078 int owningUid, boolean exported) { 6079 // We might be performing an operation on behalf of an indirect binder 6080 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6081 // client identity accordingly before proceeding. 6082 Identity tlsIdentity = sCallerIdentity.get(); 6083 if (tlsIdentity != null) { 6084 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6085 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6086 uid = tlsIdentity.uid; 6087 pid = tlsIdentity.pid; 6088 } 6089 6090 if (pid == MY_PID) { 6091 return PackageManager.PERMISSION_GRANTED; 6092 } 6093 6094 return ActivityManager.checkComponentPermission(permission, uid, 6095 owningUid, exported); 6096 } 6097 6098 /** 6099 * As the only public entry point for permissions checking, this method 6100 * can enforce the semantic that requesting a check on a null global 6101 * permission is automatically denied. (Internally a null permission 6102 * string is used when calling {@link #checkComponentPermission} in cases 6103 * when only uid-based security is needed.) 6104 * 6105 * This can be called with or without the global lock held. 6106 */ 6107 @Override 6108 public int checkPermission(String permission, int pid, int uid) { 6109 if (permission == null) { 6110 return PackageManager.PERMISSION_DENIED; 6111 } 6112 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6113 } 6114 6115 /** 6116 * Binder IPC calls go through the public entry point. 6117 * This can be called with or without the global lock held. 6118 */ 6119 int checkCallingPermission(String permission) { 6120 return checkPermission(permission, 6121 Binder.getCallingPid(), 6122 UserHandle.getAppId(Binder.getCallingUid())); 6123 } 6124 6125 /** 6126 * This can be called with or without the global lock held. 6127 */ 6128 void enforceCallingPermission(String permission, String func) { 6129 if (checkCallingPermission(permission) 6130 == PackageManager.PERMISSION_GRANTED) { 6131 return; 6132 } 6133 6134 String msg = "Permission Denial: " + func + " from pid=" 6135 + Binder.getCallingPid() 6136 + ", uid=" + Binder.getCallingUid() 6137 + " requires " + permission; 6138 Slog.w(TAG, msg); 6139 throw new SecurityException(msg); 6140 } 6141 6142 /** 6143 * Determine if UID is holding permissions required to access {@link Uri} in 6144 * the given {@link ProviderInfo}. Final permission checking is always done 6145 * in {@link ContentProvider}. 6146 */ 6147 private final boolean checkHoldingPermissionsLocked( 6148 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6149 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6150 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6151 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6152 return false; 6153 } 6154 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6155 } 6156 6157 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6158 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6159 if (pi.applicationInfo.uid == uid) { 6160 return true; 6161 } else if (!pi.exported) { 6162 return false; 6163 } 6164 6165 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6166 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6167 try { 6168 // check if target holds top-level <provider> permissions 6169 if (!readMet && pi.readPermission != null && considerUidPermissions 6170 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6171 readMet = true; 6172 } 6173 if (!writeMet && pi.writePermission != null && considerUidPermissions 6174 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6175 writeMet = true; 6176 } 6177 6178 // track if unprotected read/write is allowed; any denied 6179 // <path-permission> below removes this ability 6180 boolean allowDefaultRead = pi.readPermission == null; 6181 boolean allowDefaultWrite = pi.writePermission == null; 6182 6183 // check if target holds any <path-permission> that match uri 6184 final PathPermission[] pps = pi.pathPermissions; 6185 if (pps != null) { 6186 final String path = grantUri.uri.getPath(); 6187 int i = pps.length; 6188 while (i > 0 && (!readMet || !writeMet)) { 6189 i--; 6190 PathPermission pp = pps[i]; 6191 if (pp.match(path)) { 6192 if (!readMet) { 6193 final String pprperm = pp.getReadPermission(); 6194 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6195 + pprperm + " for " + pp.getPath() 6196 + ": match=" + pp.match(path) 6197 + " check=" + pm.checkUidPermission(pprperm, uid)); 6198 if (pprperm != null) { 6199 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6200 == PERMISSION_GRANTED) { 6201 readMet = true; 6202 } else { 6203 allowDefaultRead = false; 6204 } 6205 } 6206 } 6207 if (!writeMet) { 6208 final String ppwperm = pp.getWritePermission(); 6209 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6210 + ppwperm + " for " + pp.getPath() 6211 + ": match=" + pp.match(path) 6212 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6213 if (ppwperm != null) { 6214 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6215 == PERMISSION_GRANTED) { 6216 writeMet = true; 6217 } else { 6218 allowDefaultWrite = false; 6219 } 6220 } 6221 } 6222 } 6223 } 6224 } 6225 6226 // grant unprotected <provider> read/write, if not blocked by 6227 // <path-permission> above 6228 if (allowDefaultRead) readMet = true; 6229 if (allowDefaultWrite) writeMet = true; 6230 6231 } catch (RemoteException e) { 6232 return false; 6233 } 6234 6235 return readMet && writeMet; 6236 } 6237 6238 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6239 ProviderInfo pi = null; 6240 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6241 if (cpr != null) { 6242 pi = cpr.info; 6243 } else { 6244 try { 6245 pi = AppGlobals.getPackageManager().resolveContentProvider( 6246 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6247 } catch (RemoteException ex) { 6248 } 6249 } 6250 return pi; 6251 } 6252 6253 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6254 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6255 if (targetUris != null) { 6256 return targetUris.get(grantUri); 6257 } 6258 return null; 6259 } 6260 6261 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6262 String targetPkg, int targetUid, GrantUri grantUri) { 6263 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6264 if (targetUris == null) { 6265 targetUris = Maps.newArrayMap(); 6266 mGrantedUriPermissions.put(targetUid, targetUris); 6267 } 6268 6269 UriPermission perm = targetUris.get(grantUri); 6270 if (perm == null) { 6271 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6272 targetUris.put(grantUri, perm); 6273 } 6274 6275 return perm; 6276 } 6277 6278 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6279 final int modeFlags) { 6280 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6281 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6282 : UriPermission.STRENGTH_OWNED; 6283 6284 // Root gets to do everything. 6285 if (uid == 0) { 6286 return true; 6287 } 6288 6289 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6290 if (perms == null) return false; 6291 6292 // First look for exact match 6293 final UriPermission exactPerm = perms.get(grantUri); 6294 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6295 return true; 6296 } 6297 6298 // No exact match, look for prefixes 6299 final int N = perms.size(); 6300 for (int i = 0; i < N; i++) { 6301 final UriPermission perm = perms.valueAt(i); 6302 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6303 && perm.getStrength(modeFlags) >= minStrength) { 6304 return true; 6305 } 6306 } 6307 6308 return false; 6309 } 6310 6311 @Override 6312 public int checkUriPermission(Uri uri, int pid, int uid, 6313 final int modeFlags, int userId) { 6314 enforceNotIsolatedCaller("checkUriPermission"); 6315 6316 // Another redirected-binder-call permissions check as in 6317 // {@link checkComponentPermission}. 6318 Identity tlsIdentity = sCallerIdentity.get(); 6319 if (tlsIdentity != null) { 6320 uid = tlsIdentity.uid; 6321 pid = tlsIdentity.pid; 6322 } 6323 6324 // Our own process gets to do everything. 6325 if (pid == MY_PID) { 6326 return PackageManager.PERMISSION_GRANTED; 6327 } 6328 synchronized (this) { 6329 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6330 ? PackageManager.PERMISSION_GRANTED 6331 : PackageManager.PERMISSION_DENIED; 6332 } 6333 } 6334 6335 /** 6336 * Check if the targetPkg can be granted permission to access uri by 6337 * the callingUid using the given modeFlags. Throws a security exception 6338 * if callingUid is not allowed to do this. Returns the uid of the target 6339 * if the URI permission grant should be performed; returns -1 if it is not 6340 * needed (for example targetPkg already has permission to access the URI). 6341 * If you already know the uid of the target, you can supply it in 6342 * lastTargetUid else set that to -1. 6343 */ 6344 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6345 final int modeFlags, int lastTargetUid) { 6346 if (!Intent.isAccessUriMode(modeFlags)) { 6347 return -1; 6348 } 6349 6350 if (targetPkg != null) { 6351 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6352 "Checking grant " + targetPkg + " permission to " + grantUri); 6353 } 6354 6355 final IPackageManager pm = AppGlobals.getPackageManager(); 6356 6357 // If this is not a content: uri, we can't do anything with it. 6358 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6359 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6360 "Can't grant URI permission for non-content URI: " + grantUri); 6361 return -1; 6362 } 6363 6364 final String authority = grantUri.uri.getAuthority(); 6365 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6366 if (pi == null) { 6367 Slog.w(TAG, "No content provider found for permission check: " + 6368 grantUri.uri.toSafeString()); 6369 return -1; 6370 } 6371 6372 int targetUid = lastTargetUid; 6373 if (targetUid < 0 && targetPkg != null) { 6374 try { 6375 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6376 if (targetUid < 0) { 6377 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6378 "Can't grant URI permission no uid for: " + targetPkg); 6379 return -1; 6380 } 6381 } catch (RemoteException ex) { 6382 return -1; 6383 } 6384 } 6385 6386 if (targetUid >= 0) { 6387 // First... does the target actually need this permission? 6388 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6389 // No need to grant the target this permission. 6390 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6391 "Target " + targetPkg + " already has full permission to " + grantUri); 6392 return -1; 6393 } 6394 } else { 6395 // First... there is no target package, so can anyone access it? 6396 boolean allowed = pi.exported; 6397 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6398 if (pi.readPermission != null) { 6399 allowed = false; 6400 } 6401 } 6402 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6403 if (pi.writePermission != null) { 6404 allowed = false; 6405 } 6406 } 6407 if (allowed) { 6408 return -1; 6409 } 6410 } 6411 6412 /* There is a special cross user grant if: 6413 * - The target is on another user. 6414 * - Apps on the current user can access the uri without any uid permissions. 6415 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6416 * grant uri permissions. 6417 */ 6418 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6419 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6420 modeFlags, false /*without considering the uid permissions*/); 6421 6422 // Second... is the provider allowing granting of URI permissions? 6423 if (!specialCrossUserGrant) { 6424 if (!pi.grantUriPermissions) { 6425 throw new SecurityException("Provider " + pi.packageName 6426 + "/" + pi.name 6427 + " does not allow granting of Uri permissions (uri " 6428 + grantUri + ")"); 6429 } 6430 if (pi.uriPermissionPatterns != null) { 6431 final int N = pi.uriPermissionPatterns.length; 6432 boolean allowed = false; 6433 for (int i=0; i<N; i++) { 6434 if (pi.uriPermissionPatterns[i] != null 6435 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6436 allowed = true; 6437 break; 6438 } 6439 } 6440 if (!allowed) { 6441 throw new SecurityException("Provider " + pi.packageName 6442 + "/" + pi.name 6443 + " does not allow granting of permission to path of Uri " 6444 + grantUri); 6445 } 6446 } 6447 } 6448 6449 // Third... does the caller itself have permission to access 6450 // this uri? 6451 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6452 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6453 // Require they hold a strong enough Uri permission 6454 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6455 throw new SecurityException("Uid " + callingUid 6456 + " does not have permission to uri " + grantUri); 6457 } 6458 } 6459 } 6460 return targetUid; 6461 } 6462 6463 @Override 6464 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6465 final int modeFlags, int userId) { 6466 enforceNotIsolatedCaller("checkGrantUriPermission"); 6467 synchronized(this) { 6468 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6469 new GrantUri(userId, uri, false), modeFlags, -1); 6470 } 6471 } 6472 6473 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6474 final int modeFlags, UriPermissionOwner owner) { 6475 if (!Intent.isAccessUriMode(modeFlags)) { 6476 return; 6477 } 6478 6479 // So here we are: the caller has the assumed permission 6480 // to the uri, and the target doesn't. Let's now give this to 6481 // the target. 6482 6483 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6484 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6485 6486 final String authority = grantUri.uri.getAuthority(); 6487 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6488 if (pi == null) { 6489 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6490 return; 6491 } 6492 6493 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6494 grantUri.prefix = true; 6495 } 6496 final UriPermission perm = findOrCreateUriPermissionLocked( 6497 pi.packageName, targetPkg, targetUid, grantUri); 6498 perm.grantModes(modeFlags, owner); 6499 } 6500 6501 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6502 final int modeFlags, UriPermissionOwner owner) { 6503 if (targetPkg == null) { 6504 throw new NullPointerException("targetPkg"); 6505 } 6506 6507 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6508 -1); 6509 if (targetUid < 0) { 6510 return; 6511 } 6512 6513 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6514 owner); 6515 } 6516 6517 static class NeededUriGrants extends ArrayList<GrantUri> { 6518 final String targetPkg; 6519 final int targetUid; 6520 final int flags; 6521 6522 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6523 this.targetPkg = targetPkg; 6524 this.targetUid = targetUid; 6525 this.flags = flags; 6526 } 6527 } 6528 6529 /** 6530 * Like checkGrantUriPermissionLocked, but takes an Intent. 6531 */ 6532 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6533 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6534 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6535 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6536 + " clip=" + (intent != null ? intent.getClipData() : null) 6537 + " from " + intent + "; flags=0x" 6538 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6539 6540 if (targetPkg == null) { 6541 throw new NullPointerException("targetPkg"); 6542 } 6543 6544 if (intent == null) { 6545 return null; 6546 } 6547 Uri data = intent.getData(); 6548 ClipData clip = intent.getClipData(); 6549 if (data == null && clip == null) { 6550 return null; 6551 } 6552 final IPackageManager pm = AppGlobals.getPackageManager(); 6553 int targetUid; 6554 if (needed != null) { 6555 targetUid = needed.targetUid; 6556 } else { 6557 try { 6558 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6559 } catch (RemoteException ex) { 6560 return null; 6561 } 6562 if (targetUid < 0) { 6563 if (DEBUG_URI_PERMISSION) { 6564 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6565 + " on user " + targetUserId); 6566 } 6567 return null; 6568 } 6569 } 6570 if (data != null) { 6571 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6572 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6573 targetUid); 6574 if (targetUid > 0) { 6575 if (needed == null) { 6576 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6577 } 6578 needed.add(grantUri); 6579 } 6580 } 6581 if (clip != null) { 6582 for (int i=0; i<clip.getItemCount(); i++) { 6583 Uri uri = clip.getItemAt(i).getUri(); 6584 if (uri != null) { 6585 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6586 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6587 targetUid); 6588 if (targetUid > 0) { 6589 if (needed == null) { 6590 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6591 } 6592 needed.add(grantUri); 6593 } 6594 } else { 6595 Intent clipIntent = clip.getItemAt(i).getIntent(); 6596 if (clipIntent != null) { 6597 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6598 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6599 if (newNeeded != null) { 6600 needed = newNeeded; 6601 } 6602 } 6603 } 6604 } 6605 } 6606 6607 return needed; 6608 } 6609 6610 /** 6611 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6612 */ 6613 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6614 UriPermissionOwner owner) { 6615 if (needed != null) { 6616 for (int i=0; i<needed.size(); i++) { 6617 GrantUri grantUri = needed.get(i); 6618 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6619 grantUri, needed.flags, owner); 6620 } 6621 } 6622 } 6623 6624 void grantUriPermissionFromIntentLocked(int callingUid, 6625 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6626 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6627 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6628 if (needed == null) { 6629 return; 6630 } 6631 6632 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6633 } 6634 6635 @Override 6636 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6637 final int modeFlags, int userId) { 6638 enforceNotIsolatedCaller("grantUriPermission"); 6639 GrantUri grantUri = new GrantUri(userId, uri, false); 6640 synchronized(this) { 6641 final ProcessRecord r = getRecordForAppLocked(caller); 6642 if (r == null) { 6643 throw new SecurityException("Unable to find app for caller " 6644 + caller 6645 + " when granting permission to uri " + grantUri); 6646 } 6647 if (targetPkg == null) { 6648 throw new IllegalArgumentException("null target"); 6649 } 6650 if (grantUri == null) { 6651 throw new IllegalArgumentException("null uri"); 6652 } 6653 6654 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6655 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6656 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6657 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6658 6659 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6660 } 6661 } 6662 6663 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6664 if (perm.modeFlags == 0) { 6665 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6666 perm.targetUid); 6667 if (perms != null) { 6668 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6669 "Removing " + perm.targetUid + " permission to " + perm.uri); 6670 6671 perms.remove(perm.uri); 6672 if (perms.isEmpty()) { 6673 mGrantedUriPermissions.remove(perm.targetUid); 6674 } 6675 } 6676 } 6677 } 6678 6679 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6680 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6681 6682 final IPackageManager pm = AppGlobals.getPackageManager(); 6683 final String authority = grantUri.uri.getAuthority(); 6684 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6685 if (pi == null) { 6686 Slog.w(TAG, "No content provider found for permission revoke: " 6687 + grantUri.toSafeString()); 6688 return; 6689 } 6690 6691 // Does the caller have this permission on the URI? 6692 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6693 // Right now, if you are not the original owner of the permission, 6694 // you are not allowed to revoke it. 6695 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6696 throw new SecurityException("Uid " + callingUid 6697 + " does not have permission to uri " + grantUri); 6698 //} 6699 } 6700 6701 boolean persistChanged = false; 6702 6703 // Go through all of the permissions and remove any that match. 6704 int N = mGrantedUriPermissions.size(); 6705 for (int i = 0; i < N; i++) { 6706 final int targetUid = mGrantedUriPermissions.keyAt(i); 6707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6708 6709 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6710 final UriPermission perm = it.next(); 6711 if (perm.uri.sourceUserId == grantUri.sourceUserId 6712 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6713 if (DEBUG_URI_PERMISSION) 6714 Slog.v(TAG, 6715 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6716 persistChanged |= perm.revokeModes( 6717 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6718 if (perm.modeFlags == 0) { 6719 it.remove(); 6720 } 6721 } 6722 } 6723 6724 if (perms.isEmpty()) { 6725 mGrantedUriPermissions.remove(targetUid); 6726 N--; 6727 i--; 6728 } 6729 } 6730 6731 if (persistChanged) { 6732 schedulePersistUriGrants(); 6733 } 6734 } 6735 6736 @Override 6737 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6738 int userId) { 6739 enforceNotIsolatedCaller("revokeUriPermission"); 6740 synchronized(this) { 6741 final ProcessRecord r = getRecordForAppLocked(caller); 6742 if (r == null) { 6743 throw new SecurityException("Unable to find app for caller " 6744 + caller 6745 + " when revoking permission to uri " + uri); 6746 } 6747 if (uri == null) { 6748 Slog.w(TAG, "revokeUriPermission: null uri"); 6749 return; 6750 } 6751 6752 if (!Intent.isAccessUriMode(modeFlags)) { 6753 return; 6754 } 6755 6756 final IPackageManager pm = AppGlobals.getPackageManager(); 6757 final String authority = uri.getAuthority(); 6758 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6759 if (pi == null) { 6760 Slog.w(TAG, "No content provider found for permission revoke: " 6761 + uri.toSafeString()); 6762 return; 6763 } 6764 6765 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6766 } 6767 } 6768 6769 /** 6770 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6771 * given package. 6772 * 6773 * @param packageName Package name to match, or {@code null} to apply to all 6774 * packages. 6775 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6776 * to all users. 6777 * @param persistable If persistable grants should be removed. 6778 */ 6779 private void removeUriPermissionsForPackageLocked( 6780 String packageName, int userHandle, boolean persistable) { 6781 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6782 throw new IllegalArgumentException("Must narrow by either package or user"); 6783 } 6784 6785 boolean persistChanged = false; 6786 6787 int N = mGrantedUriPermissions.size(); 6788 for (int i = 0; i < N; i++) { 6789 final int targetUid = mGrantedUriPermissions.keyAt(i); 6790 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6791 6792 // Only inspect grants matching user 6793 if (userHandle == UserHandle.USER_ALL 6794 || userHandle == UserHandle.getUserId(targetUid)) { 6795 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6796 final UriPermission perm = it.next(); 6797 6798 // Only inspect grants matching package 6799 if (packageName == null || perm.sourcePkg.equals(packageName) 6800 || perm.targetPkg.equals(packageName)) { 6801 persistChanged |= perm.revokeModes( 6802 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6803 6804 // Only remove when no modes remain; any persisted grants 6805 // will keep this alive. 6806 if (perm.modeFlags == 0) { 6807 it.remove(); 6808 } 6809 } 6810 } 6811 6812 if (perms.isEmpty()) { 6813 mGrantedUriPermissions.remove(targetUid); 6814 N--; 6815 i--; 6816 } 6817 } 6818 } 6819 6820 if (persistChanged) { 6821 schedulePersistUriGrants(); 6822 } 6823 } 6824 6825 @Override 6826 public IBinder newUriPermissionOwner(String name) { 6827 enforceNotIsolatedCaller("newUriPermissionOwner"); 6828 synchronized(this) { 6829 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6830 return owner.getExternalTokenLocked(); 6831 } 6832 } 6833 6834 @Override 6835 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6836 final int modeFlags, int userId) { 6837 synchronized(this) { 6838 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6839 if (owner == null) { 6840 throw new IllegalArgumentException("Unknown owner: " + token); 6841 } 6842 if (fromUid != Binder.getCallingUid()) { 6843 if (Binder.getCallingUid() != Process.myUid()) { 6844 // Only system code can grant URI permissions on behalf 6845 // of other users. 6846 throw new SecurityException("nice try"); 6847 } 6848 } 6849 if (targetPkg == null) { 6850 throw new IllegalArgumentException("null target"); 6851 } 6852 if (uri == null) { 6853 throw new IllegalArgumentException("null uri"); 6854 } 6855 6856 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6857 modeFlags, owner); 6858 } 6859 } 6860 6861 @Override 6862 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6863 synchronized(this) { 6864 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6865 if (owner == null) { 6866 throw new IllegalArgumentException("Unknown owner: " + token); 6867 } 6868 6869 if (uri == null) { 6870 owner.removeUriPermissionsLocked(mode); 6871 } else { 6872 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6873 } 6874 } 6875 } 6876 6877 private void schedulePersistUriGrants() { 6878 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6879 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6880 10 * DateUtils.SECOND_IN_MILLIS); 6881 } 6882 } 6883 6884 private void writeGrantedUriPermissions() { 6885 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6886 6887 // Snapshot permissions so we can persist without lock 6888 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6889 synchronized (this) { 6890 final int size = mGrantedUriPermissions.size(); 6891 for (int i = 0; i < size; i++) { 6892 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6893 for (UriPermission perm : perms.values()) { 6894 if (perm.persistedModeFlags != 0) { 6895 persist.add(perm.snapshot()); 6896 } 6897 } 6898 } 6899 } 6900 6901 FileOutputStream fos = null; 6902 try { 6903 fos = mGrantFile.startWrite(); 6904 6905 XmlSerializer out = new FastXmlSerializer(); 6906 out.setOutput(fos, "utf-8"); 6907 out.startDocument(null, true); 6908 out.startTag(null, TAG_URI_GRANTS); 6909 for (UriPermission.Snapshot perm : persist) { 6910 out.startTag(null, TAG_URI_GRANT); 6911 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6912 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6913 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6914 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6915 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6916 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6917 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6918 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6919 out.endTag(null, TAG_URI_GRANT); 6920 } 6921 out.endTag(null, TAG_URI_GRANTS); 6922 out.endDocument(); 6923 6924 mGrantFile.finishWrite(fos); 6925 } catch (IOException e) { 6926 if (fos != null) { 6927 mGrantFile.failWrite(fos); 6928 } 6929 } 6930 } 6931 6932 private void readGrantedUriPermissionsLocked() { 6933 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6934 6935 final long now = System.currentTimeMillis(); 6936 6937 FileInputStream fis = null; 6938 try { 6939 fis = mGrantFile.openRead(); 6940 final XmlPullParser in = Xml.newPullParser(); 6941 in.setInput(fis, null); 6942 6943 int type; 6944 while ((type = in.next()) != END_DOCUMENT) { 6945 final String tag = in.getName(); 6946 if (type == START_TAG) { 6947 if (TAG_URI_GRANT.equals(tag)) { 6948 final int sourceUserId; 6949 final int targetUserId; 6950 final int userHandle = readIntAttribute(in, 6951 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6952 if (userHandle != UserHandle.USER_NULL) { 6953 // For backwards compatibility. 6954 sourceUserId = userHandle; 6955 targetUserId = userHandle; 6956 } else { 6957 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6958 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6959 } 6960 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6961 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6962 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6963 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6964 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6965 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6966 6967 // Sanity check that provider still belongs to source package 6968 final ProviderInfo pi = getProviderInfoLocked( 6969 uri.getAuthority(), sourceUserId); 6970 if (pi != null && sourcePkg.equals(pi.packageName)) { 6971 int targetUid = -1; 6972 try { 6973 targetUid = AppGlobals.getPackageManager() 6974 .getPackageUid(targetPkg, targetUserId); 6975 } catch (RemoteException e) { 6976 } 6977 if (targetUid != -1) { 6978 final UriPermission perm = findOrCreateUriPermissionLocked( 6979 sourcePkg, targetPkg, targetUid, 6980 new GrantUri(sourceUserId, uri, prefix)); 6981 perm.initPersistedModes(modeFlags, createdTime); 6982 } 6983 } else { 6984 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6985 + " but instead found " + pi); 6986 } 6987 } 6988 } 6989 } 6990 } catch (FileNotFoundException e) { 6991 // Missing grants is okay 6992 } catch (IOException e) { 6993 Log.wtf(TAG, "Failed reading Uri grants", e); 6994 } catch (XmlPullParserException e) { 6995 Log.wtf(TAG, "Failed reading Uri grants", e); 6996 } finally { 6997 IoUtils.closeQuietly(fis); 6998 } 6999 } 7000 7001 @Override 7002 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7003 enforceNotIsolatedCaller("takePersistableUriPermission"); 7004 7005 Preconditions.checkFlagsArgument(modeFlags, 7006 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7007 7008 synchronized (this) { 7009 final int callingUid = Binder.getCallingUid(); 7010 boolean persistChanged = false; 7011 GrantUri grantUri = new GrantUri(userId, uri, false); 7012 7013 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7014 new GrantUri(userId, uri, false)); 7015 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7016 new GrantUri(userId, uri, true)); 7017 7018 final boolean exactValid = (exactPerm != null) 7019 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7020 final boolean prefixValid = (prefixPerm != null) 7021 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7022 7023 if (!(exactValid || prefixValid)) { 7024 throw new SecurityException("No persistable permission grants found for UID " 7025 + callingUid + " and Uri " + grantUri.toSafeString()); 7026 } 7027 7028 if (exactValid) { 7029 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7030 } 7031 if (prefixValid) { 7032 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7033 } 7034 7035 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7036 7037 if (persistChanged) { 7038 schedulePersistUriGrants(); 7039 } 7040 } 7041 } 7042 7043 @Override 7044 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7045 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7046 7047 Preconditions.checkFlagsArgument(modeFlags, 7048 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7049 7050 synchronized (this) { 7051 final int callingUid = Binder.getCallingUid(); 7052 boolean persistChanged = false; 7053 7054 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7055 new GrantUri(userId, uri, false)); 7056 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7057 new GrantUri(userId, uri, true)); 7058 if (exactPerm == null && prefixPerm == null) { 7059 throw new SecurityException("No permission grants found for UID " + callingUid 7060 + " and Uri " + uri.toSafeString()); 7061 } 7062 7063 if (exactPerm != null) { 7064 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7065 removeUriPermissionIfNeededLocked(exactPerm); 7066 } 7067 if (prefixPerm != null) { 7068 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7069 removeUriPermissionIfNeededLocked(prefixPerm); 7070 } 7071 7072 if (persistChanged) { 7073 schedulePersistUriGrants(); 7074 } 7075 } 7076 } 7077 7078 /** 7079 * Prune any older {@link UriPermission} for the given UID until outstanding 7080 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7081 * 7082 * @return if any mutations occured that require persisting. 7083 */ 7084 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7085 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7086 if (perms == null) return false; 7087 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7088 7089 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7090 for (UriPermission perm : perms.values()) { 7091 if (perm.persistedModeFlags != 0) { 7092 persisted.add(perm); 7093 } 7094 } 7095 7096 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7097 if (trimCount <= 0) return false; 7098 7099 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7100 for (int i = 0; i < trimCount; i++) { 7101 final UriPermission perm = persisted.get(i); 7102 7103 if (DEBUG_URI_PERMISSION) { 7104 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7105 } 7106 7107 perm.releasePersistableModes(~0); 7108 removeUriPermissionIfNeededLocked(perm); 7109 } 7110 7111 return true; 7112 } 7113 7114 @Override 7115 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7116 String packageName, boolean incoming) { 7117 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7118 Preconditions.checkNotNull(packageName, "packageName"); 7119 7120 final int callingUid = Binder.getCallingUid(); 7121 final IPackageManager pm = AppGlobals.getPackageManager(); 7122 try { 7123 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7124 if (packageUid != callingUid) { 7125 throw new SecurityException( 7126 "Package " + packageName + " does not belong to calling UID " + callingUid); 7127 } 7128 } catch (RemoteException e) { 7129 throw new SecurityException("Failed to verify package name ownership"); 7130 } 7131 7132 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7133 synchronized (this) { 7134 if (incoming) { 7135 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7136 callingUid); 7137 if (perms == null) { 7138 Slog.w(TAG, "No permission grants found for " + packageName); 7139 } else { 7140 for (UriPermission perm : perms.values()) { 7141 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7142 result.add(perm.buildPersistedPublicApiObject()); 7143 } 7144 } 7145 } 7146 } else { 7147 final int size = mGrantedUriPermissions.size(); 7148 for (int i = 0; i < size; i++) { 7149 final ArrayMap<GrantUri, UriPermission> perms = 7150 mGrantedUriPermissions.valueAt(i); 7151 for (UriPermission perm : perms.values()) { 7152 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7153 result.add(perm.buildPersistedPublicApiObject()); 7154 } 7155 } 7156 } 7157 } 7158 } 7159 return new ParceledListSlice<android.content.UriPermission>(result); 7160 } 7161 7162 @Override 7163 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7164 synchronized (this) { 7165 ProcessRecord app = 7166 who != null ? getRecordForAppLocked(who) : null; 7167 if (app == null) return; 7168 7169 Message msg = Message.obtain(); 7170 msg.what = WAIT_FOR_DEBUGGER_MSG; 7171 msg.obj = app; 7172 msg.arg1 = waiting ? 1 : 0; 7173 mHandler.sendMessage(msg); 7174 } 7175 } 7176 7177 @Override 7178 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7179 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7180 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7181 outInfo.availMem = Process.getFreeMemory(); 7182 outInfo.totalMem = Process.getTotalMemory(); 7183 outInfo.threshold = homeAppMem; 7184 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7185 outInfo.hiddenAppThreshold = cachedAppMem; 7186 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7187 ProcessList.SERVICE_ADJ); 7188 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7189 ProcessList.VISIBLE_APP_ADJ); 7190 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7191 ProcessList.FOREGROUND_APP_ADJ); 7192 } 7193 7194 // ========================================================= 7195 // TASK MANAGEMENT 7196 // ========================================================= 7197 7198 @Override 7199 public List<IAppTask> getAppTasks() { 7200 final PackageManager pm = mContext.getPackageManager(); 7201 int callingUid = Binder.getCallingUid(); 7202 long ident = Binder.clearCallingIdentity(); 7203 7204 // Compose the list of packages for this id to test against 7205 HashSet<String> packages = new HashSet<String>(); 7206 String[] uidPackages = pm.getPackagesForUid(callingUid); 7207 for (int i = 0; i < uidPackages.length; i++) { 7208 packages.add(uidPackages[i]); 7209 } 7210 7211 synchronized(this) { 7212 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7213 try { 7214 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7215 7216 final int N = mRecentTasks.size(); 7217 for (int i = 0; i < N; i++) { 7218 TaskRecord tr = mRecentTasks.get(i); 7219 // Skip tasks that are not created by the caller 7220 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7221 ActivityManager.RecentTaskInfo taskInfo = 7222 createRecentTaskInfoFromTaskRecord(tr); 7223 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7224 list.add(taskImpl); 7225 } 7226 } 7227 } finally { 7228 Binder.restoreCallingIdentity(ident); 7229 } 7230 return list; 7231 } 7232 } 7233 7234 @Override 7235 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7236 final int callingUid = Binder.getCallingUid(); 7237 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7238 7239 synchronized(this) { 7240 if (localLOGV) Slog.v( 7241 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7242 7243 final boolean allowed = checkCallingPermission( 7244 android.Manifest.permission.GET_TASKS) 7245 == PackageManager.PERMISSION_GRANTED; 7246 if (!allowed) { 7247 Slog.w(TAG, "getTasks: caller " + callingUid 7248 + " does not hold GET_TASKS; limiting output"); 7249 } 7250 7251 // TODO: Improve with MRU list from all ActivityStacks. 7252 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7253 } 7254 7255 return list; 7256 } 7257 7258 TaskRecord getMostRecentTask() { 7259 return mRecentTasks.get(0); 7260 } 7261 7262 /** 7263 * Creates a new RecentTaskInfo from a TaskRecord. 7264 */ 7265 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7266 // Update the task description to reflect any changes in the task stack 7267 tr.updateTaskDescription(); 7268 7269 // Compose the recent task info 7270 ActivityManager.RecentTaskInfo rti 7271 = new ActivityManager.RecentTaskInfo(); 7272 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7273 rti.persistentId = tr.taskId; 7274 rti.baseIntent = new Intent(tr.getBaseIntent()); 7275 rti.origActivity = tr.origActivity; 7276 rti.description = tr.lastDescription; 7277 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7278 rti.userId = tr.userId; 7279 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7280 rti.firstActiveTime = tr.firstActiveTime; 7281 rti.lastActiveTime = tr.lastActiveTime; 7282 return rti; 7283 } 7284 7285 @Override 7286 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7287 int flags, int userId) { 7288 final int callingUid = Binder.getCallingUid(); 7289 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7290 false, true, "getRecentTasks", null); 7291 7292 synchronized (this) { 7293 final boolean allowed = checkCallingPermission( 7294 android.Manifest.permission.GET_TASKS) 7295 == PackageManager.PERMISSION_GRANTED; 7296 if (!allowed) { 7297 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7298 + " does not hold GET_TASKS; limiting output"); 7299 } 7300 final boolean detailed = checkCallingPermission( 7301 android.Manifest.permission.GET_DETAILED_TASKS) 7302 == PackageManager.PERMISSION_GRANTED; 7303 7304 IPackageManager pm = AppGlobals.getPackageManager(); 7305 7306 final int N = mRecentTasks.size(); 7307 ArrayList<ActivityManager.RecentTaskInfo> res 7308 = new ArrayList<ActivityManager.RecentTaskInfo>( 7309 maxNum < N ? maxNum : N); 7310 7311 final Set<Integer> includedUsers; 7312 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7313 includedUsers = getProfileIdsLocked(userId); 7314 } else { 7315 includedUsers = new HashSet<Integer>(); 7316 } 7317 includedUsers.add(Integer.valueOf(userId)); 7318 for (int i=0; i<N && maxNum > 0; i++) { 7319 TaskRecord tr = mRecentTasks.get(i); 7320 // Only add calling user or related users recent tasks 7321 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7322 7323 // Return the entry if desired by the caller. We always return 7324 // the first entry, because callers always expect this to be the 7325 // foreground app. We may filter others if the caller has 7326 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7327 // we should exclude the entry. 7328 7329 if (i == 0 7330 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7331 || (tr.intent == null) 7332 || ((tr.intent.getFlags() 7333 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7334 if (!allowed) { 7335 // If the caller doesn't have the GET_TASKS permission, then only 7336 // allow them to see a small subset of tasks -- their own and home. 7337 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7338 continue; 7339 } 7340 } 7341 if (tr.intent != null && 7342 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7343 != 0 && tr.getTopActivity() == null) { 7344 // Don't include auto remove tasks that are finished or finishing. 7345 continue; 7346 } 7347 7348 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7349 if (!detailed) { 7350 rti.baseIntent.replaceExtras((Bundle)null); 7351 } 7352 7353 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7354 // Check whether this activity is currently available. 7355 try { 7356 if (rti.origActivity != null) { 7357 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7358 == null) { 7359 continue; 7360 } 7361 } else if (rti.baseIntent != null) { 7362 if (pm.queryIntentActivities(rti.baseIntent, 7363 null, 0, userId) == null) { 7364 continue; 7365 } 7366 } 7367 } catch (RemoteException e) { 7368 // Will never happen. 7369 } 7370 } 7371 7372 res.add(rti); 7373 maxNum--; 7374 } 7375 } 7376 return res; 7377 } 7378 } 7379 7380 private TaskRecord recentTaskForIdLocked(int id) { 7381 final int N = mRecentTasks.size(); 7382 for (int i=0; i<N; i++) { 7383 TaskRecord tr = mRecentTasks.get(i); 7384 if (tr.taskId == id) { 7385 return tr; 7386 } 7387 } 7388 return null; 7389 } 7390 7391 @Override 7392 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7393 synchronized (this) { 7394 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7395 "getTaskThumbnail()"); 7396 TaskRecord tr = recentTaskForIdLocked(id); 7397 if (tr != null) { 7398 return tr.getTaskThumbnailLocked(); 7399 } 7400 } 7401 return null; 7402 } 7403 7404 @Override 7405 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7406 synchronized (this) { 7407 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7408 if (r != null) { 7409 r.taskDescription = td; 7410 r.task.updateTaskDescription(); 7411 } 7412 } 7413 } 7414 7415 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7416 if (!pr.killedByAm) { 7417 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7418 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7419 pr.processName, pr.setAdj, reason); 7420 pr.killedByAm = true; 7421 Process.killProcessQuiet(pr.pid); 7422 Process.killProcessGroup(pr.info.uid, pr.pid); 7423 } 7424 } 7425 7426 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7427 tr.disposeThumbnail(); 7428 mRecentTasks.remove(tr); 7429 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7430 Intent baseIntent = new Intent( 7431 tr.intent != null ? tr.intent : tr.affinityIntent); 7432 ComponentName component = baseIntent.getComponent(); 7433 if (component == null) { 7434 Slog.w(TAG, "Now component for base intent of task: " + tr); 7435 return; 7436 } 7437 7438 // Find any running services associated with this app. 7439 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7440 7441 if (killProcesses) { 7442 // Find any running processes associated with this app. 7443 final String pkg = component.getPackageName(); 7444 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7445 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7446 for (int i=0; i<pmap.size(); i++) { 7447 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7448 for (int j=0; j<uids.size(); j++) { 7449 ProcessRecord proc = uids.valueAt(j); 7450 if (proc.userId != tr.userId) { 7451 continue; 7452 } 7453 if (!proc.pkgList.containsKey(pkg)) { 7454 continue; 7455 } 7456 procs.add(proc); 7457 } 7458 } 7459 7460 // Kill the running processes. 7461 for (int i=0; i<procs.size(); i++) { 7462 ProcessRecord pr = procs.get(i); 7463 if (pr == mHomeProcess) { 7464 // Don't kill the home process along with tasks from the same package. 7465 continue; 7466 } 7467 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7468 killUnneededProcessLocked(pr, "remove task"); 7469 } else { 7470 pr.waitingToKill = "remove task"; 7471 } 7472 } 7473 } 7474 } 7475 7476 /** 7477 * Removes the task with the specified task id. 7478 * 7479 * @param taskId Identifier of the task to be removed. 7480 * @param flags Additional operational flags. May be 0 or 7481 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7482 * @return Returns true if the given task was found and removed. 7483 */ 7484 private boolean removeTaskByIdLocked(int taskId, int flags) { 7485 TaskRecord tr = recentTaskForIdLocked(taskId); 7486 if (tr != null) { 7487 tr.removeTaskActivitiesLocked(); 7488 cleanUpRemovedTaskLocked(tr, flags); 7489 if (tr.isPersistable) { 7490 notifyTaskPersisterLocked(tr, true); 7491 } 7492 return true; 7493 } 7494 return false; 7495 } 7496 7497 @Override 7498 public boolean removeTask(int taskId, int flags) { 7499 synchronized (this) { 7500 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7501 "removeTask()"); 7502 long ident = Binder.clearCallingIdentity(); 7503 try { 7504 return removeTaskByIdLocked(taskId, flags); 7505 } finally { 7506 Binder.restoreCallingIdentity(ident); 7507 } 7508 } 7509 } 7510 7511 /** 7512 * TODO: Add mController hook 7513 */ 7514 @Override 7515 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7516 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7517 "moveTaskToFront()"); 7518 7519 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7520 synchronized(this) { 7521 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7522 Binder.getCallingUid(), "Task to front")) { 7523 ActivityOptions.abort(options); 7524 return; 7525 } 7526 final long origId = Binder.clearCallingIdentity(); 7527 try { 7528 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7529 if (task == null) { 7530 return; 7531 } 7532 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7533 mStackSupervisor.showLockTaskToast(); 7534 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7535 return; 7536 } 7537 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7538 if (prev != null && prev.isRecentsActivity()) { 7539 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7540 } 7541 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7542 } finally { 7543 Binder.restoreCallingIdentity(origId); 7544 } 7545 ActivityOptions.abort(options); 7546 } 7547 } 7548 7549 @Override 7550 public void moveTaskToBack(int taskId) { 7551 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7552 "moveTaskToBack()"); 7553 7554 synchronized(this) { 7555 TaskRecord tr = recentTaskForIdLocked(taskId); 7556 if (tr != null) { 7557 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7558 ActivityStack stack = tr.stack; 7559 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7560 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7561 Binder.getCallingUid(), "Task to back")) { 7562 return; 7563 } 7564 } 7565 final long origId = Binder.clearCallingIdentity(); 7566 try { 7567 stack.moveTaskToBackLocked(taskId, null); 7568 } finally { 7569 Binder.restoreCallingIdentity(origId); 7570 } 7571 } 7572 } 7573 } 7574 7575 /** 7576 * Moves an activity, and all of the other activities within the same task, to the bottom 7577 * of the history stack. The activity's order within the task is unchanged. 7578 * 7579 * @param token A reference to the activity we wish to move 7580 * @param nonRoot If false then this only works if the activity is the root 7581 * of a task; if true it will work for any activity in a task. 7582 * @return Returns true if the move completed, false if not. 7583 */ 7584 @Override 7585 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7586 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7587 synchronized(this) { 7588 final long origId = Binder.clearCallingIdentity(); 7589 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7590 if (taskId >= 0) { 7591 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7592 } 7593 Binder.restoreCallingIdentity(origId); 7594 } 7595 return false; 7596 } 7597 7598 @Override 7599 public void moveTaskBackwards(int task) { 7600 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7601 "moveTaskBackwards()"); 7602 7603 synchronized(this) { 7604 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7605 Binder.getCallingUid(), "Task backwards")) { 7606 return; 7607 } 7608 final long origId = Binder.clearCallingIdentity(); 7609 moveTaskBackwardsLocked(task); 7610 Binder.restoreCallingIdentity(origId); 7611 } 7612 } 7613 7614 private final void moveTaskBackwardsLocked(int task) { 7615 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7616 } 7617 7618 @Override 7619 public IBinder getHomeActivityToken() throws RemoteException { 7620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7621 "getHomeActivityToken()"); 7622 synchronized (this) { 7623 return mStackSupervisor.getHomeActivityToken(); 7624 } 7625 } 7626 7627 @Override 7628 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7629 IActivityContainerCallback callback) throws RemoteException { 7630 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7631 "createActivityContainer()"); 7632 synchronized (this) { 7633 if (parentActivityToken == null) { 7634 throw new IllegalArgumentException("parent token must not be null"); 7635 } 7636 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7637 if (r == null) { 7638 return null; 7639 } 7640 if (callback == null) { 7641 throw new IllegalArgumentException("callback must not be null"); 7642 } 7643 return mStackSupervisor.createActivityContainer(r, callback); 7644 } 7645 } 7646 7647 @Override 7648 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7649 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7650 "deleteActivityContainer()"); 7651 synchronized (this) { 7652 mStackSupervisor.deleteActivityContainer(container); 7653 } 7654 } 7655 7656 @Override 7657 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7658 throws RemoteException { 7659 synchronized (this) { 7660 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7661 if (stack != null) { 7662 return stack.mActivityContainer; 7663 } 7664 return null; 7665 } 7666 } 7667 7668 @Override 7669 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7670 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7671 "moveTaskToStack()"); 7672 if (stackId == HOME_STACK_ID) { 7673 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7674 new RuntimeException("here").fillInStackTrace()); 7675 } 7676 synchronized (this) { 7677 long ident = Binder.clearCallingIdentity(); 7678 try { 7679 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7680 + stackId + " toTop=" + toTop); 7681 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7682 } finally { 7683 Binder.restoreCallingIdentity(ident); 7684 } 7685 } 7686 } 7687 7688 @Override 7689 public void resizeStack(int stackBoxId, Rect bounds) { 7690 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7691 "resizeStackBox()"); 7692 long ident = Binder.clearCallingIdentity(); 7693 try { 7694 mWindowManager.resizeStack(stackBoxId, bounds); 7695 } finally { 7696 Binder.restoreCallingIdentity(ident); 7697 } 7698 } 7699 7700 @Override 7701 public List<StackInfo> getAllStackInfos() { 7702 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7703 "getAllStackInfos()"); 7704 long ident = Binder.clearCallingIdentity(); 7705 try { 7706 synchronized (this) { 7707 return mStackSupervisor.getAllStackInfosLocked(); 7708 } 7709 } finally { 7710 Binder.restoreCallingIdentity(ident); 7711 } 7712 } 7713 7714 @Override 7715 public StackInfo getStackInfo(int stackId) { 7716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7717 "getStackInfo()"); 7718 long ident = Binder.clearCallingIdentity(); 7719 try { 7720 synchronized (this) { 7721 return mStackSupervisor.getStackInfoLocked(stackId); 7722 } 7723 } finally { 7724 Binder.restoreCallingIdentity(ident); 7725 } 7726 } 7727 7728 @Override 7729 public boolean isInHomeStack(int taskId) { 7730 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7731 "getStackInfo()"); 7732 long ident = Binder.clearCallingIdentity(); 7733 try { 7734 synchronized (this) { 7735 TaskRecord tr = recentTaskForIdLocked(taskId); 7736 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7737 } 7738 } finally { 7739 Binder.restoreCallingIdentity(ident); 7740 } 7741 } 7742 7743 @Override 7744 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7745 synchronized(this) { 7746 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7747 } 7748 } 7749 7750 private boolean isLockTaskAuthorized(String pkg) { 7751 final DevicePolicyManager dpm = (DevicePolicyManager) 7752 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7753 try { 7754 int uid = mContext.getPackageManager().getPackageUid(pkg, 7755 Binder.getCallingUserHandle().getIdentifier()); 7756 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7757 } catch (NameNotFoundException e) { 7758 return false; 7759 } 7760 } 7761 7762 void startLockTaskMode(TaskRecord task) { 7763 final String pkg; 7764 synchronized (this) { 7765 pkg = task.intent.getComponent().getPackageName(); 7766 } 7767 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7768 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7769 final TaskRecord taskRecord = task; 7770 mHandler.post(new Runnable() { 7771 @Override 7772 public void run() { 7773 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7774 } 7775 }); 7776 return; 7777 } 7778 long ident = Binder.clearCallingIdentity(); 7779 try { 7780 synchronized (this) { 7781 // Since we lost lock on task, make sure it is still there. 7782 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7783 if (task != null) { 7784 if (!isSystemInitiated 7785 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7786 throw new IllegalArgumentException("Invalid task, not in foreground"); 7787 } 7788 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7789 } 7790 } 7791 } finally { 7792 Binder.restoreCallingIdentity(ident); 7793 } 7794 } 7795 7796 @Override 7797 public void startLockTaskMode(int taskId) { 7798 final TaskRecord task; 7799 long ident = Binder.clearCallingIdentity(); 7800 try { 7801 synchronized (this) { 7802 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7803 } 7804 } finally { 7805 Binder.restoreCallingIdentity(ident); 7806 } 7807 if (task != null) { 7808 startLockTaskMode(task); 7809 } 7810 } 7811 7812 @Override 7813 public void startLockTaskMode(IBinder token) { 7814 final TaskRecord task; 7815 long ident = Binder.clearCallingIdentity(); 7816 try { 7817 synchronized (this) { 7818 final ActivityRecord r = ActivityRecord.forToken(token); 7819 if (r == null) { 7820 return; 7821 } 7822 task = r.task; 7823 } 7824 } finally { 7825 Binder.restoreCallingIdentity(ident); 7826 } 7827 if (task != null) { 7828 startLockTaskMode(task); 7829 } 7830 } 7831 7832 @Override 7833 public void startLockTaskModeOnCurrent() throws RemoteException { 7834 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7835 ActivityRecord r = null; 7836 synchronized (this) { 7837 r = mStackSupervisor.topRunningActivityLocked(); 7838 } 7839 startLockTaskMode(r.task); 7840 } 7841 7842 @Override 7843 public void stopLockTaskMode() { 7844 // Verify that the user matches the package of the intent for the TaskRecord 7845 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7846 // and stopLockTaskMode. 7847 final int callingUid = Binder.getCallingUid(); 7848 if (callingUid != Process.SYSTEM_UID) { 7849 try { 7850 String pkg = 7851 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7852 int uid = mContext.getPackageManager().getPackageUid(pkg, 7853 Binder.getCallingUserHandle().getIdentifier()); 7854 if (uid != callingUid) { 7855 throw new SecurityException("Invalid uid, expected " + uid); 7856 } 7857 } catch (NameNotFoundException e) { 7858 Log.d(TAG, "stopLockTaskMode " + e); 7859 return; 7860 } 7861 } 7862 long ident = Binder.clearCallingIdentity(); 7863 try { 7864 Log.d(TAG, "stopLockTaskMode"); 7865 // Stop lock task 7866 synchronized (this) { 7867 mStackSupervisor.setLockTaskModeLocked(null, false); 7868 } 7869 } finally { 7870 Binder.restoreCallingIdentity(ident); 7871 } 7872 } 7873 7874 @Override 7875 public void stopLockTaskModeOnCurrent() throws RemoteException { 7876 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7877 long ident = Binder.clearCallingIdentity(); 7878 try { 7879 stopLockTaskMode(); 7880 } finally { 7881 Binder.restoreCallingIdentity(ident); 7882 } 7883 } 7884 7885 @Override 7886 public boolean isInLockTaskMode() { 7887 synchronized (this) { 7888 return mStackSupervisor.isInLockTaskMode(); 7889 } 7890 } 7891 7892 // ========================================================= 7893 // CONTENT PROVIDERS 7894 // ========================================================= 7895 7896 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7897 List<ProviderInfo> providers = null; 7898 try { 7899 providers = AppGlobals.getPackageManager(). 7900 queryContentProviders(app.processName, app.uid, 7901 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7902 } catch (RemoteException ex) { 7903 } 7904 if (DEBUG_MU) 7905 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7906 int userId = app.userId; 7907 if (providers != null) { 7908 int N = providers.size(); 7909 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7910 for (int i=0; i<N; i++) { 7911 ProviderInfo cpi = 7912 (ProviderInfo)providers.get(i); 7913 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7914 cpi.name, cpi.flags); 7915 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7916 // This is a singleton provider, but a user besides the 7917 // default user is asking to initialize a process it runs 7918 // in... well, no, it doesn't actually run in this process, 7919 // it runs in the process of the default user. Get rid of it. 7920 providers.remove(i); 7921 N--; 7922 i--; 7923 continue; 7924 } 7925 7926 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7927 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7928 if (cpr == null) { 7929 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7930 mProviderMap.putProviderByClass(comp, cpr); 7931 } 7932 if (DEBUG_MU) 7933 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7934 app.pubProviders.put(cpi.name, cpr); 7935 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7936 // Don't add this if it is a platform component that is marked 7937 // to run in multiple processes, because this is actually 7938 // part of the framework so doesn't make sense to track as a 7939 // separate apk in the process. 7940 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7941 mProcessStats); 7942 } 7943 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7944 } 7945 } 7946 return providers; 7947 } 7948 7949 /** 7950 * Check if {@link ProcessRecord} has a possible chance at accessing the 7951 * given {@link ProviderInfo}. Final permission checking is always done 7952 * in {@link ContentProvider}. 7953 */ 7954 private final String checkContentProviderPermissionLocked( 7955 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7956 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7957 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7958 boolean checkedGrants = false; 7959 if (checkUser) { 7960 // Looking for cross-user grants before enforcing the typical cross-users permissions 7961 if (UserHandle.getUserId(callingUid) != userId) { 7962 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7963 return null; 7964 } 7965 checkedGrants = true; 7966 } 7967 userId = handleIncomingUser(callingPid, callingUid, userId, 7968 false, false, "checkContentProviderPermissionLocked " + cpi.authority, null); 7969 } 7970 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7971 cpi.applicationInfo.uid, cpi.exported) 7972 == PackageManager.PERMISSION_GRANTED) { 7973 return null; 7974 } 7975 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7976 cpi.applicationInfo.uid, cpi.exported) 7977 == PackageManager.PERMISSION_GRANTED) { 7978 return null; 7979 } 7980 7981 PathPermission[] pps = cpi.pathPermissions; 7982 if (pps != null) { 7983 int i = pps.length; 7984 while (i > 0) { 7985 i--; 7986 PathPermission pp = pps[i]; 7987 String pprperm = pp.getReadPermission(); 7988 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7989 cpi.applicationInfo.uid, cpi.exported) 7990 == PackageManager.PERMISSION_GRANTED) { 7991 return null; 7992 } 7993 String ppwperm = pp.getWritePermission(); 7994 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7995 cpi.applicationInfo.uid, cpi.exported) 7996 == PackageManager.PERMISSION_GRANTED) { 7997 return null; 7998 } 7999 } 8000 } 8001 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8002 return null; 8003 } 8004 8005 String msg; 8006 if (!cpi.exported) { 8007 msg = "Permission Denial: opening provider " + cpi.name 8008 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8009 + ", uid=" + callingUid + ") that is not exported from uid " 8010 + cpi.applicationInfo.uid; 8011 } else { 8012 msg = "Permission Denial: opening provider " + cpi.name 8013 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8014 + ", uid=" + callingUid + ") requires " 8015 + cpi.readPermission + " or " + cpi.writePermission; 8016 } 8017 Slog.w(TAG, msg); 8018 return msg; 8019 } 8020 8021 /** 8022 * Returns if the ContentProvider has granted a uri to callingUid 8023 */ 8024 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8025 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8026 if (perms != null) { 8027 for (GrantUri grantUri : perms.keySet()) { 8028 if (grantUri.sourceUserId == userId || !checkUser) { 8029 if (matchesProvider(grantUri.uri, cpi)) { 8030 return true; 8031 } 8032 } 8033 } 8034 } 8035 return false; 8036 } 8037 8038 /** 8039 * Returns true if the uri authority is one of the authorities specified in the provider. 8040 */ 8041 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8042 String uriAuth = uri.getAuthority(); 8043 String cpiAuth = cpi.authority; 8044 if (cpiAuth.indexOf(';') == -1) { 8045 return cpiAuth.equals(uriAuth); 8046 } 8047 String[] cpiAuths = cpiAuth.split(";"); 8048 int length = cpiAuths.length; 8049 for (int i = 0; i < length; i++) { 8050 if (cpiAuths[i].equals(uriAuth)) return true; 8051 } 8052 return false; 8053 } 8054 8055 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8056 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8057 if (r != null) { 8058 for (int i=0; i<r.conProviders.size(); i++) { 8059 ContentProviderConnection conn = r.conProviders.get(i); 8060 if (conn.provider == cpr) { 8061 if (DEBUG_PROVIDER) Slog.v(TAG, 8062 "Adding provider requested by " 8063 + r.processName + " from process " 8064 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8065 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8066 if (stable) { 8067 conn.stableCount++; 8068 conn.numStableIncs++; 8069 } else { 8070 conn.unstableCount++; 8071 conn.numUnstableIncs++; 8072 } 8073 return conn; 8074 } 8075 } 8076 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8077 if (stable) { 8078 conn.stableCount = 1; 8079 conn.numStableIncs = 1; 8080 } else { 8081 conn.unstableCount = 1; 8082 conn.numUnstableIncs = 1; 8083 } 8084 cpr.connections.add(conn); 8085 r.conProviders.add(conn); 8086 return conn; 8087 } 8088 cpr.addExternalProcessHandleLocked(externalProcessToken); 8089 return null; 8090 } 8091 8092 boolean decProviderCountLocked(ContentProviderConnection conn, 8093 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8094 if (conn != null) { 8095 cpr = conn.provider; 8096 if (DEBUG_PROVIDER) Slog.v(TAG, 8097 "Removing provider requested by " 8098 + conn.client.processName + " from process " 8099 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8100 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8101 if (stable) { 8102 conn.stableCount--; 8103 } else { 8104 conn.unstableCount--; 8105 } 8106 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8107 cpr.connections.remove(conn); 8108 conn.client.conProviders.remove(conn); 8109 return true; 8110 } 8111 return false; 8112 } 8113 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8114 return false; 8115 } 8116 8117 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8118 String name, IBinder token, boolean stable, int userId) { 8119 ContentProviderRecord cpr; 8120 ContentProviderConnection conn = null; 8121 ProviderInfo cpi = null; 8122 8123 synchronized(this) { 8124 ProcessRecord r = null; 8125 if (caller != null) { 8126 r = getRecordForAppLocked(caller); 8127 if (r == null) { 8128 throw new SecurityException( 8129 "Unable to find app for caller " + caller 8130 + " (pid=" + Binder.getCallingPid() 8131 + ") when getting content provider " + name); 8132 } 8133 } 8134 8135 boolean checkCrossUser = true; 8136 8137 // First check if this content provider has been published... 8138 cpr = mProviderMap.getProviderByName(name, userId); 8139 // If that didn't work, check if it exists for user 0 and then 8140 // verify that it's a singleton provider before using it. 8141 if (cpr == null && userId != UserHandle.USER_OWNER) { 8142 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8143 if (cpr != null) { 8144 cpi = cpr.info; 8145 if (isSingleton(cpi.processName, cpi.applicationInfo, 8146 cpi.name, cpi.flags) 8147 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8148 userId = UserHandle.USER_OWNER; 8149 checkCrossUser = false; 8150 } else { 8151 cpr = null; 8152 cpi = null; 8153 } 8154 } 8155 } 8156 8157 boolean providerRunning = cpr != null; 8158 if (providerRunning) { 8159 cpi = cpr.info; 8160 String msg; 8161 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8162 != null) { 8163 throw new SecurityException(msg); 8164 } 8165 8166 if (r != null && cpr.canRunHere(r)) { 8167 // This provider has been published or is in the process 8168 // of being published... but it is also allowed to run 8169 // in the caller's process, so don't make a connection 8170 // and just let the caller instantiate its own instance. 8171 ContentProviderHolder holder = cpr.newHolder(null); 8172 // don't give caller the provider object, it needs 8173 // to make its own. 8174 holder.provider = null; 8175 return holder; 8176 } 8177 8178 final long origId = Binder.clearCallingIdentity(); 8179 8180 // In this case the provider instance already exists, so we can 8181 // return it right away. 8182 conn = incProviderCountLocked(r, cpr, token, stable); 8183 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8184 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8185 // If this is a perceptible app accessing the provider, 8186 // make sure to count it as being accessed and thus 8187 // back up on the LRU list. This is good because 8188 // content providers are often expensive to start. 8189 updateLruProcessLocked(cpr.proc, false, null); 8190 } 8191 } 8192 8193 if (cpr.proc != null) { 8194 if (false) { 8195 if (cpr.name.flattenToShortString().equals( 8196 "com.android.providers.calendar/.CalendarProvider2")) { 8197 Slog.v(TAG, "****************** KILLING " 8198 + cpr.name.flattenToShortString()); 8199 Process.killProcess(cpr.proc.pid); 8200 } 8201 } 8202 boolean success = updateOomAdjLocked(cpr.proc); 8203 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8204 // NOTE: there is still a race here where a signal could be 8205 // pending on the process even though we managed to update its 8206 // adj level. Not sure what to do about this, but at least 8207 // the race is now smaller. 8208 if (!success) { 8209 // Uh oh... it looks like the provider's process 8210 // has been killed on us. We need to wait for a new 8211 // process to be started, and make sure its death 8212 // doesn't kill our process. 8213 Slog.i(TAG, 8214 "Existing provider " + cpr.name.flattenToShortString() 8215 + " is crashing; detaching " + r); 8216 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8217 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8218 if (!lastRef) { 8219 // This wasn't the last ref our process had on 8220 // the provider... we have now been killed, bail. 8221 return null; 8222 } 8223 providerRunning = false; 8224 conn = null; 8225 } 8226 } 8227 8228 Binder.restoreCallingIdentity(origId); 8229 } 8230 8231 boolean singleton; 8232 if (!providerRunning) { 8233 try { 8234 cpi = AppGlobals.getPackageManager(). 8235 resolveContentProvider(name, 8236 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8237 } catch (RemoteException ex) { 8238 } 8239 if (cpi == null) { 8240 return null; 8241 } 8242 // If the provider is a singleton AND 8243 // (it's a call within the same user || the provider is a 8244 // privileged app) 8245 // Then allow connecting to the singleton provider 8246 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8247 cpi.name, cpi.flags) 8248 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8249 if (singleton) { 8250 userId = UserHandle.USER_OWNER; 8251 } 8252 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8253 8254 String msg; 8255 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8256 != null) { 8257 throw new SecurityException(msg); 8258 } 8259 8260 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8261 && !cpi.processName.equals("system")) { 8262 // If this content provider does not run in the system 8263 // process, and the system is not yet ready to run other 8264 // processes, then fail fast instead of hanging. 8265 throw new IllegalArgumentException( 8266 "Attempt to launch content provider before system ready"); 8267 } 8268 8269 // Make sure that the user who owns this provider is started. If not, 8270 // we don't want to allow it to run. 8271 if (mStartedUsers.get(userId) == null) { 8272 Slog.w(TAG, "Unable to launch app " 8273 + cpi.applicationInfo.packageName + "/" 8274 + cpi.applicationInfo.uid + " for provider " 8275 + name + ": user " + userId + " is stopped"); 8276 return null; 8277 } 8278 8279 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8280 cpr = mProviderMap.getProviderByClass(comp, userId); 8281 final boolean firstClass = cpr == null; 8282 if (firstClass) { 8283 try { 8284 ApplicationInfo ai = 8285 AppGlobals.getPackageManager(). 8286 getApplicationInfo( 8287 cpi.applicationInfo.packageName, 8288 STOCK_PM_FLAGS, userId); 8289 if (ai == null) { 8290 Slog.w(TAG, "No package info for content provider " 8291 + cpi.name); 8292 return null; 8293 } 8294 ai = getAppInfoForUser(ai, userId); 8295 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8296 } catch (RemoteException ex) { 8297 // pm is in same process, this will never happen. 8298 } 8299 } 8300 8301 if (r != null && cpr.canRunHere(r)) { 8302 // If this is a multiprocess provider, then just return its 8303 // info and allow the caller to instantiate it. Only do 8304 // this if the provider is the same user as the caller's 8305 // process, or can run as root (so can be in any process). 8306 return cpr.newHolder(null); 8307 } 8308 8309 if (DEBUG_PROVIDER) { 8310 RuntimeException e = new RuntimeException("here"); 8311 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8312 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8313 } 8314 8315 // This is single process, and our app is now connecting to it. 8316 // See if we are already in the process of launching this 8317 // provider. 8318 final int N = mLaunchingProviders.size(); 8319 int i; 8320 for (i=0; i<N; i++) { 8321 if (mLaunchingProviders.get(i) == cpr) { 8322 break; 8323 } 8324 } 8325 8326 // If the provider is not already being launched, then get it 8327 // started. 8328 if (i >= N) { 8329 final long origId = Binder.clearCallingIdentity(); 8330 8331 try { 8332 // Content provider is now in use, its package can't be stopped. 8333 try { 8334 AppGlobals.getPackageManager().setPackageStoppedState( 8335 cpr.appInfo.packageName, false, userId); 8336 } catch (RemoteException e) { 8337 } catch (IllegalArgumentException e) { 8338 Slog.w(TAG, "Failed trying to unstop package " 8339 + cpr.appInfo.packageName + ": " + e); 8340 } 8341 8342 // Use existing process if already started 8343 ProcessRecord proc = getProcessRecordLocked( 8344 cpi.processName, cpr.appInfo.uid, false); 8345 if (proc != null && proc.thread != null) { 8346 if (DEBUG_PROVIDER) { 8347 Slog.d(TAG, "Installing in existing process " + proc); 8348 } 8349 proc.pubProviders.put(cpi.name, cpr); 8350 try { 8351 proc.thread.scheduleInstallProvider(cpi); 8352 } catch (RemoteException e) { 8353 } 8354 } else { 8355 proc = startProcessLocked(cpi.processName, 8356 cpr.appInfo, false, 0, "content provider", 8357 new ComponentName(cpi.applicationInfo.packageName, 8358 cpi.name), false, false, false); 8359 if (proc == null) { 8360 Slog.w(TAG, "Unable to launch app " 8361 + cpi.applicationInfo.packageName + "/" 8362 + cpi.applicationInfo.uid + " for provider " 8363 + name + ": process is bad"); 8364 return null; 8365 } 8366 } 8367 cpr.launchingApp = proc; 8368 mLaunchingProviders.add(cpr); 8369 } finally { 8370 Binder.restoreCallingIdentity(origId); 8371 } 8372 } 8373 8374 // Make sure the provider is published (the same provider class 8375 // may be published under multiple names). 8376 if (firstClass) { 8377 mProviderMap.putProviderByClass(comp, cpr); 8378 } 8379 8380 mProviderMap.putProviderByName(name, cpr); 8381 conn = incProviderCountLocked(r, cpr, token, stable); 8382 if (conn != null) { 8383 conn.waiting = true; 8384 } 8385 } 8386 } 8387 8388 // Wait for the provider to be published... 8389 synchronized (cpr) { 8390 while (cpr.provider == null) { 8391 if (cpr.launchingApp == null) { 8392 Slog.w(TAG, "Unable to launch app " 8393 + cpi.applicationInfo.packageName + "/" 8394 + cpi.applicationInfo.uid + " for provider " 8395 + name + ": launching app became null"); 8396 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8397 UserHandle.getUserId(cpi.applicationInfo.uid), 8398 cpi.applicationInfo.packageName, 8399 cpi.applicationInfo.uid, name); 8400 return null; 8401 } 8402 try { 8403 if (DEBUG_MU) { 8404 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8405 + cpr.launchingApp); 8406 } 8407 if (conn != null) { 8408 conn.waiting = true; 8409 } 8410 cpr.wait(); 8411 } catch (InterruptedException ex) { 8412 } finally { 8413 if (conn != null) { 8414 conn.waiting = false; 8415 } 8416 } 8417 } 8418 } 8419 return cpr != null ? cpr.newHolder(conn) : null; 8420 } 8421 8422 @Override 8423 public final ContentProviderHolder getContentProvider( 8424 IApplicationThread caller, String name, int userId, boolean stable) { 8425 enforceNotIsolatedCaller("getContentProvider"); 8426 if (caller == null) { 8427 String msg = "null IApplicationThread when getting content provider " 8428 + name; 8429 Slog.w(TAG, msg); 8430 throw new SecurityException(msg); 8431 } 8432 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8433 // with cross-user grant. 8434 return getContentProviderImpl(caller, name, null, stable, userId); 8435 } 8436 8437 public ContentProviderHolder getContentProviderExternal( 8438 String name, int userId, IBinder token) { 8439 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8440 "Do not have permission in call getContentProviderExternal()"); 8441 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8442 false, true, "getContentProvider", null); 8443 return getContentProviderExternalUnchecked(name, token, userId); 8444 } 8445 8446 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8447 IBinder token, int userId) { 8448 return getContentProviderImpl(null, name, token, true, userId); 8449 } 8450 8451 /** 8452 * Drop a content provider from a ProcessRecord's bookkeeping 8453 */ 8454 public void removeContentProvider(IBinder connection, boolean stable) { 8455 enforceNotIsolatedCaller("removeContentProvider"); 8456 long ident = Binder.clearCallingIdentity(); 8457 try { 8458 synchronized (this) { 8459 ContentProviderConnection conn; 8460 try { 8461 conn = (ContentProviderConnection)connection; 8462 } catch (ClassCastException e) { 8463 String msg ="removeContentProvider: " + connection 8464 + " not a ContentProviderConnection"; 8465 Slog.w(TAG, msg); 8466 throw new IllegalArgumentException(msg); 8467 } 8468 if (conn == null) { 8469 throw new NullPointerException("connection is null"); 8470 } 8471 if (decProviderCountLocked(conn, null, null, stable)) { 8472 updateOomAdjLocked(); 8473 } 8474 } 8475 } finally { 8476 Binder.restoreCallingIdentity(ident); 8477 } 8478 } 8479 8480 public void removeContentProviderExternal(String name, IBinder token) { 8481 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8482 "Do not have permission in call removeContentProviderExternal()"); 8483 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8484 } 8485 8486 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8487 synchronized (this) { 8488 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8489 if(cpr == null) { 8490 //remove from mProvidersByClass 8491 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8492 return; 8493 } 8494 8495 //update content provider record entry info 8496 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8497 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8498 if (localCpr.hasExternalProcessHandles()) { 8499 if (localCpr.removeExternalProcessHandleLocked(token)) { 8500 updateOomAdjLocked(); 8501 } else { 8502 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8503 + " with no external reference for token: " 8504 + token + "."); 8505 } 8506 } else { 8507 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8508 + " with no external references."); 8509 } 8510 } 8511 } 8512 8513 public final void publishContentProviders(IApplicationThread caller, 8514 List<ContentProviderHolder> providers) { 8515 if (providers == null) { 8516 return; 8517 } 8518 8519 enforceNotIsolatedCaller("publishContentProviders"); 8520 synchronized (this) { 8521 final ProcessRecord r = getRecordForAppLocked(caller); 8522 if (DEBUG_MU) 8523 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8524 if (r == null) { 8525 throw new SecurityException( 8526 "Unable to find app for caller " + caller 8527 + " (pid=" + Binder.getCallingPid() 8528 + ") when publishing content providers"); 8529 } 8530 8531 final long origId = Binder.clearCallingIdentity(); 8532 8533 final int N = providers.size(); 8534 for (int i=0; i<N; i++) { 8535 ContentProviderHolder src = providers.get(i); 8536 if (src == null || src.info == null || src.provider == null) { 8537 continue; 8538 } 8539 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8540 if (DEBUG_MU) 8541 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8542 if (dst != null) { 8543 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8544 mProviderMap.putProviderByClass(comp, dst); 8545 String names[] = dst.info.authority.split(";"); 8546 for (int j = 0; j < names.length; j++) { 8547 mProviderMap.putProviderByName(names[j], dst); 8548 } 8549 8550 int NL = mLaunchingProviders.size(); 8551 int j; 8552 for (j=0; j<NL; j++) { 8553 if (mLaunchingProviders.get(j) == dst) { 8554 mLaunchingProviders.remove(j); 8555 j--; 8556 NL--; 8557 } 8558 } 8559 synchronized (dst) { 8560 dst.provider = src.provider; 8561 dst.proc = r; 8562 dst.notifyAll(); 8563 } 8564 updateOomAdjLocked(r); 8565 } 8566 } 8567 8568 Binder.restoreCallingIdentity(origId); 8569 } 8570 } 8571 8572 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8573 ContentProviderConnection conn; 8574 try { 8575 conn = (ContentProviderConnection)connection; 8576 } catch (ClassCastException e) { 8577 String msg ="refContentProvider: " + connection 8578 + " not a ContentProviderConnection"; 8579 Slog.w(TAG, msg); 8580 throw new IllegalArgumentException(msg); 8581 } 8582 if (conn == null) { 8583 throw new NullPointerException("connection is null"); 8584 } 8585 8586 synchronized (this) { 8587 if (stable > 0) { 8588 conn.numStableIncs += stable; 8589 } 8590 stable = conn.stableCount + stable; 8591 if (stable < 0) { 8592 throw new IllegalStateException("stableCount < 0: " + stable); 8593 } 8594 8595 if (unstable > 0) { 8596 conn.numUnstableIncs += unstable; 8597 } 8598 unstable = conn.unstableCount + unstable; 8599 if (unstable < 0) { 8600 throw new IllegalStateException("unstableCount < 0: " + unstable); 8601 } 8602 8603 if ((stable+unstable) <= 0) { 8604 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8605 + stable + " unstable=" + unstable); 8606 } 8607 conn.stableCount = stable; 8608 conn.unstableCount = unstable; 8609 return !conn.dead; 8610 } 8611 } 8612 8613 public void unstableProviderDied(IBinder connection) { 8614 ContentProviderConnection conn; 8615 try { 8616 conn = (ContentProviderConnection)connection; 8617 } catch (ClassCastException e) { 8618 String msg ="refContentProvider: " + connection 8619 + " not a ContentProviderConnection"; 8620 Slog.w(TAG, msg); 8621 throw new IllegalArgumentException(msg); 8622 } 8623 if (conn == null) { 8624 throw new NullPointerException("connection is null"); 8625 } 8626 8627 // Safely retrieve the content provider associated with the connection. 8628 IContentProvider provider; 8629 synchronized (this) { 8630 provider = conn.provider.provider; 8631 } 8632 8633 if (provider == null) { 8634 // Um, yeah, we're way ahead of you. 8635 return; 8636 } 8637 8638 // Make sure the caller is being honest with us. 8639 if (provider.asBinder().pingBinder()) { 8640 // Er, no, still looks good to us. 8641 synchronized (this) { 8642 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8643 + " says " + conn + " died, but we don't agree"); 8644 return; 8645 } 8646 } 8647 8648 // Well look at that! It's dead! 8649 synchronized (this) { 8650 if (conn.provider.provider != provider) { 8651 // But something changed... good enough. 8652 return; 8653 } 8654 8655 ProcessRecord proc = conn.provider.proc; 8656 if (proc == null || proc.thread == null) { 8657 // Seems like the process is already cleaned up. 8658 return; 8659 } 8660 8661 // As far as we're concerned, this is just like receiving a 8662 // death notification... just a bit prematurely. 8663 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8664 + ") early provider death"); 8665 final long ident = Binder.clearCallingIdentity(); 8666 try { 8667 appDiedLocked(proc, proc.pid, proc.thread); 8668 } finally { 8669 Binder.restoreCallingIdentity(ident); 8670 } 8671 } 8672 } 8673 8674 @Override 8675 public void appNotRespondingViaProvider(IBinder connection) { 8676 enforceCallingPermission( 8677 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8678 8679 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8680 if (conn == null) { 8681 Slog.w(TAG, "ContentProviderConnection is null"); 8682 return; 8683 } 8684 8685 final ProcessRecord host = conn.provider.proc; 8686 if (host == null) { 8687 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8688 return; 8689 } 8690 8691 final long token = Binder.clearCallingIdentity(); 8692 try { 8693 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8694 } finally { 8695 Binder.restoreCallingIdentity(token); 8696 } 8697 } 8698 8699 public final void installSystemProviders() { 8700 List<ProviderInfo> providers; 8701 synchronized (this) { 8702 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8703 providers = generateApplicationProvidersLocked(app); 8704 if (providers != null) { 8705 for (int i=providers.size()-1; i>=0; i--) { 8706 ProviderInfo pi = (ProviderInfo)providers.get(i); 8707 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8708 Slog.w(TAG, "Not installing system proc provider " + pi.name 8709 + ": not system .apk"); 8710 providers.remove(i); 8711 } 8712 } 8713 } 8714 } 8715 if (providers != null) { 8716 mSystemThread.installSystemProviders(providers); 8717 } 8718 8719 mCoreSettingsObserver = new CoreSettingsObserver(this); 8720 8721 mUsageStatsService.monitorPackages(); 8722 } 8723 8724 /** 8725 * Allows app to retrieve the MIME type of a URI without having permission 8726 * to access its content provider. 8727 * 8728 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8729 * 8730 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8731 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8732 */ 8733 public String getProviderMimeType(Uri uri, int userId) { 8734 enforceNotIsolatedCaller("getProviderMimeType"); 8735 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8736 userId, false, true, "getProviderMimeType", null); 8737 final String name = uri.getAuthority(); 8738 final long ident = Binder.clearCallingIdentity(); 8739 ContentProviderHolder holder = null; 8740 8741 try { 8742 holder = getContentProviderExternalUnchecked(name, null, userId); 8743 if (holder != null) { 8744 return holder.provider.getType(uri); 8745 } 8746 } catch (RemoteException e) { 8747 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8748 return null; 8749 } finally { 8750 if (holder != null) { 8751 removeContentProviderExternalUnchecked(name, null, userId); 8752 } 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 8756 return null; 8757 } 8758 8759 // ========================================================= 8760 // GLOBAL MANAGEMENT 8761 // ========================================================= 8762 8763 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8764 boolean isolated) { 8765 String proc = customProcess != null ? customProcess : info.processName; 8766 BatteryStatsImpl.Uid.Proc ps = null; 8767 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8768 int uid = info.uid; 8769 if (isolated) { 8770 int userId = UserHandle.getUserId(uid); 8771 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8772 while (true) { 8773 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8774 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8775 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8776 } 8777 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8778 mNextIsolatedProcessUid++; 8779 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8780 // No process for this uid, use it. 8781 break; 8782 } 8783 stepsLeft--; 8784 if (stepsLeft <= 0) { 8785 return null; 8786 } 8787 } 8788 } 8789 return new ProcessRecord(stats, info, proc, uid); 8790 } 8791 8792 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8793 String abiOverride) { 8794 ProcessRecord app; 8795 if (!isolated) { 8796 app = getProcessRecordLocked(info.processName, info.uid, true); 8797 } else { 8798 app = null; 8799 } 8800 8801 if (app == null) { 8802 app = newProcessRecordLocked(info, null, isolated); 8803 mProcessNames.put(info.processName, app.uid, app); 8804 if (isolated) { 8805 mIsolatedProcesses.put(app.uid, app); 8806 } 8807 updateLruProcessLocked(app, false, null); 8808 updateOomAdjLocked(); 8809 } 8810 8811 // This package really, really can not be stopped. 8812 try { 8813 AppGlobals.getPackageManager().setPackageStoppedState( 8814 info.packageName, false, UserHandle.getUserId(app.uid)); 8815 } catch (RemoteException e) { 8816 } catch (IllegalArgumentException e) { 8817 Slog.w(TAG, "Failed trying to unstop package " 8818 + info.packageName + ": " + e); 8819 } 8820 8821 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8822 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8823 app.persistent = true; 8824 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8825 } 8826 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8827 mPersistentStartingProcesses.add(app); 8828 startProcessLocked(app, "added application", app.processName, 8829 abiOverride); 8830 } 8831 8832 return app; 8833 } 8834 8835 public void unhandledBack() { 8836 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8837 "unhandledBack()"); 8838 8839 synchronized(this) { 8840 final long origId = Binder.clearCallingIdentity(); 8841 try { 8842 getFocusedStack().unhandledBackLocked(); 8843 } finally { 8844 Binder.restoreCallingIdentity(origId); 8845 } 8846 } 8847 } 8848 8849 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8850 enforceNotIsolatedCaller("openContentUri"); 8851 final int userId = UserHandle.getCallingUserId(); 8852 String name = uri.getAuthority(); 8853 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8854 ParcelFileDescriptor pfd = null; 8855 if (cph != null) { 8856 // We record the binder invoker's uid in thread-local storage before 8857 // going to the content provider to open the file. Later, in the code 8858 // that handles all permissions checks, we look for this uid and use 8859 // that rather than the Activity Manager's own uid. The effect is that 8860 // we do the check against the caller's permissions even though it looks 8861 // to the content provider like the Activity Manager itself is making 8862 // the request. 8863 sCallerIdentity.set(new Identity( 8864 Binder.getCallingPid(), Binder.getCallingUid())); 8865 try { 8866 pfd = cph.provider.openFile(null, uri, "r", null); 8867 } catch (FileNotFoundException e) { 8868 // do nothing; pfd will be returned null 8869 } finally { 8870 // Ensure that whatever happens, we clean up the identity state 8871 sCallerIdentity.remove(); 8872 } 8873 8874 // We've got the fd now, so we're done with the provider. 8875 removeContentProviderExternalUnchecked(name, null, userId); 8876 } else { 8877 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8878 } 8879 return pfd; 8880 } 8881 8882 // Actually is sleeping or shutting down or whatever else in the future 8883 // is an inactive state. 8884 public boolean isSleepingOrShuttingDown() { 8885 return mSleeping || mShuttingDown; 8886 } 8887 8888 public boolean isSleeping() { 8889 return mSleeping; 8890 } 8891 8892 void goingToSleep() { 8893 synchronized(this) { 8894 mWentToSleep = true; 8895 updateEventDispatchingLocked(); 8896 goToSleepIfNeededLocked(); 8897 } 8898 } 8899 8900 void finishRunningVoiceLocked() { 8901 if (mRunningVoice) { 8902 mRunningVoice = false; 8903 goToSleepIfNeededLocked(); 8904 } 8905 } 8906 8907 void goToSleepIfNeededLocked() { 8908 if (mWentToSleep && !mRunningVoice) { 8909 if (!mSleeping) { 8910 mSleeping = true; 8911 mStackSupervisor.goingToSleepLocked(); 8912 8913 // Initialize the wake times of all processes. 8914 checkExcessivePowerUsageLocked(false); 8915 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8916 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8917 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8918 } 8919 } 8920 } 8921 8922 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8923 mTaskPersister.notify(task, flush); 8924 } 8925 8926 @Override 8927 public boolean shutdown(int timeout) { 8928 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8929 != PackageManager.PERMISSION_GRANTED) { 8930 throw new SecurityException("Requires permission " 8931 + android.Manifest.permission.SHUTDOWN); 8932 } 8933 8934 boolean timedout = false; 8935 8936 synchronized(this) { 8937 mShuttingDown = true; 8938 updateEventDispatchingLocked(); 8939 timedout = mStackSupervisor.shutdownLocked(timeout); 8940 } 8941 8942 mAppOpsService.shutdown(); 8943 mUsageStatsService.shutdown(); 8944 mBatteryStatsService.shutdown(); 8945 synchronized (this) { 8946 mProcessStats.shutdownLocked(); 8947 } 8948 notifyTaskPersisterLocked(null, true); 8949 8950 return timedout; 8951 } 8952 8953 public final void activitySlept(IBinder token) { 8954 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8955 8956 final long origId = Binder.clearCallingIdentity(); 8957 8958 synchronized (this) { 8959 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8960 if (r != null) { 8961 mStackSupervisor.activitySleptLocked(r); 8962 } 8963 } 8964 8965 Binder.restoreCallingIdentity(origId); 8966 } 8967 8968 void logLockScreen(String msg) { 8969 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8970 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8971 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8972 mStackSupervisor.mDismissKeyguardOnNextActivity); 8973 } 8974 8975 private void comeOutOfSleepIfNeededLocked() { 8976 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8977 if (mSleeping) { 8978 mSleeping = false; 8979 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8980 } 8981 } 8982 } 8983 8984 void wakingUp() { 8985 synchronized(this) { 8986 mWentToSleep = false; 8987 updateEventDispatchingLocked(); 8988 comeOutOfSleepIfNeededLocked(); 8989 } 8990 } 8991 8992 void startRunningVoiceLocked() { 8993 if (!mRunningVoice) { 8994 mRunningVoice = true; 8995 comeOutOfSleepIfNeededLocked(); 8996 } 8997 } 8998 8999 private void updateEventDispatchingLocked() { 9000 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9001 } 9002 9003 public void setLockScreenShown(boolean shown) { 9004 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9005 != PackageManager.PERMISSION_GRANTED) { 9006 throw new SecurityException("Requires permission " 9007 + android.Manifest.permission.DEVICE_POWER); 9008 } 9009 9010 synchronized(this) { 9011 long ident = Binder.clearCallingIdentity(); 9012 try { 9013 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9014 mLockScreenShown = shown; 9015 comeOutOfSleepIfNeededLocked(); 9016 } finally { 9017 Binder.restoreCallingIdentity(ident); 9018 } 9019 } 9020 } 9021 9022 public void stopAppSwitches() { 9023 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9024 != PackageManager.PERMISSION_GRANTED) { 9025 throw new SecurityException("Requires permission " 9026 + android.Manifest.permission.STOP_APP_SWITCHES); 9027 } 9028 9029 synchronized(this) { 9030 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9031 + APP_SWITCH_DELAY_TIME; 9032 mDidAppSwitch = false; 9033 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9034 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9035 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9036 } 9037 } 9038 9039 public void resumeAppSwitches() { 9040 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9041 != PackageManager.PERMISSION_GRANTED) { 9042 throw new SecurityException("Requires permission " 9043 + android.Manifest.permission.STOP_APP_SWITCHES); 9044 } 9045 9046 synchronized(this) { 9047 // Note that we don't execute any pending app switches... we will 9048 // let those wait until either the timeout, or the next start 9049 // activity request. 9050 mAppSwitchesAllowedTime = 0; 9051 } 9052 } 9053 9054 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9055 String name) { 9056 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9057 return true; 9058 } 9059 9060 final int perm = checkComponentPermission( 9061 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9062 callingUid, -1, true); 9063 if (perm == PackageManager.PERMISSION_GRANTED) { 9064 return true; 9065 } 9066 9067 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9068 return false; 9069 } 9070 9071 public void setDebugApp(String packageName, boolean waitForDebugger, 9072 boolean persistent) { 9073 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9074 "setDebugApp()"); 9075 9076 long ident = Binder.clearCallingIdentity(); 9077 try { 9078 // Note that this is not really thread safe if there are multiple 9079 // callers into it at the same time, but that's not a situation we 9080 // care about. 9081 if (persistent) { 9082 final ContentResolver resolver = mContext.getContentResolver(); 9083 Settings.Global.putString( 9084 resolver, Settings.Global.DEBUG_APP, 9085 packageName); 9086 Settings.Global.putInt( 9087 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9088 waitForDebugger ? 1 : 0); 9089 } 9090 9091 synchronized (this) { 9092 if (!persistent) { 9093 mOrigDebugApp = mDebugApp; 9094 mOrigWaitForDebugger = mWaitForDebugger; 9095 } 9096 mDebugApp = packageName; 9097 mWaitForDebugger = waitForDebugger; 9098 mDebugTransient = !persistent; 9099 if (packageName != null) { 9100 forceStopPackageLocked(packageName, -1, false, false, true, true, 9101 false, UserHandle.USER_ALL, "set debug app"); 9102 } 9103 } 9104 } finally { 9105 Binder.restoreCallingIdentity(ident); 9106 } 9107 } 9108 9109 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9110 synchronized (this) { 9111 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9112 if (!isDebuggable) { 9113 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9114 throw new SecurityException("Process not debuggable: " + app.packageName); 9115 } 9116 } 9117 9118 mOpenGlTraceApp = processName; 9119 } 9120 } 9121 9122 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9123 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9124 synchronized (this) { 9125 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9126 if (!isDebuggable) { 9127 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9128 throw new SecurityException("Process not debuggable: " + app.packageName); 9129 } 9130 } 9131 mProfileApp = processName; 9132 mProfileFile = profileFile; 9133 if (mProfileFd != null) { 9134 try { 9135 mProfileFd.close(); 9136 } catch (IOException e) { 9137 } 9138 mProfileFd = null; 9139 } 9140 mProfileFd = profileFd; 9141 mProfileType = 0; 9142 mAutoStopProfiler = autoStopProfiler; 9143 } 9144 } 9145 9146 @Override 9147 public void setAlwaysFinish(boolean enabled) { 9148 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9149 "setAlwaysFinish()"); 9150 9151 Settings.Global.putInt( 9152 mContext.getContentResolver(), 9153 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9154 9155 synchronized (this) { 9156 mAlwaysFinishActivities = enabled; 9157 } 9158 } 9159 9160 @Override 9161 public void setActivityController(IActivityController controller) { 9162 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9163 "setActivityController()"); 9164 synchronized (this) { 9165 mController = controller; 9166 Watchdog.getInstance().setActivityController(controller); 9167 } 9168 } 9169 9170 @Override 9171 public void setUserIsMonkey(boolean userIsMonkey) { 9172 synchronized (this) { 9173 synchronized (mPidsSelfLocked) { 9174 final int callingPid = Binder.getCallingPid(); 9175 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9176 if (precessRecord == null) { 9177 throw new SecurityException("Unknown process: " + callingPid); 9178 } 9179 if (precessRecord.instrumentationUiAutomationConnection == null) { 9180 throw new SecurityException("Only an instrumentation process " 9181 + "with a UiAutomation can call setUserIsMonkey"); 9182 } 9183 } 9184 mUserIsMonkey = userIsMonkey; 9185 } 9186 } 9187 9188 @Override 9189 public boolean isUserAMonkey() { 9190 synchronized (this) { 9191 // If there is a controller also implies the user is a monkey. 9192 return (mUserIsMonkey || mController != null); 9193 } 9194 } 9195 9196 public void requestBugReport() { 9197 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9198 SystemProperties.set("ctl.start", "bugreport"); 9199 } 9200 9201 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9202 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9203 } 9204 9205 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9206 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9207 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9208 } 9209 return KEY_DISPATCHING_TIMEOUT; 9210 } 9211 9212 @Override 9213 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9214 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9215 != PackageManager.PERMISSION_GRANTED) { 9216 throw new SecurityException("Requires permission " 9217 + android.Manifest.permission.FILTER_EVENTS); 9218 } 9219 ProcessRecord proc; 9220 long timeout; 9221 synchronized (this) { 9222 synchronized (mPidsSelfLocked) { 9223 proc = mPidsSelfLocked.get(pid); 9224 } 9225 timeout = getInputDispatchingTimeoutLocked(proc); 9226 } 9227 9228 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9229 return -1; 9230 } 9231 9232 return timeout; 9233 } 9234 9235 /** 9236 * Handle input dispatching timeouts. 9237 * Returns whether input dispatching should be aborted or not. 9238 */ 9239 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9240 final ActivityRecord activity, final ActivityRecord parent, 9241 final boolean aboveSystem, String reason) { 9242 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9243 != PackageManager.PERMISSION_GRANTED) { 9244 throw new SecurityException("Requires permission " 9245 + android.Manifest.permission.FILTER_EVENTS); 9246 } 9247 9248 final String annotation; 9249 if (reason == null) { 9250 annotation = "Input dispatching timed out"; 9251 } else { 9252 annotation = "Input dispatching timed out (" + reason + ")"; 9253 } 9254 9255 if (proc != null) { 9256 synchronized (this) { 9257 if (proc.debugging) { 9258 return false; 9259 } 9260 9261 if (mDidDexOpt) { 9262 // Give more time since we were dexopting. 9263 mDidDexOpt = false; 9264 return false; 9265 } 9266 9267 if (proc.instrumentationClass != null) { 9268 Bundle info = new Bundle(); 9269 info.putString("shortMsg", "keyDispatchingTimedOut"); 9270 info.putString("longMsg", annotation); 9271 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9272 return true; 9273 } 9274 } 9275 mHandler.post(new Runnable() { 9276 @Override 9277 public void run() { 9278 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9279 } 9280 }); 9281 } 9282 9283 return true; 9284 } 9285 9286 public Bundle getAssistContextExtras(int requestType) { 9287 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9288 "getAssistContextExtras()"); 9289 PendingAssistExtras pae; 9290 Bundle extras = new Bundle(); 9291 synchronized (this) { 9292 ActivityRecord activity = getFocusedStack().mResumedActivity; 9293 if (activity == null) { 9294 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9295 return null; 9296 } 9297 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9298 if (activity.app == null || activity.app.thread == null) { 9299 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9300 return extras; 9301 } 9302 if (activity.app.pid == Binder.getCallingPid()) { 9303 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9304 return extras; 9305 } 9306 pae = new PendingAssistExtras(activity); 9307 try { 9308 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9309 requestType); 9310 mPendingAssistExtras.add(pae); 9311 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9312 } catch (RemoteException e) { 9313 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9314 return extras; 9315 } 9316 } 9317 synchronized (pae) { 9318 while (!pae.haveResult) { 9319 try { 9320 pae.wait(); 9321 } catch (InterruptedException e) { 9322 } 9323 } 9324 if (pae.result != null) { 9325 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9326 } 9327 } 9328 synchronized (this) { 9329 mPendingAssistExtras.remove(pae); 9330 mHandler.removeCallbacks(pae); 9331 } 9332 return extras; 9333 } 9334 9335 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9336 PendingAssistExtras pae = (PendingAssistExtras)token; 9337 synchronized (pae) { 9338 pae.result = extras; 9339 pae.haveResult = true; 9340 pae.notifyAll(); 9341 } 9342 } 9343 9344 public void registerProcessObserver(IProcessObserver observer) { 9345 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9346 "registerProcessObserver()"); 9347 synchronized (this) { 9348 mProcessObservers.register(observer); 9349 } 9350 } 9351 9352 @Override 9353 public void unregisterProcessObserver(IProcessObserver observer) { 9354 synchronized (this) { 9355 mProcessObservers.unregister(observer); 9356 } 9357 } 9358 9359 @Override 9360 public boolean convertFromTranslucent(IBinder token) { 9361 final long origId = Binder.clearCallingIdentity(); 9362 try { 9363 synchronized (this) { 9364 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9365 if (r == null) { 9366 return false; 9367 } 9368 if (r.changeWindowTranslucency(true)) { 9369 mWindowManager.setAppFullscreen(token, true); 9370 r.task.stack.releaseMediaResources(); 9371 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9372 return true; 9373 } 9374 return false; 9375 } 9376 } finally { 9377 Binder.restoreCallingIdentity(origId); 9378 } 9379 } 9380 9381 @Override 9382 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9383 final long origId = Binder.clearCallingIdentity(); 9384 try { 9385 synchronized (this) { 9386 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9387 if (r == null) { 9388 return false; 9389 } 9390 if (r.changeWindowTranslucency(false)) { 9391 r.task.stack.convertToTranslucent(r, options); 9392 mWindowManager.setAppFullscreen(token, false); 9393 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9394 return true; 9395 } else { 9396 r.task.stack.mReturningActivityOptions = options; 9397 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9398 return false; 9399 } 9400 } 9401 } finally { 9402 Binder.restoreCallingIdentity(origId); 9403 } 9404 } 9405 9406 @Override 9407 public boolean setMediaPlaying(IBinder token, boolean playing) { 9408 final long origId = Binder.clearCallingIdentity(); 9409 try { 9410 synchronized (this) { 9411 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9412 if (r != null) { 9413 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9414 } 9415 } 9416 return false; 9417 } finally { 9418 Binder.restoreCallingIdentity(origId); 9419 } 9420 } 9421 9422 @Override 9423 public boolean isBackgroundMediaPlaying(IBinder token) { 9424 final long origId = Binder.clearCallingIdentity(); 9425 try { 9426 synchronized (this) { 9427 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9428 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9429 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9430 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9431 return playing; 9432 } 9433 } finally { 9434 Binder.restoreCallingIdentity(origId); 9435 } 9436 } 9437 9438 @Override 9439 public ActivityOptions getActivityOptions(IBinder token) { 9440 final long origId = Binder.clearCallingIdentity(); 9441 try { 9442 synchronized (this) { 9443 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9444 if (r != null) { 9445 final ActivityOptions activityOptions = r.pendingOptions; 9446 r.pendingOptions = null; 9447 return activityOptions; 9448 } 9449 return null; 9450 } 9451 } finally { 9452 Binder.restoreCallingIdentity(origId); 9453 } 9454 } 9455 9456 @Override 9457 public void setImmersive(IBinder token, boolean immersive) { 9458 synchronized(this) { 9459 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9460 if (r == null) { 9461 throw new IllegalArgumentException(); 9462 } 9463 r.immersive = immersive; 9464 9465 // update associated state if we're frontmost 9466 if (r == mFocusedActivity) { 9467 if (DEBUG_IMMERSIVE) { 9468 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9469 } 9470 applyUpdateLockStateLocked(r); 9471 } 9472 } 9473 } 9474 9475 @Override 9476 public boolean isImmersive(IBinder token) { 9477 synchronized (this) { 9478 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9479 if (r == null) { 9480 throw new IllegalArgumentException(); 9481 } 9482 return r.immersive; 9483 } 9484 } 9485 9486 public boolean isTopActivityImmersive() { 9487 enforceNotIsolatedCaller("startActivity"); 9488 synchronized (this) { 9489 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9490 return (r != null) ? r.immersive : false; 9491 } 9492 } 9493 9494 @Override 9495 public boolean isTopOfTask(IBinder token) { 9496 synchronized (this) { 9497 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9498 if (r == null) { 9499 throw new IllegalArgumentException(); 9500 } 9501 return r.task.getTopActivity() == r; 9502 } 9503 } 9504 9505 public final void enterSafeMode() { 9506 synchronized(this) { 9507 // It only makes sense to do this before the system is ready 9508 // and started launching other packages. 9509 if (!mSystemReady) { 9510 try { 9511 AppGlobals.getPackageManager().enterSafeMode(); 9512 } catch (RemoteException e) { 9513 } 9514 } 9515 9516 mSafeMode = true; 9517 } 9518 } 9519 9520 public final void showSafeModeOverlay() { 9521 View v = LayoutInflater.from(mContext).inflate( 9522 com.android.internal.R.layout.safe_mode, null); 9523 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9524 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9525 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9526 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9527 lp.gravity = Gravity.BOTTOM | Gravity.START; 9528 lp.format = v.getBackground().getOpacity(); 9529 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9530 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9531 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9532 ((WindowManager)mContext.getSystemService( 9533 Context.WINDOW_SERVICE)).addView(v, lp); 9534 } 9535 9536 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9537 if (!(sender instanceof PendingIntentRecord)) { 9538 return; 9539 } 9540 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9541 synchronized (stats) { 9542 if (mBatteryStatsService.isOnBattery()) { 9543 mBatteryStatsService.enforceCallingPermission(); 9544 PendingIntentRecord rec = (PendingIntentRecord)sender; 9545 int MY_UID = Binder.getCallingUid(); 9546 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9547 BatteryStatsImpl.Uid.Pkg pkg = 9548 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9549 sourcePkg != null ? sourcePkg : rec.key.packageName); 9550 pkg.incWakeupsLocked(); 9551 } 9552 } 9553 } 9554 9555 public boolean killPids(int[] pids, String pReason, boolean secure) { 9556 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9557 throw new SecurityException("killPids only available to the system"); 9558 } 9559 String reason = (pReason == null) ? "Unknown" : pReason; 9560 // XXX Note: don't acquire main activity lock here, because the window 9561 // manager calls in with its locks held. 9562 9563 boolean killed = false; 9564 synchronized (mPidsSelfLocked) { 9565 int[] types = new int[pids.length]; 9566 int worstType = 0; 9567 for (int i=0; i<pids.length; i++) { 9568 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9569 if (proc != null) { 9570 int type = proc.setAdj; 9571 types[i] = type; 9572 if (type > worstType) { 9573 worstType = type; 9574 } 9575 } 9576 } 9577 9578 // If the worst oom_adj is somewhere in the cached proc LRU range, 9579 // then constrain it so we will kill all cached procs. 9580 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9581 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9582 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9583 } 9584 9585 // If this is not a secure call, don't let it kill processes that 9586 // are important. 9587 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9588 worstType = ProcessList.SERVICE_ADJ; 9589 } 9590 9591 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9592 for (int i=0; i<pids.length; i++) { 9593 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9594 if (proc == null) { 9595 continue; 9596 } 9597 int adj = proc.setAdj; 9598 if (adj >= worstType && !proc.killedByAm) { 9599 killUnneededProcessLocked(proc, reason); 9600 killed = true; 9601 } 9602 } 9603 } 9604 return killed; 9605 } 9606 9607 @Override 9608 public void killUid(int uid, String reason) { 9609 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9610 throw new SecurityException("killUid only available to the system"); 9611 } 9612 synchronized (this) { 9613 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9614 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9615 reason != null ? reason : "kill uid"); 9616 } 9617 } 9618 9619 @Override 9620 public boolean killProcessesBelowForeground(String reason) { 9621 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9622 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9623 } 9624 9625 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9626 } 9627 9628 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9629 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9630 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9631 } 9632 9633 boolean killed = false; 9634 synchronized (mPidsSelfLocked) { 9635 final int size = mPidsSelfLocked.size(); 9636 for (int i = 0; i < size; i++) { 9637 final int pid = mPidsSelfLocked.keyAt(i); 9638 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9639 if (proc == null) continue; 9640 9641 final int adj = proc.setAdj; 9642 if (adj > belowAdj && !proc.killedByAm) { 9643 killUnneededProcessLocked(proc, reason); 9644 killed = true; 9645 } 9646 } 9647 } 9648 return killed; 9649 } 9650 9651 @Override 9652 public void hang(final IBinder who, boolean allowRestart) { 9653 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9654 != PackageManager.PERMISSION_GRANTED) { 9655 throw new SecurityException("Requires permission " 9656 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9657 } 9658 9659 final IBinder.DeathRecipient death = new DeathRecipient() { 9660 @Override 9661 public void binderDied() { 9662 synchronized (this) { 9663 notifyAll(); 9664 } 9665 } 9666 }; 9667 9668 try { 9669 who.linkToDeath(death, 0); 9670 } catch (RemoteException e) { 9671 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9672 return; 9673 } 9674 9675 synchronized (this) { 9676 Watchdog.getInstance().setAllowRestart(allowRestart); 9677 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9678 synchronized (death) { 9679 while (who.isBinderAlive()) { 9680 try { 9681 death.wait(); 9682 } catch (InterruptedException e) { 9683 } 9684 } 9685 } 9686 Watchdog.getInstance().setAllowRestart(true); 9687 } 9688 } 9689 9690 @Override 9691 public void restart() { 9692 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9693 != PackageManager.PERMISSION_GRANTED) { 9694 throw new SecurityException("Requires permission " 9695 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9696 } 9697 9698 Log.i(TAG, "Sending shutdown broadcast..."); 9699 9700 BroadcastReceiver br = new BroadcastReceiver() { 9701 @Override public void onReceive(Context context, Intent intent) { 9702 // Now the broadcast is done, finish up the low-level shutdown. 9703 Log.i(TAG, "Shutting down activity manager..."); 9704 shutdown(10000); 9705 Log.i(TAG, "Shutdown complete, restarting!"); 9706 Process.killProcess(Process.myPid()); 9707 System.exit(10); 9708 } 9709 }; 9710 9711 // First send the high-level shut down broadcast. 9712 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9713 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9714 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9715 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9716 mContext.sendOrderedBroadcastAsUser(intent, 9717 UserHandle.ALL, null, br, mHandler, 0, null, null); 9718 */ 9719 br.onReceive(mContext, intent); 9720 } 9721 9722 private long getLowRamTimeSinceIdle(long now) { 9723 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9724 } 9725 9726 @Override 9727 public void performIdleMaintenance() { 9728 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9729 != PackageManager.PERMISSION_GRANTED) { 9730 throw new SecurityException("Requires permission " 9731 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9732 } 9733 9734 synchronized (this) { 9735 final long now = SystemClock.uptimeMillis(); 9736 final long timeSinceLastIdle = now - mLastIdleTime; 9737 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9738 mLastIdleTime = now; 9739 mLowRamTimeSinceLastIdle = 0; 9740 if (mLowRamStartTime != 0) { 9741 mLowRamStartTime = now; 9742 } 9743 9744 StringBuilder sb = new StringBuilder(128); 9745 sb.append("Idle maintenance over "); 9746 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9747 sb.append(" low RAM for "); 9748 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9749 Slog.i(TAG, sb.toString()); 9750 9751 // If at least 1/3 of our time since the last idle period has been spent 9752 // with RAM low, then we want to kill processes. 9753 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9754 9755 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9756 ProcessRecord proc = mLruProcesses.get(i); 9757 if (proc.notCachedSinceIdle) { 9758 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9759 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9760 if (doKilling && proc.initialIdlePss != 0 9761 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9762 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9763 + " from " + proc.initialIdlePss + ")"); 9764 } 9765 } 9766 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9767 proc.notCachedSinceIdle = true; 9768 proc.initialIdlePss = 0; 9769 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9770 isSleeping(), now); 9771 } 9772 } 9773 9774 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9775 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9776 } 9777 } 9778 9779 private void retrieveSettings() { 9780 final ContentResolver resolver = mContext.getContentResolver(); 9781 String debugApp = Settings.Global.getString( 9782 resolver, Settings.Global.DEBUG_APP); 9783 boolean waitForDebugger = Settings.Global.getInt( 9784 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9785 boolean alwaysFinishActivities = Settings.Global.getInt( 9786 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9787 boolean forceRtl = Settings.Global.getInt( 9788 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9789 // Transfer any global setting for forcing RTL layout, into a System Property 9790 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9791 9792 Configuration configuration = new Configuration(); 9793 Settings.System.getConfiguration(resolver, configuration); 9794 if (forceRtl) { 9795 // This will take care of setting the correct layout direction flags 9796 configuration.setLayoutDirection(configuration.locale); 9797 } 9798 9799 synchronized (this) { 9800 mDebugApp = mOrigDebugApp = debugApp; 9801 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9802 mAlwaysFinishActivities = alwaysFinishActivities; 9803 // This happens before any activities are started, so we can 9804 // change mConfiguration in-place. 9805 updateConfigurationLocked(configuration, null, false, true); 9806 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9807 } 9808 } 9809 9810 public boolean testIsSystemReady() { 9811 // no need to synchronize(this) just to read & return the value 9812 return mSystemReady; 9813 } 9814 9815 private static File getCalledPreBootReceiversFile() { 9816 File dataDir = Environment.getDataDirectory(); 9817 File systemDir = new File(dataDir, "system"); 9818 File fname = new File(systemDir, "called_pre_boots.dat"); 9819 return fname; 9820 } 9821 9822 static final int LAST_DONE_VERSION = 10000; 9823 9824 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9825 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9826 File file = getCalledPreBootReceiversFile(); 9827 FileInputStream fis = null; 9828 try { 9829 fis = new FileInputStream(file); 9830 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9831 int fvers = dis.readInt(); 9832 if (fvers == LAST_DONE_VERSION) { 9833 String vers = dis.readUTF(); 9834 String codename = dis.readUTF(); 9835 String build = dis.readUTF(); 9836 if (android.os.Build.VERSION.RELEASE.equals(vers) 9837 && android.os.Build.VERSION.CODENAME.equals(codename) 9838 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9839 int num = dis.readInt(); 9840 while (num > 0) { 9841 num--; 9842 String pkg = dis.readUTF(); 9843 String cls = dis.readUTF(); 9844 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9845 } 9846 } 9847 } 9848 } catch (FileNotFoundException e) { 9849 } catch (IOException e) { 9850 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9851 } finally { 9852 if (fis != null) { 9853 try { 9854 fis.close(); 9855 } catch (IOException e) { 9856 } 9857 } 9858 } 9859 return lastDoneReceivers; 9860 } 9861 9862 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9863 File file = getCalledPreBootReceiversFile(); 9864 FileOutputStream fos = null; 9865 DataOutputStream dos = null; 9866 try { 9867 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9868 fos = new FileOutputStream(file); 9869 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9870 dos.writeInt(LAST_DONE_VERSION); 9871 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9872 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9873 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9874 dos.writeInt(list.size()); 9875 for (int i=0; i<list.size(); i++) { 9876 dos.writeUTF(list.get(i).getPackageName()); 9877 dos.writeUTF(list.get(i).getClassName()); 9878 } 9879 } catch (IOException e) { 9880 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9881 file.delete(); 9882 } finally { 9883 FileUtils.sync(fos); 9884 if (dos != null) { 9885 try { 9886 dos.close(); 9887 } catch (IOException e) { 9888 // TODO Auto-generated catch block 9889 e.printStackTrace(); 9890 } 9891 } 9892 } 9893 } 9894 9895 public void systemReady(final Runnable goingCallback) { 9896 synchronized(this) { 9897 if (mSystemReady) { 9898 if (goingCallback != null) goingCallback.run(); 9899 return; 9900 } 9901 9902 if (mRecentTasks == null) { 9903 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9904 if (!mRecentTasks.isEmpty()) { 9905 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9906 } 9907 mTaskPersister.startPersisting(); 9908 } 9909 9910 // Check to see if there are any update receivers to run. 9911 if (!mDidUpdate) { 9912 if (mWaitingUpdate) { 9913 return; 9914 } 9915 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9916 List<ResolveInfo> ris = null; 9917 try { 9918 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9919 intent, null, 0, 0); 9920 } catch (RemoteException e) { 9921 } 9922 if (ris != null) { 9923 for (int i=ris.size()-1; i>=0; i--) { 9924 if ((ris.get(i).activityInfo.applicationInfo.flags 9925 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9926 ris.remove(i); 9927 } 9928 } 9929 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9930 9931 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9932 9933 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9934 for (int i=0; i<ris.size(); i++) { 9935 ActivityInfo ai = ris.get(i).activityInfo; 9936 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9937 if (lastDoneReceivers.contains(comp)) { 9938 // We already did the pre boot receiver for this app with the current 9939 // platform version, so don't do it again... 9940 ris.remove(i); 9941 i--; 9942 // ...however, do keep it as one that has been done, so we don't 9943 // forget about it when rewriting the file of last done receivers. 9944 doneReceivers.add(comp); 9945 } 9946 } 9947 9948 final int[] users = getUsersLocked(); 9949 for (int i=0; i<ris.size(); i++) { 9950 ActivityInfo ai = ris.get(i).activityInfo; 9951 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9952 doneReceivers.add(comp); 9953 intent.setComponent(comp); 9954 for (int j=0; j<users.length; j++) { 9955 IIntentReceiver finisher = null; 9956 if (i == ris.size()-1 && j == users.length-1) { 9957 finisher = new IIntentReceiver.Stub() { 9958 public void performReceive(Intent intent, int resultCode, 9959 String data, Bundle extras, boolean ordered, 9960 boolean sticky, int sendingUser) { 9961 // The raw IIntentReceiver interface is called 9962 // with the AM lock held, so redispatch to 9963 // execute our code without the lock. 9964 mHandler.post(new Runnable() { 9965 public void run() { 9966 synchronized (ActivityManagerService.this) { 9967 mDidUpdate = true; 9968 } 9969 writeLastDonePreBootReceivers(doneReceivers); 9970 showBootMessage(mContext.getText( 9971 R.string.android_upgrading_complete), 9972 false); 9973 systemReady(goingCallback); 9974 } 9975 }); 9976 } 9977 }; 9978 } 9979 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9980 + " for user " + users[j]); 9981 broadcastIntentLocked(null, null, intent, null, finisher, 9982 0, null, null, null, AppOpsManager.OP_NONE, 9983 true, false, MY_PID, Process.SYSTEM_UID, 9984 users[j]); 9985 if (finisher != null) { 9986 mWaitingUpdate = true; 9987 } 9988 } 9989 } 9990 } 9991 if (mWaitingUpdate) { 9992 return; 9993 } 9994 mDidUpdate = true; 9995 } 9996 9997 mAppOpsService.systemReady(); 9998 mUsageStatsService.systemReady(); 9999 mSystemReady = true; 10000 } 10001 10002 ArrayList<ProcessRecord> procsToKill = null; 10003 synchronized(mPidsSelfLocked) { 10004 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10005 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10006 if (!isAllowedWhileBooting(proc.info)){ 10007 if (procsToKill == null) { 10008 procsToKill = new ArrayList<ProcessRecord>(); 10009 } 10010 procsToKill.add(proc); 10011 } 10012 } 10013 } 10014 10015 synchronized(this) { 10016 if (procsToKill != null) { 10017 for (int i=procsToKill.size()-1; i>=0; i--) { 10018 ProcessRecord proc = procsToKill.get(i); 10019 Slog.i(TAG, "Removing system update proc: " + proc); 10020 removeProcessLocked(proc, true, false, "system update done"); 10021 } 10022 } 10023 10024 // Now that we have cleaned up any update processes, we 10025 // are ready to start launching real processes and know that 10026 // we won't trample on them any more. 10027 mProcessesReady = true; 10028 } 10029 10030 Slog.i(TAG, "System now ready"); 10031 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10032 SystemClock.uptimeMillis()); 10033 10034 synchronized(this) { 10035 // Make sure we have no pre-ready processes sitting around. 10036 10037 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10038 ResolveInfo ri = mContext.getPackageManager() 10039 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10040 STOCK_PM_FLAGS); 10041 CharSequence errorMsg = null; 10042 if (ri != null) { 10043 ActivityInfo ai = ri.activityInfo; 10044 ApplicationInfo app = ai.applicationInfo; 10045 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10046 mTopAction = Intent.ACTION_FACTORY_TEST; 10047 mTopData = null; 10048 mTopComponent = new ComponentName(app.packageName, 10049 ai.name); 10050 } else { 10051 errorMsg = mContext.getResources().getText( 10052 com.android.internal.R.string.factorytest_not_system); 10053 } 10054 } else { 10055 errorMsg = mContext.getResources().getText( 10056 com.android.internal.R.string.factorytest_no_action); 10057 } 10058 if (errorMsg != null) { 10059 mTopAction = null; 10060 mTopData = null; 10061 mTopComponent = null; 10062 Message msg = Message.obtain(); 10063 msg.what = SHOW_FACTORY_ERROR_MSG; 10064 msg.getData().putCharSequence("msg", errorMsg); 10065 mHandler.sendMessage(msg); 10066 } 10067 } 10068 } 10069 10070 retrieveSettings(); 10071 10072 synchronized (this) { 10073 readGrantedUriPermissionsLocked(); 10074 } 10075 10076 if (goingCallback != null) goingCallback.run(); 10077 10078 mSystemServiceManager.startUser(mCurrentUserId); 10079 10080 synchronized (this) { 10081 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10082 try { 10083 List apps = AppGlobals.getPackageManager(). 10084 getPersistentApplications(STOCK_PM_FLAGS); 10085 if (apps != null) { 10086 int N = apps.size(); 10087 int i; 10088 for (i=0; i<N; i++) { 10089 ApplicationInfo info 10090 = (ApplicationInfo)apps.get(i); 10091 if (info != null && 10092 !info.packageName.equals("android")) { 10093 addAppLocked(info, false, null /* ABI override */); 10094 } 10095 } 10096 } 10097 } catch (RemoteException ex) { 10098 // pm is in same process, this will never happen. 10099 } 10100 } 10101 10102 // Start up initial activity. 10103 mBooting = true; 10104 10105 try { 10106 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10107 Message msg = Message.obtain(); 10108 msg.what = SHOW_UID_ERROR_MSG; 10109 mHandler.sendMessage(msg); 10110 } 10111 } catch (RemoteException e) { 10112 } 10113 10114 long ident = Binder.clearCallingIdentity(); 10115 try { 10116 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10117 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10118 | Intent.FLAG_RECEIVER_FOREGROUND); 10119 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10120 broadcastIntentLocked(null, null, intent, 10121 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10122 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10123 intent = new Intent(Intent.ACTION_USER_STARTING); 10124 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10125 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10126 broadcastIntentLocked(null, null, intent, 10127 null, new IIntentReceiver.Stub() { 10128 @Override 10129 public void performReceive(Intent intent, int resultCode, String data, 10130 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10131 throws RemoteException { 10132 } 10133 }, 0, null, null, 10134 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10135 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10136 } catch (Throwable t) { 10137 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10138 } finally { 10139 Binder.restoreCallingIdentity(ident); 10140 } 10141 mStackSupervisor.resumeTopActivitiesLocked(); 10142 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10143 } 10144 } 10145 10146 private boolean makeAppCrashingLocked(ProcessRecord app, 10147 String shortMsg, String longMsg, String stackTrace) { 10148 app.crashing = true; 10149 app.crashingReport = generateProcessError(app, 10150 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10151 startAppProblemLocked(app); 10152 app.stopFreezingAllLocked(); 10153 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10154 } 10155 10156 private void makeAppNotRespondingLocked(ProcessRecord app, 10157 String activity, String shortMsg, String longMsg) { 10158 app.notResponding = true; 10159 app.notRespondingReport = generateProcessError(app, 10160 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10161 activity, shortMsg, longMsg, null); 10162 startAppProblemLocked(app); 10163 app.stopFreezingAllLocked(); 10164 } 10165 10166 /** 10167 * Generate a process error record, suitable for attachment to a ProcessRecord. 10168 * 10169 * @param app The ProcessRecord in which the error occurred. 10170 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10171 * ActivityManager.AppErrorStateInfo 10172 * @param activity The activity associated with the crash, if known. 10173 * @param shortMsg Short message describing the crash. 10174 * @param longMsg Long message describing the crash. 10175 * @param stackTrace Full crash stack trace, may be null. 10176 * 10177 * @return Returns a fully-formed AppErrorStateInfo record. 10178 */ 10179 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10180 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10181 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10182 10183 report.condition = condition; 10184 report.processName = app.processName; 10185 report.pid = app.pid; 10186 report.uid = app.info.uid; 10187 report.tag = activity; 10188 report.shortMsg = shortMsg; 10189 report.longMsg = longMsg; 10190 report.stackTrace = stackTrace; 10191 10192 return report; 10193 } 10194 10195 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10196 synchronized (this) { 10197 app.crashing = false; 10198 app.crashingReport = null; 10199 app.notResponding = false; 10200 app.notRespondingReport = null; 10201 if (app.anrDialog == fromDialog) { 10202 app.anrDialog = null; 10203 } 10204 if (app.waitDialog == fromDialog) { 10205 app.waitDialog = null; 10206 } 10207 if (app.pid > 0 && app.pid != MY_PID) { 10208 handleAppCrashLocked(app, null, null, null); 10209 killUnneededProcessLocked(app, "user request after error"); 10210 } 10211 } 10212 } 10213 10214 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10215 String stackTrace) { 10216 long now = SystemClock.uptimeMillis(); 10217 10218 Long crashTime; 10219 if (!app.isolated) { 10220 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10221 } else { 10222 crashTime = null; 10223 } 10224 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10225 // This process loses! 10226 Slog.w(TAG, "Process " + app.info.processName 10227 + " has crashed too many times: killing!"); 10228 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10229 app.userId, app.info.processName, app.uid); 10230 mStackSupervisor.handleAppCrashLocked(app); 10231 if (!app.persistent) { 10232 // We don't want to start this process again until the user 10233 // explicitly does so... but for persistent process, we really 10234 // need to keep it running. If a persistent process is actually 10235 // repeatedly crashing, then badness for everyone. 10236 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10237 app.info.processName); 10238 if (!app.isolated) { 10239 // XXX We don't have a way to mark isolated processes 10240 // as bad, since they don't have a peristent identity. 10241 mBadProcesses.put(app.info.processName, app.uid, 10242 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10243 mProcessCrashTimes.remove(app.info.processName, app.uid); 10244 } 10245 app.bad = true; 10246 app.removed = true; 10247 // Don't let services in this process be restarted and potentially 10248 // annoy the user repeatedly. Unless it is persistent, since those 10249 // processes run critical code. 10250 removeProcessLocked(app, false, false, "crash"); 10251 mStackSupervisor.resumeTopActivitiesLocked(); 10252 return false; 10253 } 10254 mStackSupervisor.resumeTopActivitiesLocked(); 10255 } else { 10256 mStackSupervisor.finishTopRunningActivityLocked(app); 10257 } 10258 10259 // Bump up the crash count of any services currently running in the proc. 10260 for (int i=app.services.size()-1; i>=0; i--) { 10261 // Any services running in the application need to be placed 10262 // back in the pending list. 10263 ServiceRecord sr = app.services.valueAt(i); 10264 sr.crashCount++; 10265 } 10266 10267 // If the crashing process is what we consider to be the "home process" and it has been 10268 // replaced by a third-party app, clear the package preferred activities from packages 10269 // with a home activity running in the process to prevent a repeatedly crashing app 10270 // from blocking the user to manually clear the list. 10271 final ArrayList<ActivityRecord> activities = app.activities; 10272 if (app == mHomeProcess && activities.size() > 0 10273 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10274 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10275 final ActivityRecord r = activities.get(activityNdx); 10276 if (r.isHomeActivity()) { 10277 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10278 try { 10279 ActivityThread.getPackageManager() 10280 .clearPackagePreferredActivities(r.packageName); 10281 } catch (RemoteException c) { 10282 // pm is in same process, this will never happen. 10283 } 10284 } 10285 } 10286 } 10287 10288 if (!app.isolated) { 10289 // XXX Can't keep track of crash times for isolated processes, 10290 // because they don't have a perisistent identity. 10291 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10292 } 10293 10294 return true; 10295 } 10296 10297 void startAppProblemLocked(ProcessRecord app) { 10298 if (app.userId == mCurrentUserId) { 10299 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10300 mContext, app.info.packageName, app.info.flags); 10301 } else { 10302 // If this app is not running under the current user, then we 10303 // can't give it a report button because that would require 10304 // launching the report UI under a different user. 10305 app.errorReportReceiver = null; 10306 } 10307 skipCurrentReceiverLocked(app); 10308 } 10309 10310 void skipCurrentReceiverLocked(ProcessRecord app) { 10311 for (BroadcastQueue queue : mBroadcastQueues) { 10312 queue.skipCurrentReceiverLocked(app); 10313 } 10314 } 10315 10316 /** 10317 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10318 * The application process will exit immediately after this call returns. 10319 * @param app object of the crashing app, null for the system server 10320 * @param crashInfo describing the exception 10321 */ 10322 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10323 ProcessRecord r = findAppProcess(app, "Crash"); 10324 final String processName = app == null ? "system_server" 10325 : (r == null ? "unknown" : r.processName); 10326 10327 handleApplicationCrashInner("crash", r, processName, crashInfo); 10328 } 10329 10330 /* Native crash reporting uses this inner version because it needs to be somewhat 10331 * decoupled from the AM-managed cleanup lifecycle 10332 */ 10333 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10334 ApplicationErrorReport.CrashInfo crashInfo) { 10335 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10336 UserHandle.getUserId(Binder.getCallingUid()), processName, 10337 r == null ? -1 : r.info.flags, 10338 crashInfo.exceptionClassName, 10339 crashInfo.exceptionMessage, 10340 crashInfo.throwFileName, 10341 crashInfo.throwLineNumber); 10342 10343 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10344 10345 crashApplication(r, crashInfo); 10346 } 10347 10348 public void handleApplicationStrictModeViolation( 10349 IBinder app, 10350 int violationMask, 10351 StrictMode.ViolationInfo info) { 10352 ProcessRecord r = findAppProcess(app, "StrictMode"); 10353 if (r == null) { 10354 return; 10355 } 10356 10357 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10358 Integer stackFingerprint = info.hashCode(); 10359 boolean logIt = true; 10360 synchronized (mAlreadyLoggedViolatedStacks) { 10361 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10362 logIt = false; 10363 // TODO: sub-sample into EventLog for these, with 10364 // the info.durationMillis? Then we'd get 10365 // the relative pain numbers, without logging all 10366 // the stack traces repeatedly. We'd want to do 10367 // likewise in the client code, which also does 10368 // dup suppression, before the Binder call. 10369 } else { 10370 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10371 mAlreadyLoggedViolatedStacks.clear(); 10372 } 10373 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10374 } 10375 } 10376 if (logIt) { 10377 logStrictModeViolationToDropBox(r, info); 10378 } 10379 } 10380 10381 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10382 AppErrorResult result = new AppErrorResult(); 10383 synchronized (this) { 10384 final long origId = Binder.clearCallingIdentity(); 10385 10386 Message msg = Message.obtain(); 10387 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10388 HashMap<String, Object> data = new HashMap<String, Object>(); 10389 data.put("result", result); 10390 data.put("app", r); 10391 data.put("violationMask", violationMask); 10392 data.put("info", info); 10393 msg.obj = data; 10394 mHandler.sendMessage(msg); 10395 10396 Binder.restoreCallingIdentity(origId); 10397 } 10398 int res = result.get(); 10399 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10400 } 10401 } 10402 10403 // Depending on the policy in effect, there could be a bunch of 10404 // these in quick succession so we try to batch these together to 10405 // minimize disk writes, number of dropbox entries, and maximize 10406 // compression, by having more fewer, larger records. 10407 private void logStrictModeViolationToDropBox( 10408 ProcessRecord process, 10409 StrictMode.ViolationInfo info) { 10410 if (info == null) { 10411 return; 10412 } 10413 final boolean isSystemApp = process == null || 10414 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10415 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10416 final String processName = process == null ? "unknown" : process.processName; 10417 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10418 final DropBoxManager dbox = (DropBoxManager) 10419 mContext.getSystemService(Context.DROPBOX_SERVICE); 10420 10421 // Exit early if the dropbox isn't configured to accept this report type. 10422 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10423 10424 boolean bufferWasEmpty; 10425 boolean needsFlush; 10426 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10427 synchronized (sb) { 10428 bufferWasEmpty = sb.length() == 0; 10429 appendDropBoxProcessHeaders(process, processName, sb); 10430 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10431 sb.append("System-App: ").append(isSystemApp).append("\n"); 10432 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10433 if (info.violationNumThisLoop != 0) { 10434 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10435 } 10436 if (info.numAnimationsRunning != 0) { 10437 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10438 } 10439 if (info.broadcastIntentAction != null) { 10440 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10441 } 10442 if (info.durationMillis != -1) { 10443 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10444 } 10445 if (info.numInstances != -1) { 10446 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10447 } 10448 if (info.tags != null) { 10449 for (String tag : info.tags) { 10450 sb.append("Span-Tag: ").append(tag).append("\n"); 10451 } 10452 } 10453 sb.append("\n"); 10454 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10455 sb.append(info.crashInfo.stackTrace); 10456 } 10457 sb.append("\n"); 10458 10459 // Only buffer up to ~64k. Various logging bits truncate 10460 // things at 128k. 10461 needsFlush = (sb.length() > 64 * 1024); 10462 } 10463 10464 // Flush immediately if the buffer's grown too large, or this 10465 // is a non-system app. Non-system apps are isolated with a 10466 // different tag & policy and not batched. 10467 // 10468 // Batching is useful during internal testing with 10469 // StrictMode settings turned up high. Without batching, 10470 // thousands of separate files could be created on boot. 10471 if (!isSystemApp || needsFlush) { 10472 new Thread("Error dump: " + dropboxTag) { 10473 @Override 10474 public void run() { 10475 String report; 10476 synchronized (sb) { 10477 report = sb.toString(); 10478 sb.delete(0, sb.length()); 10479 sb.trimToSize(); 10480 } 10481 if (report.length() != 0) { 10482 dbox.addText(dropboxTag, report); 10483 } 10484 } 10485 }.start(); 10486 return; 10487 } 10488 10489 // System app batching: 10490 if (!bufferWasEmpty) { 10491 // An existing dropbox-writing thread is outstanding, so 10492 // we don't need to start it up. The existing thread will 10493 // catch the buffer appends we just did. 10494 return; 10495 } 10496 10497 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10498 // (After this point, we shouldn't access AMS internal data structures.) 10499 new Thread("Error dump: " + dropboxTag) { 10500 @Override 10501 public void run() { 10502 // 5 second sleep to let stacks arrive and be batched together 10503 try { 10504 Thread.sleep(5000); // 5 seconds 10505 } catch (InterruptedException e) {} 10506 10507 String errorReport; 10508 synchronized (mStrictModeBuffer) { 10509 errorReport = mStrictModeBuffer.toString(); 10510 if (errorReport.length() == 0) { 10511 return; 10512 } 10513 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10514 mStrictModeBuffer.trimToSize(); 10515 } 10516 dbox.addText(dropboxTag, errorReport); 10517 } 10518 }.start(); 10519 } 10520 10521 /** 10522 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10523 * @param app object of the crashing app, null for the system server 10524 * @param tag reported by the caller 10525 * @param crashInfo describing the context of the error 10526 * @return true if the process should exit immediately (WTF is fatal) 10527 */ 10528 public boolean handleApplicationWtf(IBinder app, String tag, 10529 ApplicationErrorReport.CrashInfo crashInfo) { 10530 ProcessRecord r = findAppProcess(app, "WTF"); 10531 final String processName = app == null ? "system_server" 10532 : (r == null ? "unknown" : r.processName); 10533 10534 EventLog.writeEvent(EventLogTags.AM_WTF, 10535 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10536 processName, 10537 r == null ? -1 : r.info.flags, 10538 tag, crashInfo.exceptionMessage); 10539 10540 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10541 10542 if (r != null && r.pid != Process.myPid() && 10543 Settings.Global.getInt(mContext.getContentResolver(), 10544 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10545 crashApplication(r, crashInfo); 10546 return true; 10547 } else { 10548 return false; 10549 } 10550 } 10551 10552 /** 10553 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10554 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10555 */ 10556 private ProcessRecord findAppProcess(IBinder app, String reason) { 10557 if (app == null) { 10558 return null; 10559 } 10560 10561 synchronized (this) { 10562 final int NP = mProcessNames.getMap().size(); 10563 for (int ip=0; ip<NP; ip++) { 10564 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10565 final int NA = apps.size(); 10566 for (int ia=0; ia<NA; ia++) { 10567 ProcessRecord p = apps.valueAt(ia); 10568 if (p.thread != null && p.thread.asBinder() == app) { 10569 return p; 10570 } 10571 } 10572 } 10573 10574 Slog.w(TAG, "Can't find mystery application for " + reason 10575 + " from pid=" + Binder.getCallingPid() 10576 + " uid=" + Binder.getCallingUid() + ": " + app); 10577 return null; 10578 } 10579 } 10580 10581 /** 10582 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10583 * to append various headers to the dropbox log text. 10584 */ 10585 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10586 StringBuilder sb) { 10587 // Watchdog thread ends up invoking this function (with 10588 // a null ProcessRecord) to add the stack file to dropbox. 10589 // Do not acquire a lock on this (am) in such cases, as it 10590 // could cause a potential deadlock, if and when watchdog 10591 // is invoked due to unavailability of lock on am and it 10592 // would prevent watchdog from killing system_server. 10593 if (process == null) { 10594 sb.append("Process: ").append(processName).append("\n"); 10595 return; 10596 } 10597 // Note: ProcessRecord 'process' is guarded by the service 10598 // instance. (notably process.pkgList, which could otherwise change 10599 // concurrently during execution of this method) 10600 synchronized (this) { 10601 sb.append("Process: ").append(processName).append("\n"); 10602 int flags = process.info.flags; 10603 IPackageManager pm = AppGlobals.getPackageManager(); 10604 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10605 for (int ip=0; ip<process.pkgList.size(); ip++) { 10606 String pkg = process.pkgList.keyAt(ip); 10607 sb.append("Package: ").append(pkg); 10608 try { 10609 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10610 if (pi != null) { 10611 sb.append(" v").append(pi.versionCode); 10612 if (pi.versionName != null) { 10613 sb.append(" (").append(pi.versionName).append(")"); 10614 } 10615 } 10616 } catch (RemoteException e) { 10617 Slog.e(TAG, "Error getting package info: " + pkg, e); 10618 } 10619 sb.append("\n"); 10620 } 10621 } 10622 } 10623 10624 private static String processClass(ProcessRecord process) { 10625 if (process == null || process.pid == MY_PID) { 10626 return "system_server"; 10627 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10628 return "system_app"; 10629 } else { 10630 return "data_app"; 10631 } 10632 } 10633 10634 /** 10635 * Write a description of an error (crash, WTF, ANR) to the drop box. 10636 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10637 * @param process which caused the error, null means the system server 10638 * @param activity which triggered the error, null if unknown 10639 * @param parent activity related to the error, null if unknown 10640 * @param subject line related to the error, null if absent 10641 * @param report in long form describing the error, null if absent 10642 * @param logFile to include in the report, null if none 10643 * @param crashInfo giving an application stack trace, null if absent 10644 */ 10645 public void addErrorToDropBox(String eventType, 10646 ProcessRecord process, String processName, ActivityRecord activity, 10647 ActivityRecord parent, String subject, 10648 final String report, final File logFile, 10649 final ApplicationErrorReport.CrashInfo crashInfo) { 10650 // NOTE -- this must never acquire the ActivityManagerService lock, 10651 // otherwise the watchdog may be prevented from resetting the system. 10652 10653 final String dropboxTag = processClass(process) + "_" + eventType; 10654 final DropBoxManager dbox = (DropBoxManager) 10655 mContext.getSystemService(Context.DROPBOX_SERVICE); 10656 10657 // Exit early if the dropbox isn't configured to accept this report type. 10658 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10659 10660 final StringBuilder sb = new StringBuilder(1024); 10661 appendDropBoxProcessHeaders(process, processName, sb); 10662 if (activity != null) { 10663 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10664 } 10665 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10666 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10667 } 10668 if (parent != null && parent != activity) { 10669 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10670 } 10671 if (subject != null) { 10672 sb.append("Subject: ").append(subject).append("\n"); 10673 } 10674 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10675 if (Debug.isDebuggerConnected()) { 10676 sb.append("Debugger: Connected\n"); 10677 } 10678 sb.append("\n"); 10679 10680 // Do the rest in a worker thread to avoid blocking the caller on I/O 10681 // (After this point, we shouldn't access AMS internal data structures.) 10682 Thread worker = new Thread("Error dump: " + dropboxTag) { 10683 @Override 10684 public void run() { 10685 if (report != null) { 10686 sb.append(report); 10687 } 10688 if (logFile != null) { 10689 try { 10690 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10691 "\n\n[[TRUNCATED]]")); 10692 } catch (IOException e) { 10693 Slog.e(TAG, "Error reading " + logFile, e); 10694 } 10695 } 10696 if (crashInfo != null && crashInfo.stackTrace != null) { 10697 sb.append(crashInfo.stackTrace); 10698 } 10699 10700 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10701 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10702 if (lines > 0) { 10703 sb.append("\n"); 10704 10705 // Merge several logcat streams, and take the last N lines 10706 InputStreamReader input = null; 10707 try { 10708 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10709 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10710 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10711 10712 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10713 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10714 input = new InputStreamReader(logcat.getInputStream()); 10715 10716 int num; 10717 char[] buf = new char[8192]; 10718 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10719 } catch (IOException e) { 10720 Slog.e(TAG, "Error running logcat", e); 10721 } finally { 10722 if (input != null) try { input.close(); } catch (IOException e) {} 10723 } 10724 } 10725 10726 dbox.addText(dropboxTag, sb.toString()); 10727 } 10728 }; 10729 10730 if (process == null) { 10731 // If process is null, we are being called from some internal code 10732 // and may be about to die -- run this synchronously. 10733 worker.run(); 10734 } else { 10735 worker.start(); 10736 } 10737 } 10738 10739 /** 10740 * Bring up the "unexpected error" dialog box for a crashing app. 10741 * Deal with edge cases (intercepts from instrumented applications, 10742 * ActivityController, error intent receivers, that sort of thing). 10743 * @param r the application crashing 10744 * @param crashInfo describing the failure 10745 */ 10746 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10747 long timeMillis = System.currentTimeMillis(); 10748 String shortMsg = crashInfo.exceptionClassName; 10749 String longMsg = crashInfo.exceptionMessage; 10750 String stackTrace = crashInfo.stackTrace; 10751 if (shortMsg != null && longMsg != null) { 10752 longMsg = shortMsg + ": " + longMsg; 10753 } else if (shortMsg != null) { 10754 longMsg = shortMsg; 10755 } 10756 10757 AppErrorResult result = new AppErrorResult(); 10758 synchronized (this) { 10759 if (mController != null) { 10760 try { 10761 String name = r != null ? r.processName : null; 10762 int pid = r != null ? r.pid : Binder.getCallingPid(); 10763 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10764 if (!mController.appCrashed(name, pid, 10765 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10766 Slog.w(TAG, "Force-killing crashed app " + name 10767 + " at watcher's request"); 10768 Process.killProcess(pid); 10769 if (r != null) { 10770 Process.killProcessGroup(uid, pid); 10771 } 10772 return; 10773 } 10774 } catch (RemoteException e) { 10775 mController = null; 10776 Watchdog.getInstance().setActivityController(null); 10777 } 10778 } 10779 10780 final long origId = Binder.clearCallingIdentity(); 10781 10782 // If this process is running instrumentation, finish it. 10783 if (r != null && r.instrumentationClass != null) { 10784 Slog.w(TAG, "Error in app " + r.processName 10785 + " running instrumentation " + r.instrumentationClass + ":"); 10786 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10787 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10788 Bundle info = new Bundle(); 10789 info.putString("shortMsg", shortMsg); 10790 info.putString("longMsg", longMsg); 10791 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10792 Binder.restoreCallingIdentity(origId); 10793 return; 10794 } 10795 10796 // If we can't identify the process or it's already exceeded its crash quota, 10797 // quit right away without showing a crash dialog. 10798 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10799 Binder.restoreCallingIdentity(origId); 10800 return; 10801 } 10802 10803 Message msg = Message.obtain(); 10804 msg.what = SHOW_ERROR_MSG; 10805 HashMap data = new HashMap(); 10806 data.put("result", result); 10807 data.put("app", r); 10808 msg.obj = data; 10809 mHandler.sendMessage(msg); 10810 10811 Binder.restoreCallingIdentity(origId); 10812 } 10813 10814 int res = result.get(); 10815 10816 Intent appErrorIntent = null; 10817 synchronized (this) { 10818 if (r != null && !r.isolated) { 10819 // XXX Can't keep track of crash time for isolated processes, 10820 // since they don't have a persistent identity. 10821 mProcessCrashTimes.put(r.info.processName, r.uid, 10822 SystemClock.uptimeMillis()); 10823 } 10824 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10825 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10826 } 10827 } 10828 10829 if (appErrorIntent != null) { 10830 try { 10831 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10832 } catch (ActivityNotFoundException e) { 10833 Slog.w(TAG, "bug report receiver dissappeared", e); 10834 } 10835 } 10836 } 10837 10838 Intent createAppErrorIntentLocked(ProcessRecord r, 10839 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10840 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10841 if (report == null) { 10842 return null; 10843 } 10844 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10845 result.setComponent(r.errorReportReceiver); 10846 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10847 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10848 return result; 10849 } 10850 10851 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10852 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10853 if (r.errorReportReceiver == null) { 10854 return null; 10855 } 10856 10857 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10858 return null; 10859 } 10860 10861 ApplicationErrorReport report = new ApplicationErrorReport(); 10862 report.packageName = r.info.packageName; 10863 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10864 report.processName = r.processName; 10865 report.time = timeMillis; 10866 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10867 10868 if (r.crashing || r.forceCrashReport) { 10869 report.type = ApplicationErrorReport.TYPE_CRASH; 10870 report.crashInfo = crashInfo; 10871 } else if (r.notResponding) { 10872 report.type = ApplicationErrorReport.TYPE_ANR; 10873 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10874 10875 report.anrInfo.activity = r.notRespondingReport.tag; 10876 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10877 report.anrInfo.info = r.notRespondingReport.longMsg; 10878 } 10879 10880 return report; 10881 } 10882 10883 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10884 enforceNotIsolatedCaller("getProcessesInErrorState"); 10885 // assume our apps are happy - lazy create the list 10886 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10887 10888 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10889 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10890 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10891 10892 synchronized (this) { 10893 10894 // iterate across all processes 10895 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10896 ProcessRecord app = mLruProcesses.get(i); 10897 if (!allUsers && app.userId != userId) { 10898 continue; 10899 } 10900 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10901 // This one's in trouble, so we'll generate a report for it 10902 // crashes are higher priority (in case there's a crash *and* an anr) 10903 ActivityManager.ProcessErrorStateInfo report = null; 10904 if (app.crashing) { 10905 report = app.crashingReport; 10906 } else if (app.notResponding) { 10907 report = app.notRespondingReport; 10908 } 10909 10910 if (report != null) { 10911 if (errList == null) { 10912 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10913 } 10914 errList.add(report); 10915 } else { 10916 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10917 " crashing = " + app.crashing + 10918 " notResponding = " + app.notResponding); 10919 } 10920 } 10921 } 10922 } 10923 10924 return errList; 10925 } 10926 10927 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10928 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10929 if (currApp != null) { 10930 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10931 } 10932 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10933 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10934 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10935 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10936 if (currApp != null) { 10937 currApp.lru = 0; 10938 } 10939 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10940 } else if (adj >= ProcessList.SERVICE_ADJ) { 10941 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10942 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10943 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10944 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10945 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10946 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10947 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10948 } else { 10949 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10950 } 10951 } 10952 10953 private void fillInProcMemInfo(ProcessRecord app, 10954 ActivityManager.RunningAppProcessInfo outInfo) { 10955 outInfo.pid = app.pid; 10956 outInfo.uid = app.info.uid; 10957 if (mHeavyWeightProcess == app) { 10958 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10959 } 10960 if (app.persistent) { 10961 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10962 } 10963 if (app.activities.size() > 0) { 10964 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10965 } 10966 outInfo.lastTrimLevel = app.trimMemoryLevel; 10967 int adj = app.curAdj; 10968 outInfo.importance = oomAdjToImportance(adj, outInfo); 10969 outInfo.importanceReasonCode = app.adjTypeCode; 10970 outInfo.processState = app.curProcState; 10971 } 10972 10973 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10974 enforceNotIsolatedCaller("getRunningAppProcesses"); 10975 // Lazy instantiation of list 10976 List<ActivityManager.RunningAppProcessInfo> runList = null; 10977 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10978 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10979 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10980 synchronized (this) { 10981 // Iterate across all processes 10982 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10983 ProcessRecord app = mLruProcesses.get(i); 10984 if (!allUsers && app.userId != userId) { 10985 continue; 10986 } 10987 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10988 // Generate process state info for running application 10989 ActivityManager.RunningAppProcessInfo currApp = 10990 new ActivityManager.RunningAppProcessInfo(app.processName, 10991 app.pid, app.getPackageList()); 10992 fillInProcMemInfo(app, currApp); 10993 if (app.adjSource instanceof ProcessRecord) { 10994 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10995 currApp.importanceReasonImportance = oomAdjToImportance( 10996 app.adjSourceOom, null); 10997 } else if (app.adjSource instanceof ActivityRecord) { 10998 ActivityRecord r = (ActivityRecord)app.adjSource; 10999 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11000 } 11001 if (app.adjTarget instanceof ComponentName) { 11002 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11003 } 11004 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11005 // + " lru=" + currApp.lru); 11006 if (runList == null) { 11007 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11008 } 11009 runList.add(currApp); 11010 } 11011 } 11012 } 11013 return runList; 11014 } 11015 11016 public List<ApplicationInfo> getRunningExternalApplications() { 11017 enforceNotIsolatedCaller("getRunningExternalApplications"); 11018 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11019 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11020 if (runningApps != null && runningApps.size() > 0) { 11021 Set<String> extList = new HashSet<String>(); 11022 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11023 if (app.pkgList != null) { 11024 for (String pkg : app.pkgList) { 11025 extList.add(pkg); 11026 } 11027 } 11028 } 11029 IPackageManager pm = AppGlobals.getPackageManager(); 11030 for (String pkg : extList) { 11031 try { 11032 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11033 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11034 retList.add(info); 11035 } 11036 } catch (RemoteException e) { 11037 } 11038 } 11039 } 11040 return retList; 11041 } 11042 11043 @Override 11044 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11045 enforceNotIsolatedCaller("getMyMemoryState"); 11046 synchronized (this) { 11047 ProcessRecord proc; 11048 synchronized (mPidsSelfLocked) { 11049 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11050 } 11051 fillInProcMemInfo(proc, outInfo); 11052 } 11053 } 11054 11055 @Override 11056 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11057 if (checkCallingPermission(android.Manifest.permission.DUMP) 11058 != PackageManager.PERMISSION_GRANTED) { 11059 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11060 + Binder.getCallingPid() 11061 + ", uid=" + Binder.getCallingUid() 11062 + " without permission " 11063 + android.Manifest.permission.DUMP); 11064 return; 11065 } 11066 11067 boolean dumpAll = false; 11068 boolean dumpClient = false; 11069 String dumpPackage = null; 11070 11071 int opti = 0; 11072 while (opti < args.length) { 11073 String opt = args[opti]; 11074 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11075 break; 11076 } 11077 opti++; 11078 if ("-a".equals(opt)) { 11079 dumpAll = true; 11080 } else if ("-c".equals(opt)) { 11081 dumpClient = true; 11082 } else if ("-h".equals(opt)) { 11083 pw.println("Activity manager dump options:"); 11084 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11085 pw.println(" cmd may be one of:"); 11086 pw.println(" a[ctivities]: activity stack state"); 11087 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11088 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11089 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11090 pw.println(" o[om]: out of memory management"); 11091 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11092 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11093 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11094 pw.println(" service [COMP_SPEC]: service client-side state"); 11095 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11096 pw.println(" all: dump all activities"); 11097 pw.println(" top: dump the top activity"); 11098 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11099 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11100 pw.println(" a partial substring in a component name, a"); 11101 pw.println(" hex object identifier."); 11102 pw.println(" -a: include all available server state."); 11103 pw.println(" -c: include client state."); 11104 return; 11105 } else { 11106 pw.println("Unknown argument: " + opt + "; use -h for help"); 11107 } 11108 } 11109 11110 long origId = Binder.clearCallingIdentity(); 11111 boolean more = false; 11112 // Is the caller requesting to dump a particular piece of data? 11113 if (opti < args.length) { 11114 String cmd = args[opti]; 11115 opti++; 11116 if ("activities".equals(cmd) || "a".equals(cmd)) { 11117 synchronized (this) { 11118 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11119 } 11120 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11121 String[] newArgs; 11122 String name; 11123 if (opti >= args.length) { 11124 name = null; 11125 newArgs = EMPTY_STRING_ARRAY; 11126 } else { 11127 name = args[opti]; 11128 opti++; 11129 newArgs = new String[args.length - opti]; 11130 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11131 args.length - opti); 11132 } 11133 synchronized (this) { 11134 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11135 } 11136 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11137 String[] newArgs; 11138 String name; 11139 if (opti >= args.length) { 11140 name = null; 11141 newArgs = EMPTY_STRING_ARRAY; 11142 } else { 11143 name = args[opti]; 11144 opti++; 11145 newArgs = new String[args.length - opti]; 11146 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11147 args.length - opti); 11148 } 11149 synchronized (this) { 11150 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11151 } 11152 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11153 String[] newArgs; 11154 String name; 11155 if (opti >= args.length) { 11156 name = null; 11157 newArgs = EMPTY_STRING_ARRAY; 11158 } else { 11159 name = args[opti]; 11160 opti++; 11161 newArgs = new String[args.length - opti]; 11162 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11163 args.length - opti); 11164 } 11165 synchronized (this) { 11166 dumpProcessesLocked(fd, pw, args, opti, true, name); 11167 } 11168 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11169 synchronized (this) { 11170 dumpOomLocked(fd, pw, args, opti, true); 11171 } 11172 } else if ("provider".equals(cmd)) { 11173 String[] newArgs; 11174 String name; 11175 if (opti >= args.length) { 11176 name = null; 11177 newArgs = EMPTY_STRING_ARRAY; 11178 } else { 11179 name = args[opti]; 11180 opti++; 11181 newArgs = new String[args.length - opti]; 11182 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11183 } 11184 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11185 pw.println("No providers match: " + name); 11186 pw.println("Use -h for help."); 11187 } 11188 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11189 synchronized (this) { 11190 dumpProvidersLocked(fd, pw, args, opti, true, null); 11191 } 11192 } else if ("service".equals(cmd)) { 11193 String[] newArgs; 11194 String name; 11195 if (opti >= args.length) { 11196 name = null; 11197 newArgs = EMPTY_STRING_ARRAY; 11198 } else { 11199 name = args[opti]; 11200 opti++; 11201 newArgs = new String[args.length - opti]; 11202 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11203 args.length - opti); 11204 } 11205 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11206 pw.println("No services match: " + name); 11207 pw.println("Use -h for help."); 11208 } 11209 } else if ("package".equals(cmd)) { 11210 String[] newArgs; 11211 if (opti >= args.length) { 11212 pw.println("package: no package name specified"); 11213 pw.println("Use -h for help."); 11214 } else { 11215 dumpPackage = args[opti]; 11216 opti++; 11217 newArgs = new String[args.length - opti]; 11218 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11219 args.length - opti); 11220 args = newArgs; 11221 opti = 0; 11222 more = true; 11223 } 11224 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11225 synchronized (this) { 11226 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11227 } 11228 } else { 11229 // Dumping a single activity? 11230 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11231 pw.println("Bad activity command, or no activities match: " + cmd); 11232 pw.println("Use -h for help."); 11233 } 11234 } 11235 if (!more) { 11236 Binder.restoreCallingIdentity(origId); 11237 return; 11238 } 11239 } 11240 11241 // No piece of data specified, dump everything. 11242 synchronized (this) { 11243 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11244 pw.println(); 11245 if (dumpAll) { 11246 pw.println("-------------------------------------------------------------------------------"); 11247 } 11248 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11249 pw.println(); 11250 if (dumpAll) { 11251 pw.println("-------------------------------------------------------------------------------"); 11252 } 11253 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11254 pw.println(); 11255 if (dumpAll) { 11256 pw.println("-------------------------------------------------------------------------------"); 11257 } 11258 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11259 pw.println(); 11260 if (dumpAll) { 11261 pw.println("-------------------------------------------------------------------------------"); 11262 } 11263 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11264 pw.println(); 11265 if (dumpAll) { 11266 pw.println("-------------------------------------------------------------------------------"); 11267 } 11268 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11269 } 11270 Binder.restoreCallingIdentity(origId); 11271 } 11272 11273 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11274 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11275 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11276 11277 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11278 dumpPackage); 11279 boolean needSep = printedAnything; 11280 11281 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11282 dumpPackage, needSep, " mFocusedActivity: "); 11283 if (printed) { 11284 printedAnything = true; 11285 needSep = false; 11286 } 11287 11288 if (dumpPackage == null) { 11289 if (needSep) { 11290 pw.println(); 11291 } 11292 needSep = true; 11293 printedAnything = true; 11294 mStackSupervisor.dump(pw, " "); 11295 } 11296 11297 if (mRecentTasks.size() > 0) { 11298 boolean printedHeader = false; 11299 11300 final int N = mRecentTasks.size(); 11301 for (int i=0; i<N; i++) { 11302 TaskRecord tr = mRecentTasks.get(i); 11303 if (dumpPackage != null) { 11304 if (tr.realActivity == null || 11305 !dumpPackage.equals(tr.realActivity)) { 11306 continue; 11307 } 11308 } 11309 if (!printedHeader) { 11310 if (needSep) { 11311 pw.println(); 11312 } 11313 pw.println(" Recent tasks:"); 11314 printedHeader = true; 11315 printedAnything = true; 11316 } 11317 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11318 pw.println(tr); 11319 if (dumpAll) { 11320 mRecentTasks.get(i).dump(pw, " "); 11321 } 11322 } 11323 } 11324 11325 if (!printedAnything) { 11326 pw.println(" (nothing)"); 11327 } 11328 } 11329 11330 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11331 int opti, boolean dumpAll, String dumpPackage) { 11332 boolean needSep = false; 11333 boolean printedAnything = false; 11334 int numPers = 0; 11335 11336 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11337 11338 if (dumpAll) { 11339 final int NP = mProcessNames.getMap().size(); 11340 for (int ip=0; ip<NP; ip++) { 11341 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11342 final int NA = procs.size(); 11343 for (int ia=0; ia<NA; ia++) { 11344 ProcessRecord r = procs.valueAt(ia); 11345 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11346 continue; 11347 } 11348 if (!needSep) { 11349 pw.println(" All known processes:"); 11350 needSep = true; 11351 printedAnything = true; 11352 } 11353 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11354 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11355 pw.print(" "); pw.println(r); 11356 r.dump(pw, " "); 11357 if (r.persistent) { 11358 numPers++; 11359 } 11360 } 11361 } 11362 } 11363 11364 if (mIsolatedProcesses.size() > 0) { 11365 boolean printed = false; 11366 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11367 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11368 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11369 continue; 11370 } 11371 if (!printed) { 11372 if (needSep) { 11373 pw.println(); 11374 } 11375 pw.println(" Isolated process list (sorted by uid):"); 11376 printedAnything = true; 11377 printed = true; 11378 needSep = true; 11379 } 11380 pw.println(String.format("%sIsolated #%2d: %s", 11381 " ", i, r.toString())); 11382 } 11383 } 11384 11385 if (mLruProcesses.size() > 0) { 11386 if (needSep) { 11387 pw.println(); 11388 } 11389 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11390 pw.print(" total, non-act at "); 11391 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11392 pw.print(", non-svc at "); 11393 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11394 pw.println("):"); 11395 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11396 needSep = true; 11397 printedAnything = true; 11398 } 11399 11400 if (dumpAll || dumpPackage != null) { 11401 synchronized (mPidsSelfLocked) { 11402 boolean printed = false; 11403 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11404 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11405 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11406 continue; 11407 } 11408 if (!printed) { 11409 if (needSep) pw.println(); 11410 needSep = true; 11411 pw.println(" PID mappings:"); 11412 printed = true; 11413 printedAnything = true; 11414 } 11415 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11416 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11417 } 11418 } 11419 } 11420 11421 if (mForegroundProcesses.size() > 0) { 11422 synchronized (mPidsSelfLocked) { 11423 boolean printed = false; 11424 for (int i=0; i<mForegroundProcesses.size(); i++) { 11425 ProcessRecord r = mPidsSelfLocked.get( 11426 mForegroundProcesses.valueAt(i).pid); 11427 if (dumpPackage != null && (r == null 11428 || !r.pkgList.containsKey(dumpPackage))) { 11429 continue; 11430 } 11431 if (!printed) { 11432 if (needSep) pw.println(); 11433 needSep = true; 11434 pw.println(" Foreground Processes:"); 11435 printed = true; 11436 printedAnything = true; 11437 } 11438 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11439 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11440 } 11441 } 11442 } 11443 11444 if (mPersistentStartingProcesses.size() > 0) { 11445 if (needSep) pw.println(); 11446 needSep = true; 11447 printedAnything = true; 11448 pw.println(" Persisent processes that are starting:"); 11449 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11450 "Starting Norm", "Restarting PERS", dumpPackage); 11451 } 11452 11453 if (mRemovedProcesses.size() > 0) { 11454 if (needSep) pw.println(); 11455 needSep = true; 11456 printedAnything = true; 11457 pw.println(" Processes that are being removed:"); 11458 dumpProcessList(pw, this, mRemovedProcesses, " ", 11459 "Removed Norm", "Removed PERS", dumpPackage); 11460 } 11461 11462 if (mProcessesOnHold.size() > 0) { 11463 if (needSep) pw.println(); 11464 needSep = true; 11465 printedAnything = true; 11466 pw.println(" Processes that are on old until the system is ready:"); 11467 dumpProcessList(pw, this, mProcessesOnHold, " ", 11468 "OnHold Norm", "OnHold PERS", dumpPackage); 11469 } 11470 11471 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11472 11473 if (mProcessCrashTimes.getMap().size() > 0) { 11474 boolean printed = false; 11475 long now = SystemClock.uptimeMillis(); 11476 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11477 final int NP = pmap.size(); 11478 for (int ip=0; ip<NP; ip++) { 11479 String pname = pmap.keyAt(ip); 11480 SparseArray<Long> uids = pmap.valueAt(ip); 11481 final int N = uids.size(); 11482 for (int i=0; i<N; i++) { 11483 int puid = uids.keyAt(i); 11484 ProcessRecord r = mProcessNames.get(pname, puid); 11485 if (dumpPackage != null && (r == null 11486 || !r.pkgList.containsKey(dumpPackage))) { 11487 continue; 11488 } 11489 if (!printed) { 11490 if (needSep) pw.println(); 11491 needSep = true; 11492 pw.println(" Time since processes crashed:"); 11493 printed = true; 11494 printedAnything = true; 11495 } 11496 pw.print(" Process "); pw.print(pname); 11497 pw.print(" uid "); pw.print(puid); 11498 pw.print(": last crashed "); 11499 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11500 pw.println(" ago"); 11501 } 11502 } 11503 } 11504 11505 if (mBadProcesses.getMap().size() > 0) { 11506 boolean printed = false; 11507 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11508 final int NP = pmap.size(); 11509 for (int ip=0; ip<NP; ip++) { 11510 String pname = pmap.keyAt(ip); 11511 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11512 final int N = uids.size(); 11513 for (int i=0; i<N; i++) { 11514 int puid = uids.keyAt(i); 11515 ProcessRecord r = mProcessNames.get(pname, puid); 11516 if (dumpPackage != null && (r == null 11517 || !r.pkgList.containsKey(dumpPackage))) { 11518 continue; 11519 } 11520 if (!printed) { 11521 if (needSep) pw.println(); 11522 needSep = true; 11523 pw.println(" Bad processes:"); 11524 printedAnything = true; 11525 } 11526 BadProcessInfo info = uids.valueAt(i); 11527 pw.print(" Bad process "); pw.print(pname); 11528 pw.print(" uid "); pw.print(puid); 11529 pw.print(": crashed at time "); pw.println(info.time); 11530 if (info.shortMsg != null) { 11531 pw.print(" Short msg: "); pw.println(info.shortMsg); 11532 } 11533 if (info.longMsg != null) { 11534 pw.print(" Long msg: "); pw.println(info.longMsg); 11535 } 11536 if (info.stack != null) { 11537 pw.println(" Stack:"); 11538 int lastPos = 0; 11539 for (int pos=0; pos<info.stack.length(); pos++) { 11540 if (info.stack.charAt(pos) == '\n') { 11541 pw.print(" "); 11542 pw.write(info.stack, lastPos, pos-lastPos); 11543 pw.println(); 11544 lastPos = pos+1; 11545 } 11546 } 11547 if (lastPos < info.stack.length()) { 11548 pw.print(" "); 11549 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11550 pw.println(); 11551 } 11552 } 11553 } 11554 } 11555 } 11556 11557 if (dumpPackage == null) { 11558 pw.println(); 11559 needSep = false; 11560 pw.println(" mStartedUsers:"); 11561 for (int i=0; i<mStartedUsers.size(); i++) { 11562 UserStartedState uss = mStartedUsers.valueAt(i); 11563 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11564 pw.print(": "); uss.dump("", pw); 11565 } 11566 pw.print(" mStartedUserArray: ["); 11567 for (int i=0; i<mStartedUserArray.length; i++) { 11568 if (i > 0) pw.print(", "); 11569 pw.print(mStartedUserArray[i]); 11570 } 11571 pw.println("]"); 11572 pw.print(" mUserLru: ["); 11573 for (int i=0; i<mUserLru.size(); i++) { 11574 if (i > 0) pw.print(", "); 11575 pw.print(mUserLru.get(i)); 11576 } 11577 pw.println("]"); 11578 if (dumpAll) { 11579 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11580 } 11581 } 11582 if (mHomeProcess != null && (dumpPackage == null 11583 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11584 if (needSep) { 11585 pw.println(); 11586 needSep = false; 11587 } 11588 pw.println(" mHomeProcess: " + mHomeProcess); 11589 } 11590 if (mPreviousProcess != null && (dumpPackage == null 11591 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11592 if (needSep) { 11593 pw.println(); 11594 needSep = false; 11595 } 11596 pw.println(" mPreviousProcess: " + mPreviousProcess); 11597 } 11598 if (dumpAll) { 11599 StringBuilder sb = new StringBuilder(128); 11600 sb.append(" mPreviousProcessVisibleTime: "); 11601 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11602 pw.println(sb); 11603 } 11604 if (mHeavyWeightProcess != null && (dumpPackage == null 11605 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11606 if (needSep) { 11607 pw.println(); 11608 needSep = false; 11609 } 11610 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11611 } 11612 if (dumpPackage == null) { 11613 pw.println(" mConfiguration: " + mConfiguration); 11614 } 11615 if (dumpAll) { 11616 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11617 if (mCompatModePackages.getPackages().size() > 0) { 11618 boolean printed = false; 11619 for (Map.Entry<String, Integer> entry 11620 : mCompatModePackages.getPackages().entrySet()) { 11621 String pkg = entry.getKey(); 11622 int mode = entry.getValue(); 11623 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11624 continue; 11625 } 11626 if (!printed) { 11627 pw.println(" mScreenCompatPackages:"); 11628 printed = true; 11629 } 11630 pw.print(" "); pw.print(pkg); pw.print(": "); 11631 pw.print(mode); pw.println(); 11632 } 11633 } 11634 } 11635 if (dumpPackage == null) { 11636 if (mSleeping || mWentToSleep || mLockScreenShown) { 11637 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11638 + " mLockScreenShown " + mLockScreenShown); 11639 } 11640 if (mShuttingDown || mRunningVoice) { 11641 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11642 } 11643 } 11644 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11645 || mOrigWaitForDebugger) { 11646 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11647 || dumpPackage.equals(mOrigDebugApp)) { 11648 if (needSep) { 11649 pw.println(); 11650 needSep = false; 11651 } 11652 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11653 + " mDebugTransient=" + mDebugTransient 11654 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11655 } 11656 } 11657 if (mOpenGlTraceApp != null) { 11658 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11659 if (needSep) { 11660 pw.println(); 11661 needSep = false; 11662 } 11663 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11664 } 11665 } 11666 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11667 || mProfileFd != null) { 11668 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11669 if (needSep) { 11670 pw.println(); 11671 needSep = false; 11672 } 11673 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11674 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11675 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11676 + mAutoStopProfiler); 11677 } 11678 } 11679 if (dumpPackage == null) { 11680 if (mAlwaysFinishActivities || mController != null) { 11681 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11682 + " mController=" + mController); 11683 } 11684 if (dumpAll) { 11685 pw.println(" Total persistent processes: " + numPers); 11686 pw.println(" mProcessesReady=" + mProcessesReady 11687 + " mSystemReady=" + mSystemReady); 11688 pw.println(" mBooting=" + mBooting 11689 + " mBooted=" + mBooted 11690 + " mFactoryTest=" + mFactoryTest); 11691 pw.print(" mLastPowerCheckRealtime="); 11692 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11693 pw.println(""); 11694 pw.print(" mLastPowerCheckUptime="); 11695 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11696 pw.println(""); 11697 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11698 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11699 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11700 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11701 + " (" + mLruProcesses.size() + " total)" 11702 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11703 + " mNumServiceProcs=" + mNumServiceProcs 11704 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11705 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11706 + " mLastMemoryLevel" + mLastMemoryLevel 11707 + " mLastNumProcesses" + mLastNumProcesses); 11708 long now = SystemClock.uptimeMillis(); 11709 pw.print(" mLastIdleTime="); 11710 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11711 pw.print(" mLowRamSinceLastIdle="); 11712 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11713 pw.println(); 11714 } 11715 } 11716 11717 if (!printedAnything) { 11718 pw.println(" (nothing)"); 11719 } 11720 } 11721 11722 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11723 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11724 if (mProcessesToGc.size() > 0) { 11725 boolean printed = false; 11726 long now = SystemClock.uptimeMillis(); 11727 for (int i=0; i<mProcessesToGc.size(); i++) { 11728 ProcessRecord proc = mProcessesToGc.get(i); 11729 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11730 continue; 11731 } 11732 if (!printed) { 11733 if (needSep) pw.println(); 11734 needSep = true; 11735 pw.println(" Processes that are waiting to GC:"); 11736 printed = true; 11737 } 11738 pw.print(" Process "); pw.println(proc); 11739 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11740 pw.print(", last gced="); 11741 pw.print(now-proc.lastRequestedGc); 11742 pw.print(" ms ago, last lowMem="); 11743 pw.print(now-proc.lastLowMemory); 11744 pw.println(" ms ago"); 11745 11746 } 11747 } 11748 return needSep; 11749 } 11750 11751 void printOomLevel(PrintWriter pw, String name, int adj) { 11752 pw.print(" "); 11753 if (adj >= 0) { 11754 pw.print(' '); 11755 if (adj < 10) pw.print(' '); 11756 } else { 11757 if (adj > -10) pw.print(' '); 11758 } 11759 pw.print(adj); 11760 pw.print(": "); 11761 pw.print(name); 11762 pw.print(" ("); 11763 pw.print(mProcessList.getMemLevel(adj)/1024); 11764 pw.println(" kB)"); 11765 } 11766 11767 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11768 int opti, boolean dumpAll) { 11769 boolean needSep = false; 11770 11771 if (mLruProcesses.size() > 0) { 11772 if (needSep) pw.println(); 11773 needSep = true; 11774 pw.println(" OOM levels:"); 11775 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11776 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11777 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11778 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11779 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11780 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11781 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11782 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11783 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11784 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11785 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11786 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11787 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11788 11789 if (needSep) pw.println(); 11790 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11791 pw.print(" total, non-act at "); 11792 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11793 pw.print(", non-svc at "); 11794 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11795 pw.println("):"); 11796 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11797 needSep = true; 11798 } 11799 11800 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11801 11802 pw.println(); 11803 pw.println(" mHomeProcess: " + mHomeProcess); 11804 pw.println(" mPreviousProcess: " + mPreviousProcess); 11805 if (mHeavyWeightProcess != null) { 11806 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11807 } 11808 11809 return true; 11810 } 11811 11812 /** 11813 * There are three ways to call this: 11814 * - no provider specified: dump all the providers 11815 * - a flattened component name that matched an existing provider was specified as the 11816 * first arg: dump that one provider 11817 * - the first arg isn't the flattened component name of an existing provider: 11818 * dump all providers whose component contains the first arg as a substring 11819 */ 11820 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11821 int opti, boolean dumpAll) { 11822 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11823 } 11824 11825 static class ItemMatcher { 11826 ArrayList<ComponentName> components; 11827 ArrayList<String> strings; 11828 ArrayList<Integer> objects; 11829 boolean all; 11830 11831 ItemMatcher() { 11832 all = true; 11833 } 11834 11835 void build(String name) { 11836 ComponentName componentName = ComponentName.unflattenFromString(name); 11837 if (componentName != null) { 11838 if (components == null) { 11839 components = new ArrayList<ComponentName>(); 11840 } 11841 components.add(componentName); 11842 all = false; 11843 } else { 11844 int objectId = 0; 11845 // Not a '/' separated full component name; maybe an object ID? 11846 try { 11847 objectId = Integer.parseInt(name, 16); 11848 if (objects == null) { 11849 objects = new ArrayList<Integer>(); 11850 } 11851 objects.add(objectId); 11852 all = false; 11853 } catch (RuntimeException e) { 11854 // Not an integer; just do string match. 11855 if (strings == null) { 11856 strings = new ArrayList<String>(); 11857 } 11858 strings.add(name); 11859 all = false; 11860 } 11861 } 11862 } 11863 11864 int build(String[] args, int opti) { 11865 for (; opti<args.length; opti++) { 11866 String name = args[opti]; 11867 if ("--".equals(name)) { 11868 return opti+1; 11869 } 11870 build(name); 11871 } 11872 return opti; 11873 } 11874 11875 boolean match(Object object, ComponentName comp) { 11876 if (all) { 11877 return true; 11878 } 11879 if (components != null) { 11880 for (int i=0; i<components.size(); i++) { 11881 if (components.get(i).equals(comp)) { 11882 return true; 11883 } 11884 } 11885 } 11886 if (objects != null) { 11887 for (int i=0; i<objects.size(); i++) { 11888 if (System.identityHashCode(object) == objects.get(i)) { 11889 return true; 11890 } 11891 } 11892 } 11893 if (strings != null) { 11894 String flat = comp.flattenToString(); 11895 for (int i=0; i<strings.size(); i++) { 11896 if (flat.contains(strings.get(i))) { 11897 return true; 11898 } 11899 } 11900 } 11901 return false; 11902 } 11903 } 11904 11905 /** 11906 * There are three things that cmd can be: 11907 * - a flattened component name that matches an existing activity 11908 * - the cmd arg isn't the flattened component name of an existing activity: 11909 * dump all activity whose component contains the cmd as a substring 11910 * - A hex number of the ActivityRecord object instance. 11911 */ 11912 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11913 int opti, boolean dumpAll) { 11914 ArrayList<ActivityRecord> activities; 11915 11916 synchronized (this) { 11917 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11918 } 11919 11920 if (activities.size() <= 0) { 11921 return false; 11922 } 11923 11924 String[] newArgs = new String[args.length - opti]; 11925 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11926 11927 TaskRecord lastTask = null; 11928 boolean needSep = false; 11929 for (int i=activities.size()-1; i>=0; i--) { 11930 ActivityRecord r = activities.get(i); 11931 if (needSep) { 11932 pw.println(); 11933 } 11934 needSep = true; 11935 synchronized (this) { 11936 if (lastTask != r.task) { 11937 lastTask = r.task; 11938 pw.print("TASK "); pw.print(lastTask.affinity); 11939 pw.print(" id="); pw.println(lastTask.taskId); 11940 if (dumpAll) { 11941 lastTask.dump(pw, " "); 11942 } 11943 } 11944 } 11945 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11946 } 11947 return true; 11948 } 11949 11950 /** 11951 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11952 * there is a thread associated with the activity. 11953 */ 11954 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11955 final ActivityRecord r, String[] args, boolean dumpAll) { 11956 String innerPrefix = prefix + " "; 11957 synchronized (this) { 11958 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11959 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11960 pw.print(" pid="); 11961 if (r.app != null) pw.println(r.app.pid); 11962 else pw.println("(not running)"); 11963 if (dumpAll) { 11964 r.dump(pw, innerPrefix); 11965 } 11966 } 11967 if (r.app != null && r.app.thread != null) { 11968 // flush anything that is already in the PrintWriter since the thread is going 11969 // to write to the file descriptor directly 11970 pw.flush(); 11971 try { 11972 TransferPipe tp = new TransferPipe(); 11973 try { 11974 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11975 r.appToken, innerPrefix, args); 11976 tp.go(fd); 11977 } finally { 11978 tp.kill(); 11979 } 11980 } catch (IOException e) { 11981 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11982 } catch (RemoteException e) { 11983 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11984 } 11985 } 11986 } 11987 11988 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11989 int opti, boolean dumpAll, String dumpPackage) { 11990 boolean needSep = false; 11991 boolean onlyHistory = false; 11992 boolean printedAnything = false; 11993 11994 if ("history".equals(dumpPackage)) { 11995 if (opti < args.length && "-s".equals(args[opti])) { 11996 dumpAll = false; 11997 } 11998 onlyHistory = true; 11999 dumpPackage = null; 12000 } 12001 12002 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12003 if (!onlyHistory && dumpAll) { 12004 if (mRegisteredReceivers.size() > 0) { 12005 boolean printed = false; 12006 Iterator it = mRegisteredReceivers.values().iterator(); 12007 while (it.hasNext()) { 12008 ReceiverList r = (ReceiverList)it.next(); 12009 if (dumpPackage != null && (r.app == null || 12010 !dumpPackage.equals(r.app.info.packageName))) { 12011 continue; 12012 } 12013 if (!printed) { 12014 pw.println(" Registered Receivers:"); 12015 needSep = true; 12016 printed = true; 12017 printedAnything = true; 12018 } 12019 pw.print(" * "); pw.println(r); 12020 r.dump(pw, " "); 12021 } 12022 } 12023 12024 if (mReceiverResolver.dump(pw, needSep ? 12025 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12026 " ", dumpPackage, false)) { 12027 needSep = true; 12028 printedAnything = true; 12029 } 12030 } 12031 12032 for (BroadcastQueue q : mBroadcastQueues) { 12033 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12034 printedAnything |= needSep; 12035 } 12036 12037 needSep = true; 12038 12039 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12040 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12041 if (needSep) { 12042 pw.println(); 12043 } 12044 needSep = true; 12045 printedAnything = true; 12046 pw.print(" Sticky broadcasts for user "); 12047 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12048 StringBuilder sb = new StringBuilder(128); 12049 for (Map.Entry<String, ArrayList<Intent>> ent 12050 : mStickyBroadcasts.valueAt(user).entrySet()) { 12051 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12052 if (dumpAll) { 12053 pw.println(":"); 12054 ArrayList<Intent> intents = ent.getValue(); 12055 final int N = intents.size(); 12056 for (int i=0; i<N; i++) { 12057 sb.setLength(0); 12058 sb.append(" Intent: "); 12059 intents.get(i).toShortString(sb, false, true, false, false); 12060 pw.println(sb.toString()); 12061 Bundle bundle = intents.get(i).getExtras(); 12062 if (bundle != null) { 12063 pw.print(" "); 12064 pw.println(bundle.toString()); 12065 } 12066 } 12067 } else { 12068 pw.println(""); 12069 } 12070 } 12071 } 12072 } 12073 12074 if (!onlyHistory && dumpAll) { 12075 pw.println(); 12076 for (BroadcastQueue queue : mBroadcastQueues) { 12077 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12078 + queue.mBroadcastsScheduled); 12079 } 12080 pw.println(" mHandler:"); 12081 mHandler.dump(new PrintWriterPrinter(pw), " "); 12082 needSep = true; 12083 printedAnything = true; 12084 } 12085 12086 if (!printedAnything) { 12087 pw.println(" (nothing)"); 12088 } 12089 } 12090 12091 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12092 int opti, boolean dumpAll, String dumpPackage) { 12093 boolean needSep; 12094 boolean printedAnything = false; 12095 12096 ItemMatcher matcher = new ItemMatcher(); 12097 matcher.build(args, opti); 12098 12099 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12100 12101 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12102 printedAnything |= needSep; 12103 12104 if (mLaunchingProviders.size() > 0) { 12105 boolean printed = false; 12106 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12107 ContentProviderRecord r = mLaunchingProviders.get(i); 12108 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12109 continue; 12110 } 12111 if (!printed) { 12112 if (needSep) pw.println(); 12113 needSep = true; 12114 pw.println(" Launching content providers:"); 12115 printed = true; 12116 printedAnything = true; 12117 } 12118 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12119 pw.println(r); 12120 } 12121 } 12122 12123 if (mGrantedUriPermissions.size() > 0) { 12124 boolean printed = false; 12125 int dumpUid = -2; 12126 if (dumpPackage != null) { 12127 try { 12128 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12129 } catch (NameNotFoundException e) { 12130 dumpUid = -1; 12131 } 12132 } 12133 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12134 int uid = mGrantedUriPermissions.keyAt(i); 12135 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12136 continue; 12137 } 12138 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12139 if (!printed) { 12140 if (needSep) pw.println(); 12141 needSep = true; 12142 pw.println(" Granted Uri Permissions:"); 12143 printed = true; 12144 printedAnything = true; 12145 } 12146 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12147 for (UriPermission perm : perms.values()) { 12148 pw.print(" "); pw.println(perm); 12149 if (dumpAll) { 12150 perm.dump(pw, " "); 12151 } 12152 } 12153 } 12154 } 12155 12156 if (!printedAnything) { 12157 pw.println(" (nothing)"); 12158 } 12159 } 12160 12161 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12162 int opti, boolean dumpAll, String dumpPackage) { 12163 boolean printed = false; 12164 12165 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12166 12167 if (mIntentSenderRecords.size() > 0) { 12168 Iterator<WeakReference<PendingIntentRecord>> it 12169 = mIntentSenderRecords.values().iterator(); 12170 while (it.hasNext()) { 12171 WeakReference<PendingIntentRecord> ref = it.next(); 12172 PendingIntentRecord rec = ref != null ? ref.get(): null; 12173 if (dumpPackage != null && (rec == null 12174 || !dumpPackage.equals(rec.key.packageName))) { 12175 continue; 12176 } 12177 printed = true; 12178 if (rec != null) { 12179 pw.print(" * "); pw.println(rec); 12180 if (dumpAll) { 12181 rec.dump(pw, " "); 12182 } 12183 } else { 12184 pw.print(" * "); pw.println(ref); 12185 } 12186 } 12187 } 12188 12189 if (!printed) { 12190 pw.println(" (nothing)"); 12191 } 12192 } 12193 12194 private static final int dumpProcessList(PrintWriter pw, 12195 ActivityManagerService service, List list, 12196 String prefix, String normalLabel, String persistentLabel, 12197 String dumpPackage) { 12198 int numPers = 0; 12199 final int N = list.size()-1; 12200 for (int i=N; i>=0; i--) { 12201 ProcessRecord r = (ProcessRecord)list.get(i); 12202 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12203 continue; 12204 } 12205 pw.println(String.format("%s%s #%2d: %s", 12206 prefix, (r.persistent ? persistentLabel : normalLabel), 12207 i, r.toString())); 12208 if (r.persistent) { 12209 numPers++; 12210 } 12211 } 12212 return numPers; 12213 } 12214 12215 private static final boolean dumpProcessOomList(PrintWriter pw, 12216 ActivityManagerService service, List<ProcessRecord> origList, 12217 String prefix, String normalLabel, String persistentLabel, 12218 boolean inclDetails, String dumpPackage) { 12219 12220 ArrayList<Pair<ProcessRecord, Integer>> list 12221 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12222 for (int i=0; i<origList.size(); i++) { 12223 ProcessRecord r = origList.get(i); 12224 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12225 continue; 12226 } 12227 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12228 } 12229 12230 if (list.size() <= 0) { 12231 return false; 12232 } 12233 12234 Comparator<Pair<ProcessRecord, Integer>> comparator 12235 = new Comparator<Pair<ProcessRecord, Integer>>() { 12236 @Override 12237 public int compare(Pair<ProcessRecord, Integer> object1, 12238 Pair<ProcessRecord, Integer> object2) { 12239 if (object1.first.setAdj != object2.first.setAdj) { 12240 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12241 } 12242 if (object1.second.intValue() != object2.second.intValue()) { 12243 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12244 } 12245 return 0; 12246 } 12247 }; 12248 12249 Collections.sort(list, comparator); 12250 12251 final long curRealtime = SystemClock.elapsedRealtime(); 12252 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12253 final long curUptime = SystemClock.uptimeMillis(); 12254 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12255 12256 for (int i=list.size()-1; i>=0; i--) { 12257 ProcessRecord r = list.get(i).first; 12258 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12259 char schedGroup; 12260 switch (r.setSchedGroup) { 12261 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12262 schedGroup = 'B'; 12263 break; 12264 case Process.THREAD_GROUP_DEFAULT: 12265 schedGroup = 'F'; 12266 break; 12267 default: 12268 schedGroup = '?'; 12269 break; 12270 } 12271 char foreground; 12272 if (r.foregroundActivities) { 12273 foreground = 'A'; 12274 } else if (r.foregroundServices) { 12275 foreground = 'S'; 12276 } else { 12277 foreground = ' '; 12278 } 12279 String procState = ProcessList.makeProcStateString(r.curProcState); 12280 pw.print(prefix); 12281 pw.print(r.persistent ? persistentLabel : normalLabel); 12282 pw.print(" #"); 12283 int num = (origList.size()-1)-list.get(i).second; 12284 if (num < 10) pw.print(' '); 12285 pw.print(num); 12286 pw.print(": "); 12287 pw.print(oomAdj); 12288 pw.print(' '); 12289 pw.print(schedGroup); 12290 pw.print('/'); 12291 pw.print(foreground); 12292 pw.print('/'); 12293 pw.print(procState); 12294 pw.print(" trm:"); 12295 if (r.trimMemoryLevel < 10) pw.print(' '); 12296 pw.print(r.trimMemoryLevel); 12297 pw.print(' '); 12298 pw.print(r.toShortString()); 12299 pw.print(" ("); 12300 pw.print(r.adjType); 12301 pw.println(')'); 12302 if (r.adjSource != null || r.adjTarget != null) { 12303 pw.print(prefix); 12304 pw.print(" "); 12305 if (r.adjTarget instanceof ComponentName) { 12306 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12307 } else if (r.adjTarget != null) { 12308 pw.print(r.adjTarget.toString()); 12309 } else { 12310 pw.print("{null}"); 12311 } 12312 pw.print("<="); 12313 if (r.adjSource instanceof ProcessRecord) { 12314 pw.print("Proc{"); 12315 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12316 pw.println("}"); 12317 } else if (r.adjSource != null) { 12318 pw.println(r.adjSource.toString()); 12319 } else { 12320 pw.println("{null}"); 12321 } 12322 } 12323 if (inclDetails) { 12324 pw.print(prefix); 12325 pw.print(" "); 12326 pw.print("oom: max="); pw.print(r.maxAdj); 12327 pw.print(" curRaw="); pw.print(r.curRawAdj); 12328 pw.print(" setRaw="); pw.print(r.setRawAdj); 12329 pw.print(" cur="); pw.print(r.curAdj); 12330 pw.print(" set="); pw.println(r.setAdj); 12331 pw.print(prefix); 12332 pw.print(" "); 12333 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12334 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12335 pw.print(" lastPss="); pw.print(r.lastPss); 12336 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12337 pw.print(prefix); 12338 pw.print(" "); 12339 pw.print("keeping="); pw.print(r.keeping); 12340 pw.print(" cached="); pw.print(r.cached); 12341 pw.print(" empty="); pw.print(r.empty); 12342 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12343 12344 if (!r.keeping) { 12345 if (r.lastWakeTime != 0) { 12346 long wtime; 12347 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12348 synchronized (stats) { 12349 wtime = stats.getProcessWakeTime(r.info.uid, 12350 r.pid, curRealtime); 12351 } 12352 long timeUsed = wtime - r.lastWakeTime; 12353 pw.print(prefix); 12354 pw.print(" "); 12355 pw.print("keep awake over "); 12356 TimeUtils.formatDuration(realtimeSince, pw); 12357 pw.print(" used "); 12358 TimeUtils.formatDuration(timeUsed, pw); 12359 pw.print(" ("); 12360 pw.print((timeUsed*100)/realtimeSince); 12361 pw.println("%)"); 12362 } 12363 if (r.lastCpuTime != 0) { 12364 long timeUsed = r.curCpuTime - r.lastCpuTime; 12365 pw.print(prefix); 12366 pw.print(" "); 12367 pw.print("run cpu over "); 12368 TimeUtils.formatDuration(uptimeSince, pw); 12369 pw.print(" used "); 12370 TimeUtils.formatDuration(timeUsed, pw); 12371 pw.print(" ("); 12372 pw.print((timeUsed*100)/uptimeSince); 12373 pw.println("%)"); 12374 } 12375 } 12376 } 12377 } 12378 return true; 12379 } 12380 12381 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12382 ArrayList<ProcessRecord> procs; 12383 synchronized (this) { 12384 if (args != null && args.length > start 12385 && args[start].charAt(0) != '-') { 12386 procs = new ArrayList<ProcessRecord>(); 12387 int pid = -1; 12388 try { 12389 pid = Integer.parseInt(args[start]); 12390 } catch (NumberFormatException e) { 12391 } 12392 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12393 ProcessRecord proc = mLruProcesses.get(i); 12394 if (proc.pid == pid) { 12395 procs.add(proc); 12396 } else if (proc.processName.equals(args[start])) { 12397 procs.add(proc); 12398 } 12399 } 12400 if (procs.size() <= 0) { 12401 return null; 12402 } 12403 } else { 12404 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12405 } 12406 } 12407 return procs; 12408 } 12409 12410 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12411 PrintWriter pw, String[] args) { 12412 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12413 if (procs == null) { 12414 pw.println("No process found for: " + args[0]); 12415 return; 12416 } 12417 12418 long uptime = SystemClock.uptimeMillis(); 12419 long realtime = SystemClock.elapsedRealtime(); 12420 pw.println("Applications Graphics Acceleration Info:"); 12421 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12422 12423 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12424 ProcessRecord r = procs.get(i); 12425 if (r.thread != null) { 12426 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12427 pw.flush(); 12428 try { 12429 TransferPipe tp = new TransferPipe(); 12430 try { 12431 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12432 tp.go(fd); 12433 } finally { 12434 tp.kill(); 12435 } 12436 } catch (IOException e) { 12437 pw.println("Failure while dumping the app: " + r); 12438 pw.flush(); 12439 } catch (RemoteException e) { 12440 pw.println("Got a RemoteException while dumping the app " + r); 12441 pw.flush(); 12442 } 12443 } 12444 } 12445 } 12446 12447 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12448 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12449 if (procs == null) { 12450 pw.println("No process found for: " + args[0]); 12451 return; 12452 } 12453 12454 pw.println("Applications Database Info:"); 12455 12456 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12457 ProcessRecord r = procs.get(i); 12458 if (r.thread != null) { 12459 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12460 pw.flush(); 12461 try { 12462 TransferPipe tp = new TransferPipe(); 12463 try { 12464 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12465 tp.go(fd); 12466 } finally { 12467 tp.kill(); 12468 } 12469 } catch (IOException e) { 12470 pw.println("Failure while dumping the app: " + r); 12471 pw.flush(); 12472 } catch (RemoteException e) { 12473 pw.println("Got a RemoteException while dumping the app " + r); 12474 pw.flush(); 12475 } 12476 } 12477 } 12478 } 12479 12480 final static class MemItem { 12481 final boolean isProc; 12482 final String label; 12483 final String shortLabel; 12484 final long pss; 12485 final int id; 12486 final boolean hasActivities; 12487 ArrayList<MemItem> subitems; 12488 12489 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12490 boolean _hasActivities) { 12491 isProc = true; 12492 label = _label; 12493 shortLabel = _shortLabel; 12494 pss = _pss; 12495 id = _id; 12496 hasActivities = _hasActivities; 12497 } 12498 12499 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12500 isProc = false; 12501 label = _label; 12502 shortLabel = _shortLabel; 12503 pss = _pss; 12504 id = _id; 12505 hasActivities = false; 12506 } 12507 } 12508 12509 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12510 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12511 if (sort && !isCompact) { 12512 Collections.sort(items, new Comparator<MemItem>() { 12513 @Override 12514 public int compare(MemItem lhs, MemItem rhs) { 12515 if (lhs.pss < rhs.pss) { 12516 return 1; 12517 } else if (lhs.pss > rhs.pss) { 12518 return -1; 12519 } 12520 return 0; 12521 } 12522 }); 12523 } 12524 12525 for (int i=0; i<items.size(); i++) { 12526 MemItem mi = items.get(i); 12527 if (!isCompact) { 12528 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12529 } else if (mi.isProc) { 12530 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12531 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12532 pw.println(mi.hasActivities ? ",a" : ",e"); 12533 } else { 12534 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12535 pw.println(mi.pss); 12536 } 12537 if (mi.subitems != null) { 12538 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12539 true, isCompact); 12540 } 12541 } 12542 } 12543 12544 // These are in KB. 12545 static final long[] DUMP_MEM_BUCKETS = new long[] { 12546 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12547 120*1024, 160*1024, 200*1024, 12548 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12549 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12550 }; 12551 12552 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12553 boolean stackLike) { 12554 int start = label.lastIndexOf('.'); 12555 if (start >= 0) start++; 12556 else start = 0; 12557 int end = label.length(); 12558 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12559 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12560 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12561 out.append(bucket); 12562 out.append(stackLike ? "MB." : "MB "); 12563 out.append(label, start, end); 12564 return; 12565 } 12566 } 12567 out.append(memKB/1024); 12568 out.append(stackLike ? "MB." : "MB "); 12569 out.append(label, start, end); 12570 } 12571 12572 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12573 ProcessList.NATIVE_ADJ, 12574 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12575 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12576 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12577 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12578 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12579 }; 12580 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12581 "Native", 12582 "System", "Persistent", "Foreground", 12583 "Visible", "Perceptible", 12584 "Heavy Weight", "Backup", 12585 "A Services", "Home", 12586 "Previous", "B Services", "Cached" 12587 }; 12588 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12589 "native", 12590 "sys", "pers", "fore", 12591 "vis", "percept", 12592 "heavy", "backup", 12593 "servicea", "home", 12594 "prev", "serviceb", "cached" 12595 }; 12596 12597 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12598 long realtime, boolean isCheckinRequest, boolean isCompact) { 12599 if (isCheckinRequest || isCompact) { 12600 // short checkin version 12601 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12602 } else { 12603 pw.println("Applications Memory Usage (kB):"); 12604 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12605 } 12606 } 12607 12608 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12609 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12610 boolean dumpDetails = false; 12611 boolean dumpFullDetails = false; 12612 boolean dumpDalvik = false; 12613 boolean oomOnly = false; 12614 boolean isCompact = false; 12615 boolean localOnly = false; 12616 12617 int opti = 0; 12618 while (opti < args.length) { 12619 String opt = args[opti]; 12620 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12621 break; 12622 } 12623 opti++; 12624 if ("-a".equals(opt)) { 12625 dumpDetails = true; 12626 dumpFullDetails = true; 12627 dumpDalvik = true; 12628 } else if ("-d".equals(opt)) { 12629 dumpDalvik = true; 12630 } else if ("-c".equals(opt)) { 12631 isCompact = true; 12632 } else if ("--oom".equals(opt)) { 12633 oomOnly = true; 12634 } else if ("--local".equals(opt)) { 12635 localOnly = true; 12636 } else if ("-h".equals(opt)) { 12637 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12638 pw.println(" -a: include all available information for each process."); 12639 pw.println(" -d: include dalvik details when dumping process details."); 12640 pw.println(" -c: dump in a compact machine-parseable representation."); 12641 pw.println(" --oom: only show processes organized by oom adj."); 12642 pw.println(" --local: only collect details locally, don't call process."); 12643 pw.println("If [process] is specified it can be the name or "); 12644 pw.println("pid of a specific process to dump."); 12645 return; 12646 } else { 12647 pw.println("Unknown argument: " + opt + "; use -h for help"); 12648 } 12649 } 12650 12651 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12652 long uptime = SystemClock.uptimeMillis(); 12653 long realtime = SystemClock.elapsedRealtime(); 12654 final long[] tmpLong = new long[1]; 12655 12656 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12657 if (procs == null) { 12658 // No Java processes. Maybe they want to print a native process. 12659 if (args != null && args.length > opti 12660 && args[opti].charAt(0) != '-') { 12661 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12662 = new ArrayList<ProcessCpuTracker.Stats>(); 12663 updateCpuStatsNow(); 12664 int findPid = -1; 12665 try { 12666 findPid = Integer.parseInt(args[opti]); 12667 } catch (NumberFormatException e) { 12668 } 12669 synchronized (mProcessCpuThread) { 12670 final int N = mProcessCpuTracker.countStats(); 12671 for (int i=0; i<N; i++) { 12672 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12673 if (st.pid == findPid || (st.baseName != null 12674 && st.baseName.equals(args[opti]))) { 12675 nativeProcs.add(st); 12676 } 12677 } 12678 } 12679 if (nativeProcs.size() > 0) { 12680 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12681 isCompact); 12682 Debug.MemoryInfo mi = null; 12683 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12684 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12685 final int pid = r.pid; 12686 if (!isCheckinRequest && dumpDetails) { 12687 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12688 } 12689 if (mi == null) { 12690 mi = new Debug.MemoryInfo(); 12691 } 12692 if (dumpDetails || (!brief && !oomOnly)) { 12693 Debug.getMemoryInfo(pid, mi); 12694 } else { 12695 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12696 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12697 } 12698 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12699 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12700 if (isCheckinRequest) { 12701 pw.println(); 12702 } 12703 } 12704 return; 12705 } 12706 } 12707 pw.println("No process found for: " + args[opti]); 12708 return; 12709 } 12710 12711 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12712 dumpDetails = true; 12713 } 12714 12715 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12716 12717 String[] innerArgs = new String[args.length-opti]; 12718 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12719 12720 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12721 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12722 long nativePss=0, dalvikPss=0, otherPss=0; 12723 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12724 12725 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12726 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12727 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12728 12729 long totalPss = 0; 12730 long cachedPss = 0; 12731 12732 Debug.MemoryInfo mi = null; 12733 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12734 final ProcessRecord r = procs.get(i); 12735 final IApplicationThread thread; 12736 final int pid; 12737 final int oomAdj; 12738 final boolean hasActivities; 12739 synchronized (this) { 12740 thread = r.thread; 12741 pid = r.pid; 12742 oomAdj = r.getSetAdjWithServices(); 12743 hasActivities = r.activities.size() > 0; 12744 } 12745 if (thread != null) { 12746 if (!isCheckinRequest && dumpDetails) { 12747 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12748 } 12749 if (mi == null) { 12750 mi = new Debug.MemoryInfo(); 12751 } 12752 if (dumpDetails || (!brief && !oomOnly)) { 12753 Debug.getMemoryInfo(pid, mi); 12754 } else { 12755 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12756 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12757 } 12758 if (dumpDetails) { 12759 if (localOnly) { 12760 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12761 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12762 if (isCheckinRequest) { 12763 pw.println(); 12764 } 12765 } else { 12766 try { 12767 pw.flush(); 12768 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12769 dumpDalvik, innerArgs); 12770 } catch (RemoteException e) { 12771 if (!isCheckinRequest) { 12772 pw.println("Got RemoteException!"); 12773 pw.flush(); 12774 } 12775 } 12776 } 12777 } 12778 12779 final long myTotalPss = mi.getTotalPss(); 12780 final long myTotalUss = mi.getTotalUss(); 12781 12782 synchronized (this) { 12783 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12784 // Record this for posterity if the process has been stable. 12785 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12786 } 12787 } 12788 12789 if (!isCheckinRequest && mi != null) { 12790 totalPss += myTotalPss; 12791 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12792 (hasActivities ? " / activities)" : ")"), 12793 r.processName, myTotalPss, pid, hasActivities); 12794 procMems.add(pssItem); 12795 procMemsMap.put(pid, pssItem); 12796 12797 nativePss += mi.nativePss; 12798 dalvikPss += mi.dalvikPss; 12799 otherPss += mi.otherPss; 12800 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12801 long mem = mi.getOtherPss(j); 12802 miscPss[j] += mem; 12803 otherPss -= mem; 12804 } 12805 12806 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12807 cachedPss += myTotalPss; 12808 } 12809 12810 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12811 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12812 || oomIndex == (oomPss.length-1)) { 12813 oomPss[oomIndex] += myTotalPss; 12814 if (oomProcs[oomIndex] == null) { 12815 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12816 } 12817 oomProcs[oomIndex].add(pssItem); 12818 break; 12819 } 12820 } 12821 } 12822 } 12823 } 12824 12825 long nativeProcTotalPss = 0; 12826 12827 if (!isCheckinRequest && procs.size() > 1) { 12828 // If we are showing aggregations, also look for native processes to 12829 // include so that our aggregations are more accurate. 12830 updateCpuStatsNow(); 12831 synchronized (mProcessCpuThread) { 12832 final int N = mProcessCpuTracker.countStats(); 12833 for (int i=0; i<N; i++) { 12834 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12835 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12836 if (mi == null) { 12837 mi = new Debug.MemoryInfo(); 12838 } 12839 if (!brief && !oomOnly) { 12840 Debug.getMemoryInfo(st.pid, mi); 12841 } else { 12842 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12843 mi.nativePrivateDirty = (int)tmpLong[0]; 12844 } 12845 12846 final long myTotalPss = mi.getTotalPss(); 12847 totalPss += myTotalPss; 12848 nativeProcTotalPss += myTotalPss; 12849 12850 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12851 st.name, myTotalPss, st.pid, false); 12852 procMems.add(pssItem); 12853 12854 nativePss += mi.nativePss; 12855 dalvikPss += mi.dalvikPss; 12856 otherPss += mi.otherPss; 12857 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12858 long mem = mi.getOtherPss(j); 12859 miscPss[j] += mem; 12860 otherPss -= mem; 12861 } 12862 oomPss[0] += myTotalPss; 12863 if (oomProcs[0] == null) { 12864 oomProcs[0] = new ArrayList<MemItem>(); 12865 } 12866 oomProcs[0].add(pssItem); 12867 } 12868 } 12869 } 12870 12871 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12872 12873 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12874 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12875 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12876 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12877 String label = Debug.MemoryInfo.getOtherLabel(j); 12878 catMems.add(new MemItem(label, label, miscPss[j], j)); 12879 } 12880 12881 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12882 for (int j=0; j<oomPss.length; j++) { 12883 if (oomPss[j] != 0) { 12884 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12885 : DUMP_MEM_OOM_LABEL[j]; 12886 MemItem item = new MemItem(label, label, oomPss[j], 12887 DUMP_MEM_OOM_ADJ[j]); 12888 item.subitems = oomProcs[j]; 12889 oomMems.add(item); 12890 } 12891 } 12892 12893 if (!brief && !oomOnly && !isCompact) { 12894 pw.println(); 12895 pw.println("Total PSS by process:"); 12896 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12897 pw.println(); 12898 } 12899 if (!isCompact) { 12900 pw.println("Total PSS by OOM adjustment:"); 12901 } 12902 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12903 if (!brief && !oomOnly) { 12904 PrintWriter out = categoryPw != null ? categoryPw : pw; 12905 if (!isCompact) { 12906 out.println(); 12907 out.println("Total PSS by category:"); 12908 } 12909 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12910 } 12911 if (!isCompact) { 12912 pw.println(); 12913 } 12914 MemInfoReader memInfo = new MemInfoReader(); 12915 memInfo.readMemInfo(); 12916 if (nativeProcTotalPss > 0) { 12917 synchronized (this) { 12918 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12919 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12920 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12921 nativeProcTotalPss); 12922 } 12923 } 12924 if (!brief) { 12925 if (!isCompact) { 12926 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12927 pw.print(" kB (status "); 12928 switch (mLastMemoryLevel) { 12929 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12930 pw.println("normal)"); 12931 break; 12932 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12933 pw.println("moderate)"); 12934 break; 12935 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12936 pw.println("low)"); 12937 break; 12938 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12939 pw.println("critical)"); 12940 break; 12941 default: 12942 pw.print(mLastMemoryLevel); 12943 pw.println(")"); 12944 break; 12945 } 12946 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12947 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12948 pw.print(cachedPss); pw.print(" cached pss + "); 12949 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12950 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12951 } else { 12952 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12953 pw.print(cachedPss + memInfo.getCachedSizeKb() 12954 + memInfo.getFreeSizeKb()); pw.print(","); 12955 pw.println(totalPss - cachedPss); 12956 } 12957 } 12958 if (!isCompact) { 12959 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12960 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12961 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12962 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12963 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12964 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12965 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12966 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12967 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12968 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12969 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12970 } 12971 if (!brief) { 12972 if (memInfo.getZramTotalSizeKb() != 0) { 12973 if (!isCompact) { 12974 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12975 pw.print(" kB physical used for "); 12976 pw.print(memInfo.getSwapTotalSizeKb() 12977 - memInfo.getSwapFreeSizeKb()); 12978 pw.print(" kB in swap ("); 12979 pw.print(memInfo.getSwapTotalSizeKb()); 12980 pw.println(" kB total swap)"); 12981 } else { 12982 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12983 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12984 pw.println(memInfo.getSwapFreeSizeKb()); 12985 } 12986 } 12987 final int[] SINGLE_LONG_FORMAT = new int[] { 12988 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12989 }; 12990 long[] longOut = new long[1]; 12991 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12992 SINGLE_LONG_FORMAT, null, longOut, null); 12993 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12994 longOut[0] = 0; 12995 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12996 SINGLE_LONG_FORMAT, null, longOut, null); 12997 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12998 longOut[0] = 0; 12999 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13000 SINGLE_LONG_FORMAT, null, longOut, null); 13001 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13002 longOut[0] = 0; 13003 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13004 SINGLE_LONG_FORMAT, null, longOut, null); 13005 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13006 if (!isCompact) { 13007 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13008 pw.print(" KSM: "); pw.print(sharing); 13009 pw.print(" kB saved from shared "); 13010 pw.print(shared); pw.println(" kB"); 13011 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13012 pw.print(voltile); pw.println(" kB volatile"); 13013 } 13014 pw.print(" Tuning: "); 13015 pw.print(ActivityManager.staticGetMemoryClass()); 13016 pw.print(" (large "); 13017 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13018 pw.print("), oom "); 13019 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13020 pw.print(" kB"); 13021 pw.print(", restore limit "); 13022 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13023 pw.print(" kB"); 13024 if (ActivityManager.isLowRamDeviceStatic()) { 13025 pw.print(" (low-ram)"); 13026 } 13027 if (ActivityManager.isHighEndGfx()) { 13028 pw.print(" (high-end-gfx)"); 13029 } 13030 pw.println(); 13031 } else { 13032 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13033 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13034 pw.println(voltile); 13035 pw.print("tuning,"); 13036 pw.print(ActivityManager.staticGetMemoryClass()); 13037 pw.print(','); 13038 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13039 pw.print(','); 13040 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13041 if (ActivityManager.isLowRamDeviceStatic()) { 13042 pw.print(",low-ram"); 13043 } 13044 if (ActivityManager.isHighEndGfx()) { 13045 pw.print(",high-end-gfx"); 13046 } 13047 pw.println(); 13048 } 13049 } 13050 } 13051 } 13052 13053 /** 13054 * Searches array of arguments for the specified string 13055 * @param args array of argument strings 13056 * @param value value to search for 13057 * @return true if the value is contained in the array 13058 */ 13059 private static boolean scanArgs(String[] args, String value) { 13060 if (args != null) { 13061 for (String arg : args) { 13062 if (value.equals(arg)) { 13063 return true; 13064 } 13065 } 13066 } 13067 return false; 13068 } 13069 13070 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13071 ContentProviderRecord cpr, boolean always) { 13072 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13073 13074 if (!inLaunching || always) { 13075 synchronized (cpr) { 13076 cpr.launchingApp = null; 13077 cpr.notifyAll(); 13078 } 13079 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13080 String names[] = cpr.info.authority.split(";"); 13081 for (int j = 0; j < names.length; j++) { 13082 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13083 } 13084 } 13085 13086 for (int i=0; i<cpr.connections.size(); i++) { 13087 ContentProviderConnection conn = cpr.connections.get(i); 13088 if (conn.waiting) { 13089 // If this connection is waiting for the provider, then we don't 13090 // need to mess with its process unless we are always removing 13091 // or for some reason the provider is not currently launching. 13092 if (inLaunching && !always) { 13093 continue; 13094 } 13095 } 13096 ProcessRecord capp = conn.client; 13097 conn.dead = true; 13098 if (conn.stableCount > 0) { 13099 if (!capp.persistent && capp.thread != null 13100 && capp.pid != 0 13101 && capp.pid != MY_PID) { 13102 killUnneededProcessLocked(capp, "depends on provider " 13103 + cpr.name.flattenToShortString() 13104 + " in dying proc " + (proc != null ? proc.processName : "??")); 13105 } 13106 } else if (capp.thread != null && conn.provider.provider != null) { 13107 try { 13108 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13109 } catch (RemoteException e) { 13110 } 13111 // In the protocol here, we don't expect the client to correctly 13112 // clean up this connection, we'll just remove it. 13113 cpr.connections.remove(i); 13114 conn.client.conProviders.remove(conn); 13115 } 13116 } 13117 13118 if (inLaunching && always) { 13119 mLaunchingProviders.remove(cpr); 13120 } 13121 return inLaunching; 13122 } 13123 13124 /** 13125 * Main code for cleaning up a process when it has gone away. This is 13126 * called both as a result of the process dying, or directly when stopping 13127 * a process when running in single process mode. 13128 */ 13129 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13130 boolean restarting, boolean allowRestart, int index) { 13131 if (index >= 0) { 13132 removeLruProcessLocked(app); 13133 ProcessList.remove(app.pid); 13134 } 13135 13136 mProcessesToGc.remove(app); 13137 mPendingPssProcesses.remove(app); 13138 13139 // Dismiss any open dialogs. 13140 if (app.crashDialog != null && !app.forceCrashReport) { 13141 app.crashDialog.dismiss(); 13142 app.crashDialog = null; 13143 } 13144 if (app.anrDialog != null) { 13145 app.anrDialog.dismiss(); 13146 app.anrDialog = null; 13147 } 13148 if (app.waitDialog != null) { 13149 app.waitDialog.dismiss(); 13150 app.waitDialog = null; 13151 } 13152 13153 app.crashing = false; 13154 app.notResponding = false; 13155 13156 app.resetPackageList(mProcessStats); 13157 app.unlinkDeathRecipient(); 13158 app.makeInactive(mProcessStats); 13159 app.waitingToKill = null; 13160 app.forcingToForeground = null; 13161 updateProcessForegroundLocked(app, false, false); 13162 app.foregroundActivities = false; 13163 app.hasShownUi = false; 13164 app.treatLikeActivity = false; 13165 app.hasAboveClient = false; 13166 app.hasClientActivities = false; 13167 13168 mServices.killServicesLocked(app, allowRestart); 13169 13170 boolean restart = false; 13171 13172 // Remove published content providers. 13173 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13174 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13175 final boolean always = app.bad || !allowRestart; 13176 if (removeDyingProviderLocked(app, cpr, always) || always) { 13177 // We left the provider in the launching list, need to 13178 // restart it. 13179 restart = true; 13180 } 13181 13182 cpr.provider = null; 13183 cpr.proc = null; 13184 } 13185 app.pubProviders.clear(); 13186 13187 // Take care of any launching providers waiting for this process. 13188 if (checkAppInLaunchingProvidersLocked(app, false)) { 13189 restart = true; 13190 } 13191 13192 // Unregister from connected content providers. 13193 if (!app.conProviders.isEmpty()) { 13194 for (int i=0; i<app.conProviders.size(); i++) { 13195 ContentProviderConnection conn = app.conProviders.get(i); 13196 conn.provider.connections.remove(conn); 13197 } 13198 app.conProviders.clear(); 13199 } 13200 13201 // At this point there may be remaining entries in mLaunchingProviders 13202 // where we were the only one waiting, so they are no longer of use. 13203 // Look for these and clean up if found. 13204 // XXX Commented out for now. Trying to figure out a way to reproduce 13205 // the actual situation to identify what is actually going on. 13206 if (false) { 13207 for (int i=0; i<mLaunchingProviders.size(); i++) { 13208 ContentProviderRecord cpr = (ContentProviderRecord) 13209 mLaunchingProviders.get(i); 13210 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13211 synchronized (cpr) { 13212 cpr.launchingApp = null; 13213 cpr.notifyAll(); 13214 } 13215 } 13216 } 13217 } 13218 13219 skipCurrentReceiverLocked(app); 13220 13221 // Unregister any receivers. 13222 for (int i=app.receivers.size()-1; i>=0; i--) { 13223 removeReceiverLocked(app.receivers.valueAt(i)); 13224 } 13225 app.receivers.clear(); 13226 13227 // If the app is undergoing backup, tell the backup manager about it 13228 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13229 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13230 + mBackupTarget.appInfo + " died during backup"); 13231 try { 13232 IBackupManager bm = IBackupManager.Stub.asInterface( 13233 ServiceManager.getService(Context.BACKUP_SERVICE)); 13234 bm.agentDisconnected(app.info.packageName); 13235 } catch (RemoteException e) { 13236 // can't happen; backup manager is local 13237 } 13238 } 13239 13240 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13241 ProcessChangeItem item = mPendingProcessChanges.get(i); 13242 if (item.pid == app.pid) { 13243 mPendingProcessChanges.remove(i); 13244 mAvailProcessChanges.add(item); 13245 } 13246 } 13247 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13248 13249 // If the caller is restarting this app, then leave it in its 13250 // current lists and let the caller take care of it. 13251 if (restarting) { 13252 return; 13253 } 13254 13255 if (!app.persistent || app.isolated) { 13256 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13257 "Removing non-persistent process during cleanup: " + app); 13258 mProcessNames.remove(app.processName, app.uid); 13259 mIsolatedProcesses.remove(app.uid); 13260 if (mHeavyWeightProcess == app) { 13261 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13262 mHeavyWeightProcess.userId, 0)); 13263 mHeavyWeightProcess = null; 13264 } 13265 } else if (!app.removed) { 13266 // This app is persistent, so we need to keep its record around. 13267 // If it is not already on the pending app list, add it there 13268 // and start a new process for it. 13269 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13270 mPersistentStartingProcesses.add(app); 13271 restart = true; 13272 } 13273 } 13274 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13275 "Clean-up removing on hold: " + app); 13276 mProcessesOnHold.remove(app); 13277 13278 if (app == mHomeProcess) { 13279 mHomeProcess = null; 13280 } 13281 if (app == mPreviousProcess) { 13282 mPreviousProcess = null; 13283 } 13284 13285 if (restart && !app.isolated) { 13286 // We have components that still need to be running in the 13287 // process, so re-launch it. 13288 mProcessNames.put(app.processName, app.uid, app); 13289 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13290 } else if (app.pid > 0 && app.pid != MY_PID) { 13291 // Goodbye! 13292 boolean removed; 13293 synchronized (mPidsSelfLocked) { 13294 mPidsSelfLocked.remove(app.pid); 13295 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13296 } 13297 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13298 if (app.isolated) { 13299 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13300 } 13301 app.setPid(0); 13302 } 13303 } 13304 13305 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13306 // Look through the content providers we are waiting to have launched, 13307 // and if any run in this process then either schedule a restart of 13308 // the process or kill the client waiting for it if this process has 13309 // gone bad. 13310 int NL = mLaunchingProviders.size(); 13311 boolean restart = false; 13312 for (int i=0; i<NL; i++) { 13313 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13314 if (cpr.launchingApp == app) { 13315 if (!alwaysBad && !app.bad) { 13316 restart = true; 13317 } else { 13318 removeDyingProviderLocked(app, cpr, true); 13319 // cpr should have been removed from mLaunchingProviders 13320 NL = mLaunchingProviders.size(); 13321 i--; 13322 } 13323 } 13324 } 13325 return restart; 13326 } 13327 13328 // ========================================================= 13329 // SERVICES 13330 // ========================================================= 13331 13332 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13333 int flags) { 13334 enforceNotIsolatedCaller("getServices"); 13335 synchronized (this) { 13336 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13337 } 13338 } 13339 13340 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13341 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13342 synchronized (this) { 13343 return mServices.getRunningServiceControlPanelLocked(name); 13344 } 13345 } 13346 13347 public ComponentName startService(IApplicationThread caller, Intent service, 13348 String resolvedType, int userId) { 13349 enforceNotIsolatedCaller("startService"); 13350 // Refuse possible leaked file descriptors 13351 if (service != null && service.hasFileDescriptors() == true) { 13352 throw new IllegalArgumentException("File descriptors passed in Intent"); 13353 } 13354 13355 if (DEBUG_SERVICE) 13356 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13357 synchronized(this) { 13358 final int callingPid = Binder.getCallingPid(); 13359 final int callingUid = Binder.getCallingUid(); 13360 final long origId = Binder.clearCallingIdentity(); 13361 ComponentName res = mServices.startServiceLocked(caller, service, 13362 resolvedType, callingPid, callingUid, userId); 13363 Binder.restoreCallingIdentity(origId); 13364 return res; 13365 } 13366 } 13367 13368 ComponentName startServiceInPackage(int uid, 13369 Intent service, String resolvedType, int userId) { 13370 synchronized(this) { 13371 if (DEBUG_SERVICE) 13372 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13373 final long origId = Binder.clearCallingIdentity(); 13374 ComponentName res = mServices.startServiceLocked(null, service, 13375 resolvedType, -1, uid, userId); 13376 Binder.restoreCallingIdentity(origId); 13377 return res; 13378 } 13379 } 13380 13381 public int stopService(IApplicationThread caller, Intent service, 13382 String resolvedType, int userId) { 13383 enforceNotIsolatedCaller("stopService"); 13384 // Refuse possible leaked file descriptors 13385 if (service != null && service.hasFileDescriptors() == true) { 13386 throw new IllegalArgumentException("File descriptors passed in Intent"); 13387 } 13388 13389 synchronized(this) { 13390 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13391 } 13392 } 13393 13394 public IBinder peekService(Intent service, String resolvedType) { 13395 enforceNotIsolatedCaller("peekService"); 13396 // Refuse possible leaked file descriptors 13397 if (service != null && service.hasFileDescriptors() == true) { 13398 throw new IllegalArgumentException("File descriptors passed in Intent"); 13399 } 13400 synchronized(this) { 13401 return mServices.peekServiceLocked(service, resolvedType); 13402 } 13403 } 13404 13405 public boolean stopServiceToken(ComponentName className, IBinder token, 13406 int startId) { 13407 synchronized(this) { 13408 return mServices.stopServiceTokenLocked(className, token, startId); 13409 } 13410 } 13411 13412 public void setServiceForeground(ComponentName className, IBinder token, 13413 int id, Notification notification, boolean removeNotification) { 13414 synchronized(this) { 13415 mServices.setServiceForegroundLocked(className, token, id, notification, 13416 removeNotification); 13417 } 13418 } 13419 13420 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13421 boolean requireFull, String name, String callerPackage) { 13422 final int callingUserId = UserHandle.getUserId(callingUid); 13423 if (callingUserId != userId) { 13424 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13425 if ((requireFull || checkComponentPermission( 13426 android.Manifest.permission.INTERACT_ACROSS_USERS, 13427 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13428 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13429 callingPid, callingUid, -1, true) 13430 != PackageManager.PERMISSION_GRANTED) { 13431 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13432 // In this case, they would like to just execute as their 13433 // owner user instead of failing. 13434 userId = callingUserId; 13435 } else { 13436 StringBuilder builder = new StringBuilder(128); 13437 builder.append("Permission Denial: "); 13438 builder.append(name); 13439 if (callerPackage != null) { 13440 builder.append(" from "); 13441 builder.append(callerPackage); 13442 } 13443 builder.append(" asks to run as user "); 13444 builder.append(userId); 13445 builder.append(" but is calling from user "); 13446 builder.append(UserHandle.getUserId(callingUid)); 13447 builder.append("; this requires "); 13448 builder.append(INTERACT_ACROSS_USERS_FULL); 13449 if (!requireFull) { 13450 builder.append(" or "); 13451 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13452 } 13453 String msg = builder.toString(); 13454 Slog.w(TAG, msg); 13455 throw new SecurityException(msg); 13456 } 13457 } 13458 } 13459 if (userId == UserHandle.USER_CURRENT 13460 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13461 // Note that we may be accessing this outside of a lock... 13462 // shouldn't be a big deal, if this is being called outside 13463 // of a locked context there is intrinsically a race with 13464 // the value the caller will receive and someone else changing it. 13465 userId = mCurrentUserId; 13466 } 13467 if (!allowAll && userId < 0) { 13468 throw new IllegalArgumentException( 13469 "Call does not support special user #" + userId); 13470 } 13471 } 13472 return userId; 13473 } 13474 13475 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13476 String className, int flags) { 13477 boolean result = false; 13478 // For apps that don't have pre-defined UIDs, check for permission 13479 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13480 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13481 if (ActivityManager.checkUidPermission( 13482 android.Manifest.permission.INTERACT_ACROSS_USERS, 13483 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13484 ComponentName comp = new ComponentName(aInfo.packageName, className); 13485 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13486 + " requests FLAG_SINGLE_USER, but app does not hold " 13487 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13488 Slog.w(TAG, msg); 13489 throw new SecurityException(msg); 13490 } 13491 // Permission passed 13492 result = true; 13493 } 13494 } else if ("system".equals(componentProcessName)) { 13495 result = true; 13496 } else { 13497 // App with pre-defined UID, check if it's a persistent app 13498 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13499 } 13500 if (DEBUG_MU) { 13501 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13502 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13503 } 13504 return result; 13505 } 13506 13507 /** 13508 * Checks to see if the caller is in the same app as the singleton 13509 * component, or the component is in a special app. It allows special apps 13510 * to export singleton components but prevents exporting singleton 13511 * components for regular apps. 13512 */ 13513 boolean isValidSingletonCall(int callingUid, int componentUid) { 13514 int componentAppId = UserHandle.getAppId(componentUid); 13515 return UserHandle.isSameApp(callingUid, componentUid) 13516 || componentAppId == Process.SYSTEM_UID 13517 || componentAppId == Process.PHONE_UID 13518 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13519 == PackageManager.PERMISSION_GRANTED; 13520 } 13521 13522 public int bindService(IApplicationThread caller, IBinder token, 13523 Intent service, String resolvedType, 13524 IServiceConnection connection, int flags, int userId) { 13525 enforceNotIsolatedCaller("bindService"); 13526 // Refuse possible leaked file descriptors 13527 if (service != null && service.hasFileDescriptors() == true) { 13528 throw new IllegalArgumentException("File descriptors passed in Intent"); 13529 } 13530 13531 synchronized(this) { 13532 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13533 connection, flags, userId); 13534 } 13535 } 13536 13537 public boolean unbindService(IServiceConnection connection) { 13538 synchronized (this) { 13539 return mServices.unbindServiceLocked(connection); 13540 } 13541 } 13542 13543 public void publishService(IBinder token, Intent intent, IBinder service) { 13544 // Refuse possible leaked file descriptors 13545 if (intent != null && intent.hasFileDescriptors() == true) { 13546 throw new IllegalArgumentException("File descriptors passed in Intent"); 13547 } 13548 13549 synchronized(this) { 13550 if (!(token instanceof ServiceRecord)) { 13551 throw new IllegalArgumentException("Invalid service token"); 13552 } 13553 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13554 } 13555 } 13556 13557 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13558 // Refuse possible leaked file descriptors 13559 if (intent != null && intent.hasFileDescriptors() == true) { 13560 throw new IllegalArgumentException("File descriptors passed in Intent"); 13561 } 13562 13563 synchronized(this) { 13564 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13565 } 13566 } 13567 13568 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13569 synchronized(this) { 13570 if (!(token instanceof ServiceRecord)) { 13571 throw new IllegalArgumentException("Invalid service token"); 13572 } 13573 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13574 } 13575 } 13576 13577 // ========================================================= 13578 // BACKUP AND RESTORE 13579 // ========================================================= 13580 13581 // Cause the target app to be launched if necessary and its backup agent 13582 // instantiated. The backup agent will invoke backupAgentCreated() on the 13583 // activity manager to announce its creation. 13584 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13585 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13586 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13587 13588 synchronized(this) { 13589 // !!! TODO: currently no check here that we're already bound 13590 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13591 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13592 synchronized (stats) { 13593 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13594 } 13595 13596 // Backup agent is now in use, its package can't be stopped. 13597 try { 13598 AppGlobals.getPackageManager().setPackageStoppedState( 13599 app.packageName, false, UserHandle.getUserId(app.uid)); 13600 } catch (RemoteException e) { 13601 } catch (IllegalArgumentException e) { 13602 Slog.w(TAG, "Failed trying to unstop package " 13603 + app.packageName + ": " + e); 13604 } 13605 13606 BackupRecord r = new BackupRecord(ss, app, backupMode); 13607 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13608 ? new ComponentName(app.packageName, app.backupAgentName) 13609 : new ComponentName("android", "FullBackupAgent"); 13610 // startProcessLocked() returns existing proc's record if it's already running 13611 ProcessRecord proc = startProcessLocked(app.processName, app, 13612 false, 0, "backup", hostingName, false, false, false); 13613 if (proc == null) { 13614 Slog.e(TAG, "Unable to start backup agent process " + r); 13615 return false; 13616 } 13617 13618 r.app = proc; 13619 mBackupTarget = r; 13620 mBackupAppName = app.packageName; 13621 13622 // Try not to kill the process during backup 13623 updateOomAdjLocked(proc); 13624 13625 // If the process is already attached, schedule the creation of the backup agent now. 13626 // If it is not yet live, this will be done when it attaches to the framework. 13627 if (proc.thread != null) { 13628 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13629 try { 13630 proc.thread.scheduleCreateBackupAgent(app, 13631 compatibilityInfoForPackageLocked(app), backupMode); 13632 } catch (RemoteException e) { 13633 // Will time out on the backup manager side 13634 } 13635 } else { 13636 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13637 } 13638 // Invariants: at this point, the target app process exists and the application 13639 // is either already running or in the process of coming up. mBackupTarget and 13640 // mBackupAppName describe the app, so that when it binds back to the AM we 13641 // know that it's scheduled for a backup-agent operation. 13642 } 13643 13644 return true; 13645 } 13646 13647 @Override 13648 public void clearPendingBackup() { 13649 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13650 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13651 13652 synchronized (this) { 13653 mBackupTarget = null; 13654 mBackupAppName = null; 13655 } 13656 } 13657 13658 // A backup agent has just come up 13659 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13660 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13661 + " = " + agent); 13662 13663 synchronized(this) { 13664 if (!agentPackageName.equals(mBackupAppName)) { 13665 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13666 return; 13667 } 13668 } 13669 13670 long oldIdent = Binder.clearCallingIdentity(); 13671 try { 13672 IBackupManager bm = IBackupManager.Stub.asInterface( 13673 ServiceManager.getService(Context.BACKUP_SERVICE)); 13674 bm.agentConnected(agentPackageName, agent); 13675 } catch (RemoteException e) { 13676 // can't happen; the backup manager service is local 13677 } catch (Exception e) { 13678 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13679 e.printStackTrace(); 13680 } finally { 13681 Binder.restoreCallingIdentity(oldIdent); 13682 } 13683 } 13684 13685 // done with this agent 13686 public void unbindBackupAgent(ApplicationInfo appInfo) { 13687 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13688 if (appInfo == null) { 13689 Slog.w(TAG, "unbind backup agent for null app"); 13690 return; 13691 } 13692 13693 synchronized(this) { 13694 try { 13695 if (mBackupAppName == null) { 13696 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13697 return; 13698 } 13699 13700 if (!mBackupAppName.equals(appInfo.packageName)) { 13701 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13702 return; 13703 } 13704 13705 // Not backing this app up any more; reset its OOM adjustment 13706 final ProcessRecord proc = mBackupTarget.app; 13707 updateOomAdjLocked(proc); 13708 13709 // If the app crashed during backup, 'thread' will be null here 13710 if (proc.thread != null) { 13711 try { 13712 proc.thread.scheduleDestroyBackupAgent(appInfo, 13713 compatibilityInfoForPackageLocked(appInfo)); 13714 } catch (Exception e) { 13715 Slog.e(TAG, "Exception when unbinding backup agent:"); 13716 e.printStackTrace(); 13717 } 13718 } 13719 } finally { 13720 mBackupTarget = null; 13721 mBackupAppName = null; 13722 } 13723 } 13724 } 13725 // ========================================================= 13726 // BROADCASTS 13727 // ========================================================= 13728 13729 private final List getStickiesLocked(String action, IntentFilter filter, 13730 List cur, int userId) { 13731 final ContentResolver resolver = mContext.getContentResolver(); 13732 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13733 if (stickies == null) { 13734 return cur; 13735 } 13736 final ArrayList<Intent> list = stickies.get(action); 13737 if (list == null) { 13738 return cur; 13739 } 13740 int N = list.size(); 13741 for (int i=0; i<N; i++) { 13742 Intent intent = list.get(i); 13743 if (filter.match(resolver, intent, true, TAG) >= 0) { 13744 if (cur == null) { 13745 cur = new ArrayList<Intent>(); 13746 } 13747 cur.add(intent); 13748 } 13749 } 13750 return cur; 13751 } 13752 13753 boolean isPendingBroadcastProcessLocked(int pid) { 13754 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13755 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13756 } 13757 13758 void skipPendingBroadcastLocked(int pid) { 13759 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13760 for (BroadcastQueue queue : mBroadcastQueues) { 13761 queue.skipPendingBroadcastLocked(pid); 13762 } 13763 } 13764 13765 // The app just attached; send any pending broadcasts that it should receive 13766 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13767 boolean didSomething = false; 13768 for (BroadcastQueue queue : mBroadcastQueues) { 13769 didSomething |= queue.sendPendingBroadcastsLocked(app); 13770 } 13771 return didSomething; 13772 } 13773 13774 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13775 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13776 enforceNotIsolatedCaller("registerReceiver"); 13777 int callingUid; 13778 int callingPid; 13779 synchronized(this) { 13780 ProcessRecord callerApp = null; 13781 if (caller != null) { 13782 callerApp = getRecordForAppLocked(caller); 13783 if (callerApp == null) { 13784 throw new SecurityException( 13785 "Unable to find app for caller " + caller 13786 + " (pid=" + Binder.getCallingPid() 13787 + ") when registering receiver " + receiver); 13788 } 13789 if (callerApp.info.uid != Process.SYSTEM_UID && 13790 !callerApp.pkgList.containsKey(callerPackage) && 13791 !"android".equals(callerPackage)) { 13792 throw new SecurityException("Given caller package " + callerPackage 13793 + " is not running in process " + callerApp); 13794 } 13795 callingUid = callerApp.info.uid; 13796 callingPid = callerApp.pid; 13797 } else { 13798 callerPackage = null; 13799 callingUid = Binder.getCallingUid(); 13800 callingPid = Binder.getCallingPid(); 13801 } 13802 13803 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13804 true, true, "registerReceiver", callerPackage); 13805 13806 List allSticky = null; 13807 13808 // Look for any matching sticky broadcasts... 13809 Iterator actions = filter.actionsIterator(); 13810 if (actions != null) { 13811 while (actions.hasNext()) { 13812 String action = (String)actions.next(); 13813 allSticky = getStickiesLocked(action, filter, allSticky, 13814 UserHandle.USER_ALL); 13815 allSticky = getStickiesLocked(action, filter, allSticky, 13816 UserHandle.getUserId(callingUid)); 13817 } 13818 } else { 13819 allSticky = getStickiesLocked(null, filter, allSticky, 13820 UserHandle.USER_ALL); 13821 allSticky = getStickiesLocked(null, filter, allSticky, 13822 UserHandle.getUserId(callingUid)); 13823 } 13824 13825 // The first sticky in the list is returned directly back to 13826 // the client. 13827 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13828 13829 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13830 + ": " + sticky); 13831 13832 if (receiver == null) { 13833 return sticky; 13834 } 13835 13836 ReceiverList rl 13837 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13838 if (rl == null) { 13839 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13840 userId, receiver); 13841 if (rl.app != null) { 13842 rl.app.receivers.add(rl); 13843 } else { 13844 try { 13845 receiver.asBinder().linkToDeath(rl, 0); 13846 } catch (RemoteException e) { 13847 return sticky; 13848 } 13849 rl.linkedToDeath = true; 13850 } 13851 mRegisteredReceivers.put(receiver.asBinder(), rl); 13852 } else if (rl.uid != callingUid) { 13853 throw new IllegalArgumentException( 13854 "Receiver requested to register for uid " + callingUid 13855 + " was previously registered for uid " + rl.uid); 13856 } else if (rl.pid != callingPid) { 13857 throw new IllegalArgumentException( 13858 "Receiver requested to register for pid " + callingPid 13859 + " was previously registered for pid " + rl.pid); 13860 } else if (rl.userId != userId) { 13861 throw new IllegalArgumentException( 13862 "Receiver requested to register for user " + userId 13863 + " was previously registered for user " + rl.userId); 13864 } 13865 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13866 permission, callingUid, userId); 13867 rl.add(bf); 13868 if (!bf.debugCheck()) { 13869 Slog.w(TAG, "==> For Dynamic broadast"); 13870 } 13871 mReceiverResolver.addFilter(bf); 13872 13873 // Enqueue broadcasts for all existing stickies that match 13874 // this filter. 13875 if (allSticky != null) { 13876 ArrayList receivers = new ArrayList(); 13877 receivers.add(bf); 13878 13879 int N = allSticky.size(); 13880 for (int i=0; i<N; i++) { 13881 Intent intent = (Intent)allSticky.get(i); 13882 BroadcastQueue queue = broadcastQueueForIntent(intent); 13883 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13884 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13885 null, null, false, true, true, -1); 13886 queue.enqueueParallelBroadcastLocked(r); 13887 queue.scheduleBroadcastsLocked(); 13888 } 13889 } 13890 13891 return sticky; 13892 } 13893 } 13894 13895 public void unregisterReceiver(IIntentReceiver receiver) { 13896 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13897 13898 final long origId = Binder.clearCallingIdentity(); 13899 try { 13900 boolean doTrim = false; 13901 13902 synchronized(this) { 13903 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13904 if (rl != null) { 13905 if (rl.curBroadcast != null) { 13906 BroadcastRecord r = rl.curBroadcast; 13907 final boolean doNext = finishReceiverLocked( 13908 receiver.asBinder(), r.resultCode, r.resultData, 13909 r.resultExtras, r.resultAbort); 13910 if (doNext) { 13911 doTrim = true; 13912 r.queue.processNextBroadcast(false); 13913 } 13914 } 13915 13916 if (rl.app != null) { 13917 rl.app.receivers.remove(rl); 13918 } 13919 removeReceiverLocked(rl); 13920 if (rl.linkedToDeath) { 13921 rl.linkedToDeath = false; 13922 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13923 } 13924 } 13925 } 13926 13927 // If we actually concluded any broadcasts, we might now be able 13928 // to trim the recipients' apps from our working set 13929 if (doTrim) { 13930 trimApplications(); 13931 return; 13932 } 13933 13934 } finally { 13935 Binder.restoreCallingIdentity(origId); 13936 } 13937 } 13938 13939 void removeReceiverLocked(ReceiverList rl) { 13940 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13941 int N = rl.size(); 13942 for (int i=0; i<N; i++) { 13943 mReceiverResolver.removeFilter(rl.get(i)); 13944 } 13945 } 13946 13947 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13948 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13949 ProcessRecord r = mLruProcesses.get(i); 13950 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13951 try { 13952 r.thread.dispatchPackageBroadcast(cmd, packages); 13953 } catch (RemoteException ex) { 13954 } 13955 } 13956 } 13957 } 13958 13959 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13960 int[] users) { 13961 List<ResolveInfo> receivers = null; 13962 try { 13963 HashSet<ComponentName> singleUserReceivers = null; 13964 boolean scannedFirstReceivers = false; 13965 for (int user : users) { 13966 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13967 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13968 if (user != 0 && newReceivers != null) { 13969 // If this is not the primary user, we need to check for 13970 // any receivers that should be filtered out. 13971 for (int i=0; i<newReceivers.size(); i++) { 13972 ResolveInfo ri = newReceivers.get(i); 13973 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13974 newReceivers.remove(i); 13975 i--; 13976 } 13977 } 13978 } 13979 if (newReceivers != null && newReceivers.size() == 0) { 13980 newReceivers = null; 13981 } 13982 if (receivers == null) { 13983 receivers = newReceivers; 13984 } else if (newReceivers != null) { 13985 // We need to concatenate the additional receivers 13986 // found with what we have do far. This would be easy, 13987 // but we also need to de-dup any receivers that are 13988 // singleUser. 13989 if (!scannedFirstReceivers) { 13990 // Collect any single user receivers we had already retrieved. 13991 scannedFirstReceivers = true; 13992 for (int i=0; i<receivers.size(); i++) { 13993 ResolveInfo ri = receivers.get(i); 13994 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13995 ComponentName cn = new ComponentName( 13996 ri.activityInfo.packageName, ri.activityInfo.name); 13997 if (singleUserReceivers == null) { 13998 singleUserReceivers = new HashSet<ComponentName>(); 13999 } 14000 singleUserReceivers.add(cn); 14001 } 14002 } 14003 } 14004 // Add the new results to the existing results, tracking 14005 // and de-dupping single user receivers. 14006 for (int i=0; i<newReceivers.size(); i++) { 14007 ResolveInfo ri = newReceivers.get(i); 14008 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14009 ComponentName cn = new ComponentName( 14010 ri.activityInfo.packageName, ri.activityInfo.name); 14011 if (singleUserReceivers == null) { 14012 singleUserReceivers = new HashSet<ComponentName>(); 14013 } 14014 if (!singleUserReceivers.contains(cn)) { 14015 singleUserReceivers.add(cn); 14016 receivers.add(ri); 14017 } 14018 } else { 14019 receivers.add(ri); 14020 } 14021 } 14022 } 14023 } 14024 } catch (RemoteException ex) { 14025 // pm is in same process, this will never happen. 14026 } 14027 return receivers; 14028 } 14029 14030 private final int broadcastIntentLocked(ProcessRecord callerApp, 14031 String callerPackage, Intent intent, String resolvedType, 14032 IIntentReceiver resultTo, int resultCode, String resultData, 14033 Bundle map, String requiredPermission, int appOp, 14034 boolean ordered, boolean sticky, int callingPid, int callingUid, 14035 int userId) { 14036 intent = new Intent(intent); 14037 14038 // By default broadcasts do not go to stopped apps. 14039 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14040 14041 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14042 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14043 + " ordered=" + ordered + " userid=" + userId); 14044 if ((resultTo != null) && !ordered) { 14045 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14046 } 14047 14048 userId = handleIncomingUser(callingPid, callingUid, userId, 14049 true, false, "broadcast", callerPackage); 14050 14051 // Make sure that the user who is receiving this broadcast is started. 14052 // If not, we will just skip it. 14053 14054 14055 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14056 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14057 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14058 Slog.w(TAG, "Skipping broadcast of " + intent 14059 + ": user " + userId + " is stopped"); 14060 return ActivityManager.BROADCAST_SUCCESS; 14061 } 14062 } 14063 14064 /* 14065 * Prevent non-system code (defined here to be non-persistent 14066 * processes) from sending protected broadcasts. 14067 */ 14068 int callingAppId = UserHandle.getAppId(callingUid); 14069 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14070 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14071 || callingAppId == Process.NFC_UID || callingUid == 0) { 14072 // Always okay. 14073 } else if (callerApp == null || !callerApp.persistent) { 14074 try { 14075 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14076 intent.getAction())) { 14077 String msg = "Permission Denial: not allowed to send broadcast " 14078 + intent.getAction() + " from pid=" 14079 + callingPid + ", uid=" + callingUid; 14080 Slog.w(TAG, msg); 14081 throw new SecurityException(msg); 14082 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14083 // Special case for compatibility: we don't want apps to send this, 14084 // but historically it has not been protected and apps may be using it 14085 // to poke their own app widget. So, instead of making it protected, 14086 // just limit it to the caller. 14087 if (callerApp == null) { 14088 String msg = "Permission Denial: not allowed to send broadcast " 14089 + intent.getAction() + " from unknown caller."; 14090 Slog.w(TAG, msg); 14091 throw new SecurityException(msg); 14092 } else if (intent.getComponent() != null) { 14093 // They are good enough to send to an explicit component... verify 14094 // it is being sent to the calling app. 14095 if (!intent.getComponent().getPackageName().equals( 14096 callerApp.info.packageName)) { 14097 String msg = "Permission Denial: not allowed to send broadcast " 14098 + intent.getAction() + " to " 14099 + intent.getComponent().getPackageName() + " from " 14100 + callerApp.info.packageName; 14101 Slog.w(TAG, msg); 14102 throw new SecurityException(msg); 14103 } 14104 } else { 14105 // Limit broadcast to their own package. 14106 intent.setPackage(callerApp.info.packageName); 14107 } 14108 } 14109 } catch (RemoteException e) { 14110 Slog.w(TAG, "Remote exception", e); 14111 return ActivityManager.BROADCAST_SUCCESS; 14112 } 14113 } 14114 14115 // Handle special intents: if this broadcast is from the package 14116 // manager about a package being removed, we need to remove all of 14117 // its activities from the history stack. 14118 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14119 intent.getAction()); 14120 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14121 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14122 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14123 || uidRemoved) { 14124 if (checkComponentPermission( 14125 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14126 callingPid, callingUid, -1, true) 14127 == PackageManager.PERMISSION_GRANTED) { 14128 if (uidRemoved) { 14129 final Bundle intentExtras = intent.getExtras(); 14130 final int uid = intentExtras != null 14131 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14132 if (uid >= 0) { 14133 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14134 synchronized (bs) { 14135 bs.removeUidStatsLocked(uid); 14136 } 14137 mAppOpsService.uidRemoved(uid); 14138 } 14139 } else { 14140 // If resources are unavailable just force stop all 14141 // those packages and flush the attribute cache as well. 14142 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14143 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14144 if (list != null && (list.length > 0)) { 14145 for (String pkg : list) { 14146 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14147 "storage unmount"); 14148 } 14149 sendPackageBroadcastLocked( 14150 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14151 } 14152 } else { 14153 Uri data = intent.getData(); 14154 String ssp; 14155 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14156 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14157 intent.getAction()); 14158 boolean fullUninstall = removed && 14159 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14160 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14161 forceStopPackageLocked(ssp, UserHandle.getAppId( 14162 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14163 false, fullUninstall, userId, 14164 removed ? "pkg removed" : "pkg changed"); 14165 } 14166 if (removed) { 14167 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14168 new String[] {ssp}, userId); 14169 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14170 mAppOpsService.packageRemoved( 14171 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14172 14173 // Remove all permissions granted from/to this package 14174 removeUriPermissionsForPackageLocked(ssp, userId, true); 14175 } 14176 } 14177 } 14178 } 14179 } 14180 } else { 14181 String msg = "Permission Denial: " + intent.getAction() 14182 + " broadcast from " + callerPackage + " (pid=" + callingPid 14183 + ", uid=" + callingUid + ")" 14184 + " requires " 14185 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14186 Slog.w(TAG, msg); 14187 throw new SecurityException(msg); 14188 } 14189 14190 // Special case for adding a package: by default turn on compatibility 14191 // mode. 14192 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14193 Uri data = intent.getData(); 14194 String ssp; 14195 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14196 mCompatModePackages.handlePackageAddedLocked(ssp, 14197 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14198 } 14199 } 14200 14201 /* 14202 * If this is the time zone changed action, queue up a message that will reset the timezone 14203 * of all currently running processes. This message will get queued up before the broadcast 14204 * happens. 14205 */ 14206 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14207 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14208 } 14209 14210 /* 14211 * If the user set the time, let all running processes know. 14212 */ 14213 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14214 final int is24Hour = intent.getBooleanExtra( 14215 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14216 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14217 } 14218 14219 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14220 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14221 } 14222 14223 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14224 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14225 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14226 } 14227 14228 // Add to the sticky list if requested. 14229 if (sticky) { 14230 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14231 callingPid, callingUid) 14232 != PackageManager.PERMISSION_GRANTED) { 14233 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14234 + callingPid + ", uid=" + callingUid 14235 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14236 Slog.w(TAG, msg); 14237 throw new SecurityException(msg); 14238 } 14239 if (requiredPermission != null) { 14240 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14241 + " and enforce permission " + requiredPermission); 14242 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14243 } 14244 if (intent.getComponent() != null) { 14245 throw new SecurityException( 14246 "Sticky broadcasts can't target a specific component"); 14247 } 14248 // We use userId directly here, since the "all" target is maintained 14249 // as a separate set of sticky broadcasts. 14250 if (userId != UserHandle.USER_ALL) { 14251 // But first, if this is not a broadcast to all users, then 14252 // make sure it doesn't conflict with an existing broadcast to 14253 // all users. 14254 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14255 UserHandle.USER_ALL); 14256 if (stickies != null) { 14257 ArrayList<Intent> list = stickies.get(intent.getAction()); 14258 if (list != null) { 14259 int N = list.size(); 14260 int i; 14261 for (i=0; i<N; i++) { 14262 if (intent.filterEquals(list.get(i))) { 14263 throw new IllegalArgumentException( 14264 "Sticky broadcast " + intent + " for user " 14265 + userId + " conflicts with existing global broadcast"); 14266 } 14267 } 14268 } 14269 } 14270 } 14271 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14272 if (stickies == null) { 14273 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14274 mStickyBroadcasts.put(userId, stickies); 14275 } 14276 ArrayList<Intent> list = stickies.get(intent.getAction()); 14277 if (list == null) { 14278 list = new ArrayList<Intent>(); 14279 stickies.put(intent.getAction(), list); 14280 } 14281 int N = list.size(); 14282 int i; 14283 for (i=0; i<N; i++) { 14284 if (intent.filterEquals(list.get(i))) { 14285 // This sticky already exists, replace it. 14286 list.set(i, new Intent(intent)); 14287 break; 14288 } 14289 } 14290 if (i >= N) { 14291 list.add(new Intent(intent)); 14292 } 14293 } 14294 14295 int[] users; 14296 if (userId == UserHandle.USER_ALL) { 14297 // Caller wants broadcast to go to all started users. 14298 users = mStartedUserArray; 14299 } else { 14300 // Caller wants broadcast to go to one specific user. 14301 users = new int[] {userId}; 14302 } 14303 14304 // Figure out who all will receive this broadcast. 14305 List receivers = null; 14306 List<BroadcastFilter> registeredReceivers = null; 14307 // Need to resolve the intent to interested receivers... 14308 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14309 == 0) { 14310 receivers = collectReceiverComponents(intent, resolvedType, users); 14311 } 14312 if (intent.getComponent() == null) { 14313 registeredReceivers = mReceiverResolver.queryIntent(intent, 14314 resolvedType, false, userId); 14315 } 14316 14317 final boolean replacePending = 14318 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14319 14320 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14321 + " replacePending=" + replacePending); 14322 14323 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14324 if (!ordered && NR > 0) { 14325 // If we are not serializing this broadcast, then send the 14326 // registered receivers separately so they don't wait for the 14327 // components to be launched. 14328 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14329 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14330 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14331 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14332 ordered, sticky, false, userId); 14333 if (DEBUG_BROADCAST) Slog.v( 14334 TAG, "Enqueueing parallel broadcast " + r); 14335 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14336 if (!replaced) { 14337 queue.enqueueParallelBroadcastLocked(r); 14338 queue.scheduleBroadcastsLocked(); 14339 } 14340 registeredReceivers = null; 14341 NR = 0; 14342 } 14343 14344 // Merge into one list. 14345 int ir = 0; 14346 if (receivers != null) { 14347 // A special case for PACKAGE_ADDED: do not allow the package 14348 // being added to see this broadcast. This prevents them from 14349 // using this as a back door to get run as soon as they are 14350 // installed. Maybe in the future we want to have a special install 14351 // broadcast or such for apps, but we'd like to deliberately make 14352 // this decision. 14353 String skipPackages[] = null; 14354 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14355 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14356 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14357 Uri data = intent.getData(); 14358 if (data != null) { 14359 String pkgName = data.getSchemeSpecificPart(); 14360 if (pkgName != null) { 14361 skipPackages = new String[] { pkgName }; 14362 } 14363 } 14364 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14365 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14366 } 14367 if (skipPackages != null && (skipPackages.length > 0)) { 14368 for (String skipPackage : skipPackages) { 14369 if (skipPackage != null) { 14370 int NT = receivers.size(); 14371 for (int it=0; it<NT; it++) { 14372 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14373 if (curt.activityInfo.packageName.equals(skipPackage)) { 14374 receivers.remove(it); 14375 it--; 14376 NT--; 14377 } 14378 } 14379 } 14380 } 14381 } 14382 14383 int NT = receivers != null ? receivers.size() : 0; 14384 int it = 0; 14385 ResolveInfo curt = null; 14386 BroadcastFilter curr = null; 14387 while (it < NT && ir < NR) { 14388 if (curt == null) { 14389 curt = (ResolveInfo)receivers.get(it); 14390 } 14391 if (curr == null) { 14392 curr = registeredReceivers.get(ir); 14393 } 14394 if (curr.getPriority() >= curt.priority) { 14395 // Insert this broadcast record into the final list. 14396 receivers.add(it, curr); 14397 ir++; 14398 curr = null; 14399 it++; 14400 NT++; 14401 } else { 14402 // Skip to the next ResolveInfo in the final list. 14403 it++; 14404 curt = null; 14405 } 14406 } 14407 } 14408 while (ir < NR) { 14409 if (receivers == null) { 14410 receivers = new ArrayList(); 14411 } 14412 receivers.add(registeredReceivers.get(ir)); 14413 ir++; 14414 } 14415 14416 if ((receivers != null && receivers.size() > 0) 14417 || resultTo != null) { 14418 BroadcastQueue queue = broadcastQueueForIntent(intent); 14419 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14420 callerPackage, callingPid, callingUid, resolvedType, 14421 requiredPermission, appOp, receivers, resultTo, resultCode, 14422 resultData, map, ordered, sticky, false, userId); 14423 if (DEBUG_BROADCAST) Slog.v( 14424 TAG, "Enqueueing ordered broadcast " + r 14425 + ": prev had " + queue.mOrderedBroadcasts.size()); 14426 if (DEBUG_BROADCAST) { 14427 int seq = r.intent.getIntExtra("seq", -1); 14428 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14429 } 14430 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14431 if (!replaced) { 14432 queue.enqueueOrderedBroadcastLocked(r); 14433 queue.scheduleBroadcastsLocked(); 14434 } 14435 } 14436 14437 return ActivityManager.BROADCAST_SUCCESS; 14438 } 14439 14440 final Intent verifyBroadcastLocked(Intent intent) { 14441 // Refuse possible leaked file descriptors 14442 if (intent != null && intent.hasFileDescriptors() == true) { 14443 throw new IllegalArgumentException("File descriptors passed in Intent"); 14444 } 14445 14446 int flags = intent.getFlags(); 14447 14448 if (!mProcessesReady) { 14449 // if the caller really truly claims to know what they're doing, go 14450 // ahead and allow the broadcast without launching any receivers 14451 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14452 intent = new Intent(intent); 14453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14454 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14455 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14456 + " before boot completion"); 14457 throw new IllegalStateException("Cannot broadcast before boot completed"); 14458 } 14459 } 14460 14461 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14462 throw new IllegalArgumentException( 14463 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14464 } 14465 14466 return intent; 14467 } 14468 14469 public final int broadcastIntent(IApplicationThread caller, 14470 Intent intent, String resolvedType, IIntentReceiver resultTo, 14471 int resultCode, String resultData, Bundle map, 14472 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14473 enforceNotIsolatedCaller("broadcastIntent"); 14474 synchronized(this) { 14475 intent = verifyBroadcastLocked(intent); 14476 14477 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14478 final int callingPid = Binder.getCallingPid(); 14479 final int callingUid = Binder.getCallingUid(); 14480 final long origId = Binder.clearCallingIdentity(); 14481 int res = broadcastIntentLocked(callerApp, 14482 callerApp != null ? callerApp.info.packageName : null, 14483 intent, resolvedType, resultTo, 14484 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14485 callingPid, callingUid, userId); 14486 Binder.restoreCallingIdentity(origId); 14487 return res; 14488 } 14489 } 14490 14491 int broadcastIntentInPackage(String packageName, int uid, 14492 Intent intent, String resolvedType, IIntentReceiver resultTo, 14493 int resultCode, String resultData, Bundle map, 14494 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14495 synchronized(this) { 14496 intent = verifyBroadcastLocked(intent); 14497 14498 final long origId = Binder.clearCallingIdentity(); 14499 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14500 resultTo, resultCode, resultData, map, requiredPermission, 14501 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14502 Binder.restoreCallingIdentity(origId); 14503 return res; 14504 } 14505 } 14506 14507 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14508 // Refuse possible leaked file descriptors 14509 if (intent != null && intent.hasFileDescriptors() == true) { 14510 throw new IllegalArgumentException("File descriptors passed in Intent"); 14511 } 14512 14513 userId = handleIncomingUser(Binder.getCallingPid(), 14514 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14515 14516 synchronized(this) { 14517 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14518 != PackageManager.PERMISSION_GRANTED) { 14519 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14520 + Binder.getCallingPid() 14521 + ", uid=" + Binder.getCallingUid() 14522 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14523 Slog.w(TAG, msg); 14524 throw new SecurityException(msg); 14525 } 14526 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14527 if (stickies != null) { 14528 ArrayList<Intent> list = stickies.get(intent.getAction()); 14529 if (list != null) { 14530 int N = list.size(); 14531 int i; 14532 for (i=0; i<N; i++) { 14533 if (intent.filterEquals(list.get(i))) { 14534 list.remove(i); 14535 break; 14536 } 14537 } 14538 if (list.size() <= 0) { 14539 stickies.remove(intent.getAction()); 14540 } 14541 } 14542 if (stickies.size() <= 0) { 14543 mStickyBroadcasts.remove(userId); 14544 } 14545 } 14546 } 14547 } 14548 14549 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14550 String resultData, Bundle resultExtras, boolean resultAbort) { 14551 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14552 if (r == null) { 14553 Slog.w(TAG, "finishReceiver called but not found on queue"); 14554 return false; 14555 } 14556 14557 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14558 } 14559 14560 void backgroundServicesFinishedLocked(int userId) { 14561 for (BroadcastQueue queue : mBroadcastQueues) { 14562 queue.backgroundServicesFinishedLocked(userId); 14563 } 14564 } 14565 14566 public void finishReceiver(IBinder who, int resultCode, String resultData, 14567 Bundle resultExtras, boolean resultAbort) { 14568 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14569 14570 // Refuse possible leaked file descriptors 14571 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14572 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14573 } 14574 14575 final long origId = Binder.clearCallingIdentity(); 14576 try { 14577 boolean doNext = false; 14578 BroadcastRecord r; 14579 14580 synchronized(this) { 14581 r = broadcastRecordForReceiverLocked(who); 14582 if (r != null) { 14583 doNext = r.queue.finishReceiverLocked(r, resultCode, 14584 resultData, resultExtras, resultAbort, true); 14585 } 14586 } 14587 14588 if (doNext) { 14589 r.queue.processNextBroadcast(false); 14590 } 14591 trimApplications(); 14592 } finally { 14593 Binder.restoreCallingIdentity(origId); 14594 } 14595 } 14596 14597 // ========================================================= 14598 // INSTRUMENTATION 14599 // ========================================================= 14600 14601 public boolean startInstrumentation(ComponentName className, 14602 String profileFile, int flags, Bundle arguments, 14603 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14604 int userId, String abiOverride) { 14605 enforceNotIsolatedCaller("startInstrumentation"); 14606 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14607 userId, false, true, "startInstrumentation", null); 14608 // Refuse possible leaked file descriptors 14609 if (arguments != null && arguments.hasFileDescriptors()) { 14610 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14611 } 14612 14613 synchronized(this) { 14614 InstrumentationInfo ii = null; 14615 ApplicationInfo ai = null; 14616 try { 14617 ii = mContext.getPackageManager().getInstrumentationInfo( 14618 className, STOCK_PM_FLAGS); 14619 ai = AppGlobals.getPackageManager().getApplicationInfo( 14620 ii.targetPackage, STOCK_PM_FLAGS, userId); 14621 } catch (PackageManager.NameNotFoundException e) { 14622 } catch (RemoteException e) { 14623 } 14624 if (ii == null) { 14625 reportStartInstrumentationFailure(watcher, className, 14626 "Unable to find instrumentation info for: " + className); 14627 return false; 14628 } 14629 if (ai == null) { 14630 reportStartInstrumentationFailure(watcher, className, 14631 "Unable to find instrumentation target package: " + ii.targetPackage); 14632 return false; 14633 } 14634 14635 int match = mContext.getPackageManager().checkSignatures( 14636 ii.targetPackage, ii.packageName); 14637 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14638 String msg = "Permission Denial: starting instrumentation " 14639 + className + " from pid=" 14640 + Binder.getCallingPid() 14641 + ", uid=" + Binder.getCallingPid() 14642 + " not allowed because package " + ii.packageName 14643 + " does not have a signature matching the target " 14644 + ii.targetPackage; 14645 reportStartInstrumentationFailure(watcher, className, msg); 14646 throw new SecurityException(msg); 14647 } 14648 14649 final long origId = Binder.clearCallingIdentity(); 14650 // Instrumentation can kill and relaunch even persistent processes 14651 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14652 "start instr"); 14653 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14654 app.instrumentationClass = className; 14655 app.instrumentationInfo = ai; 14656 app.instrumentationProfileFile = profileFile; 14657 app.instrumentationArguments = arguments; 14658 app.instrumentationWatcher = watcher; 14659 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14660 app.instrumentationResultClass = className; 14661 Binder.restoreCallingIdentity(origId); 14662 } 14663 14664 return true; 14665 } 14666 14667 /** 14668 * Report errors that occur while attempting to start Instrumentation. Always writes the 14669 * error to the logs, but if somebody is watching, send the report there too. This enables 14670 * the "am" command to report errors with more information. 14671 * 14672 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14673 * @param cn The component name of the instrumentation. 14674 * @param report The error report. 14675 */ 14676 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14677 ComponentName cn, String report) { 14678 Slog.w(TAG, report); 14679 try { 14680 if (watcher != null) { 14681 Bundle results = new Bundle(); 14682 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14683 results.putString("Error", report); 14684 watcher.instrumentationStatus(cn, -1, results); 14685 } 14686 } catch (RemoteException e) { 14687 Slog.w(TAG, e); 14688 } 14689 } 14690 14691 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14692 if (app.instrumentationWatcher != null) { 14693 try { 14694 // NOTE: IInstrumentationWatcher *must* be oneway here 14695 app.instrumentationWatcher.instrumentationFinished( 14696 app.instrumentationClass, 14697 resultCode, 14698 results); 14699 } catch (RemoteException e) { 14700 } 14701 } 14702 if (app.instrumentationUiAutomationConnection != null) { 14703 try { 14704 app.instrumentationUiAutomationConnection.shutdown(); 14705 } catch (RemoteException re) { 14706 /* ignore */ 14707 } 14708 // Only a UiAutomation can set this flag and now that 14709 // it is finished we make sure it is reset to its default. 14710 mUserIsMonkey = false; 14711 } 14712 app.instrumentationWatcher = null; 14713 app.instrumentationUiAutomationConnection = null; 14714 app.instrumentationClass = null; 14715 app.instrumentationInfo = null; 14716 app.instrumentationProfileFile = null; 14717 app.instrumentationArguments = null; 14718 14719 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14720 "finished inst"); 14721 } 14722 14723 public void finishInstrumentation(IApplicationThread target, 14724 int resultCode, Bundle results) { 14725 int userId = UserHandle.getCallingUserId(); 14726 // Refuse possible leaked file descriptors 14727 if (results != null && results.hasFileDescriptors()) { 14728 throw new IllegalArgumentException("File descriptors passed in Intent"); 14729 } 14730 14731 synchronized(this) { 14732 ProcessRecord app = getRecordForAppLocked(target); 14733 if (app == null) { 14734 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14735 return; 14736 } 14737 final long origId = Binder.clearCallingIdentity(); 14738 finishInstrumentationLocked(app, resultCode, results); 14739 Binder.restoreCallingIdentity(origId); 14740 } 14741 } 14742 14743 // ========================================================= 14744 // CONFIGURATION 14745 // ========================================================= 14746 14747 public ConfigurationInfo getDeviceConfigurationInfo() { 14748 ConfigurationInfo config = new ConfigurationInfo(); 14749 synchronized (this) { 14750 config.reqTouchScreen = mConfiguration.touchscreen; 14751 config.reqKeyboardType = mConfiguration.keyboard; 14752 config.reqNavigation = mConfiguration.navigation; 14753 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14754 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14755 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14756 } 14757 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14758 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14759 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14760 } 14761 config.reqGlEsVersion = GL_ES_VERSION; 14762 } 14763 return config; 14764 } 14765 14766 ActivityStack getFocusedStack() { 14767 return mStackSupervisor.getFocusedStack(); 14768 } 14769 14770 public Configuration getConfiguration() { 14771 Configuration ci; 14772 synchronized(this) { 14773 ci = new Configuration(mConfiguration); 14774 } 14775 return ci; 14776 } 14777 14778 public void updatePersistentConfiguration(Configuration values) { 14779 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14780 "updateConfiguration()"); 14781 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14782 "updateConfiguration()"); 14783 if (values == null) { 14784 throw new NullPointerException("Configuration must not be null"); 14785 } 14786 14787 synchronized(this) { 14788 final long origId = Binder.clearCallingIdentity(); 14789 updateConfigurationLocked(values, null, true, false); 14790 Binder.restoreCallingIdentity(origId); 14791 } 14792 } 14793 14794 public void updateConfiguration(Configuration values) { 14795 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14796 "updateConfiguration()"); 14797 14798 synchronized(this) { 14799 if (values == null && mWindowManager != null) { 14800 // sentinel: fetch the current configuration from the window manager 14801 values = mWindowManager.computeNewConfiguration(); 14802 } 14803 14804 if (mWindowManager != null) { 14805 mProcessList.applyDisplaySize(mWindowManager); 14806 } 14807 14808 final long origId = Binder.clearCallingIdentity(); 14809 if (values != null) { 14810 Settings.System.clearConfiguration(values); 14811 } 14812 updateConfigurationLocked(values, null, false, false); 14813 Binder.restoreCallingIdentity(origId); 14814 } 14815 } 14816 14817 /** 14818 * Do either or both things: (1) change the current configuration, and (2) 14819 * make sure the given activity is running with the (now) current 14820 * configuration. Returns true if the activity has been left running, or 14821 * false if <var>starting</var> is being destroyed to match the new 14822 * configuration. 14823 * @param persistent TODO 14824 */ 14825 boolean updateConfigurationLocked(Configuration values, 14826 ActivityRecord starting, boolean persistent, boolean initLocale) { 14827 int changes = 0; 14828 14829 if (values != null) { 14830 Configuration newConfig = new Configuration(mConfiguration); 14831 changes = newConfig.updateFrom(values); 14832 if (changes != 0) { 14833 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14834 Slog.i(TAG, "Updating configuration to: " + values); 14835 } 14836 14837 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14838 14839 if (values.locale != null && !initLocale) { 14840 saveLocaleLocked(values.locale, 14841 !values.locale.equals(mConfiguration.locale), 14842 values.userSetLocale); 14843 } 14844 14845 mConfigurationSeq++; 14846 if (mConfigurationSeq <= 0) { 14847 mConfigurationSeq = 1; 14848 } 14849 newConfig.seq = mConfigurationSeq; 14850 mConfiguration = newConfig; 14851 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14852 mUsageStatsService.noteStartConfig(newConfig); 14853 14854 final Configuration configCopy = new Configuration(mConfiguration); 14855 14856 // TODO: If our config changes, should we auto dismiss any currently 14857 // showing dialogs? 14858 mShowDialogs = shouldShowDialogs(newConfig); 14859 14860 AttributeCache ac = AttributeCache.instance(); 14861 if (ac != null) { 14862 ac.updateConfiguration(configCopy); 14863 } 14864 14865 // Make sure all resources in our process are updated 14866 // right now, so that anyone who is going to retrieve 14867 // resource values after we return will be sure to get 14868 // the new ones. This is especially important during 14869 // boot, where the first config change needs to guarantee 14870 // all resources have that config before following boot 14871 // code is executed. 14872 mSystemThread.applyConfigurationToResources(configCopy); 14873 14874 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14875 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14876 msg.obj = new Configuration(configCopy); 14877 mHandler.sendMessage(msg); 14878 } 14879 14880 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14881 ProcessRecord app = mLruProcesses.get(i); 14882 try { 14883 if (app.thread != null) { 14884 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14885 + app.processName + " new config " + mConfiguration); 14886 app.thread.scheduleConfigurationChanged(configCopy); 14887 } 14888 } catch (Exception e) { 14889 } 14890 } 14891 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14892 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14893 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14894 | Intent.FLAG_RECEIVER_FOREGROUND); 14895 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14896 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14897 Process.SYSTEM_UID, UserHandle.USER_ALL); 14898 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14899 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14900 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14901 broadcastIntentLocked(null, null, intent, 14902 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14903 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14904 } 14905 } 14906 } 14907 14908 boolean kept = true; 14909 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14910 // mainStack is null during startup. 14911 if (mainStack != null) { 14912 if (changes != 0 && starting == null) { 14913 // If the configuration changed, and the caller is not already 14914 // in the process of starting an activity, then find the top 14915 // activity to check if its configuration needs to change. 14916 starting = mainStack.topRunningActivityLocked(null); 14917 } 14918 14919 if (starting != null) { 14920 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14921 // And we need to make sure at this point that all other activities 14922 // are made visible with the correct configuration. 14923 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14924 } 14925 } 14926 14927 if (values != null && mWindowManager != null) { 14928 mWindowManager.setNewConfiguration(mConfiguration); 14929 } 14930 14931 return kept; 14932 } 14933 14934 /** 14935 * Decide based on the configuration whether we should shouw the ANR, 14936 * crash, etc dialogs. The idea is that if there is no affordnace to 14937 * press the on-screen buttons, we shouldn't show the dialog. 14938 * 14939 * A thought: SystemUI might also want to get told about this, the Power 14940 * dialog / global actions also might want different behaviors. 14941 */ 14942 private static final boolean shouldShowDialogs(Configuration config) { 14943 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14944 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14945 } 14946 14947 /** 14948 * Save the locale. You must be inside a synchronized (this) block. 14949 */ 14950 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14951 if(isDiff) { 14952 SystemProperties.set("user.language", l.getLanguage()); 14953 SystemProperties.set("user.region", l.getCountry()); 14954 } 14955 14956 if(isPersist) { 14957 SystemProperties.set("persist.sys.language", l.getLanguage()); 14958 SystemProperties.set("persist.sys.country", l.getCountry()); 14959 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14960 } 14961 } 14962 14963 @Override 14964 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14965 ActivityRecord srec = ActivityRecord.forToken(token); 14966 return srec != null && srec.task.affinity != null && 14967 srec.task.affinity.equals(destAffinity); 14968 } 14969 14970 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14971 Intent resultData) { 14972 14973 synchronized (this) { 14974 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14975 if (stack != null) { 14976 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14977 } 14978 return false; 14979 } 14980 } 14981 14982 public int getLaunchedFromUid(IBinder activityToken) { 14983 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14984 if (srec == null) { 14985 return -1; 14986 } 14987 return srec.launchedFromUid; 14988 } 14989 14990 public String getLaunchedFromPackage(IBinder activityToken) { 14991 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14992 if (srec == null) { 14993 return null; 14994 } 14995 return srec.launchedFromPackage; 14996 } 14997 14998 // ========================================================= 14999 // LIFETIME MANAGEMENT 15000 // ========================================================= 15001 15002 // Returns which broadcast queue the app is the current [or imminent] receiver 15003 // on, or 'null' if the app is not an active broadcast recipient. 15004 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15005 BroadcastRecord r = app.curReceiver; 15006 if (r != null) { 15007 return r.queue; 15008 } 15009 15010 // It's not the current receiver, but it might be starting up to become one 15011 synchronized (this) { 15012 for (BroadcastQueue queue : mBroadcastQueues) { 15013 r = queue.mPendingBroadcast; 15014 if (r != null && r.curApp == app) { 15015 // found it; report which queue it's in 15016 return queue; 15017 } 15018 } 15019 } 15020 15021 return null; 15022 } 15023 15024 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15025 boolean doingAll, long now) { 15026 if (mAdjSeq == app.adjSeq) { 15027 // This adjustment has already been computed. 15028 return app.curRawAdj; 15029 } 15030 15031 if (app.thread == null) { 15032 app.adjSeq = mAdjSeq; 15033 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15034 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15035 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15036 } 15037 15038 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15039 app.adjSource = null; 15040 app.adjTarget = null; 15041 app.empty = false; 15042 app.cached = false; 15043 15044 final int activitiesSize = app.activities.size(); 15045 15046 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15047 // The max adjustment doesn't allow this app to be anything 15048 // below foreground, so it is not worth doing work for it. 15049 app.adjType = "fixed"; 15050 app.adjSeq = mAdjSeq; 15051 app.curRawAdj = app.maxAdj; 15052 app.foregroundActivities = false; 15053 app.keeping = true; 15054 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15055 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15056 // System processes can do UI, and when they do we want to have 15057 // them trim their memory after the user leaves the UI. To 15058 // facilitate this, here we need to determine whether or not it 15059 // is currently showing UI. 15060 app.systemNoUi = true; 15061 if (app == TOP_APP) { 15062 app.systemNoUi = false; 15063 } else if (activitiesSize > 0) { 15064 for (int j = 0; j < activitiesSize; j++) { 15065 final ActivityRecord r = app.activities.get(j); 15066 if (r.visible) { 15067 app.systemNoUi = false; 15068 } 15069 } 15070 } 15071 if (!app.systemNoUi) { 15072 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15073 } 15074 return (app.curAdj=app.maxAdj); 15075 } 15076 15077 app.keeping = false; 15078 app.systemNoUi = false; 15079 15080 // Determine the importance of the process, starting with most 15081 // important to least, and assign an appropriate OOM adjustment. 15082 int adj; 15083 int schedGroup; 15084 int procState; 15085 boolean foregroundActivities = false; 15086 BroadcastQueue queue; 15087 if (app == TOP_APP) { 15088 // The last app on the list is the foreground app. 15089 adj = ProcessList.FOREGROUND_APP_ADJ; 15090 schedGroup = Process.THREAD_GROUP_DEFAULT; 15091 app.adjType = "top-activity"; 15092 foregroundActivities = true; 15093 procState = ActivityManager.PROCESS_STATE_TOP; 15094 } else if (app.instrumentationClass != null) { 15095 // Don't want to kill running instrumentation. 15096 adj = ProcessList.FOREGROUND_APP_ADJ; 15097 schedGroup = Process.THREAD_GROUP_DEFAULT; 15098 app.adjType = "instrumentation"; 15099 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15100 } else if ((queue = isReceivingBroadcast(app)) != null) { 15101 // An app that is currently receiving a broadcast also 15102 // counts as being in the foreground for OOM killer purposes. 15103 // It's placed in a sched group based on the nature of the 15104 // broadcast as reflected by which queue it's active in. 15105 adj = ProcessList.FOREGROUND_APP_ADJ; 15106 schedGroup = (queue == mFgBroadcastQueue) 15107 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15108 app.adjType = "broadcast"; 15109 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15110 } else if (app.executingServices.size() > 0) { 15111 // An app that is currently executing a service callback also 15112 // counts as being in the foreground. 15113 adj = ProcessList.FOREGROUND_APP_ADJ; 15114 schedGroup = app.execServicesFg ? 15115 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15116 app.adjType = "exec-service"; 15117 procState = ActivityManager.PROCESS_STATE_SERVICE; 15118 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15119 } else { 15120 // As far as we know the process is empty. We may change our mind later. 15121 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15122 // At this point we don't actually know the adjustment. Use the cached adj 15123 // value that the caller wants us to. 15124 adj = cachedAdj; 15125 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15126 app.cached = true; 15127 app.empty = true; 15128 app.adjType = "cch-empty"; 15129 } 15130 15131 // Examine all activities if not already foreground. 15132 if (!foregroundActivities && activitiesSize > 0) { 15133 for (int j = 0; j < activitiesSize; j++) { 15134 final ActivityRecord r = app.activities.get(j); 15135 if (r.app != app) { 15136 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15137 + app + "?!?"); 15138 continue; 15139 } 15140 if (r.visible) { 15141 // App has a visible activity; only upgrade adjustment. 15142 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15143 adj = ProcessList.VISIBLE_APP_ADJ; 15144 app.adjType = "visible"; 15145 } 15146 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15147 procState = ActivityManager.PROCESS_STATE_TOP; 15148 } 15149 schedGroup = Process.THREAD_GROUP_DEFAULT; 15150 app.cached = false; 15151 app.empty = false; 15152 foregroundActivities = true; 15153 break; 15154 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15155 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15156 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15157 app.adjType = "pausing"; 15158 } 15159 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15160 procState = ActivityManager.PROCESS_STATE_TOP; 15161 } 15162 schedGroup = Process.THREAD_GROUP_DEFAULT; 15163 app.cached = false; 15164 app.empty = false; 15165 foregroundActivities = true; 15166 } else if (r.state == ActivityState.STOPPING) { 15167 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15168 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15169 app.adjType = "stopping"; 15170 } 15171 // For the process state, we will at this point consider the 15172 // process to be cached. It will be cached either as an activity 15173 // or empty depending on whether the activity is finishing. We do 15174 // this so that we can treat the process as cached for purposes of 15175 // memory trimming (determing current memory level, trim command to 15176 // send to process) since there can be an arbitrary number of stopping 15177 // processes and they should soon all go into the cached state. 15178 if (!r.finishing) { 15179 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15180 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15181 } 15182 } 15183 app.cached = false; 15184 app.empty = false; 15185 foregroundActivities = true; 15186 } else { 15187 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15188 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15189 app.adjType = "cch-act"; 15190 } 15191 } 15192 } 15193 } 15194 15195 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15196 if (app.foregroundServices) { 15197 // The user is aware of this app, so make it visible. 15198 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15199 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15200 app.cached = false; 15201 app.adjType = "fg-service"; 15202 schedGroup = Process.THREAD_GROUP_DEFAULT; 15203 } else if (app.forcingToForeground != null) { 15204 // The user is aware of this app, so make it visible. 15205 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15206 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15207 app.cached = false; 15208 app.adjType = "force-fg"; 15209 app.adjSource = app.forcingToForeground; 15210 schedGroup = Process.THREAD_GROUP_DEFAULT; 15211 } 15212 } 15213 15214 if (app == mHeavyWeightProcess) { 15215 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15216 // We don't want to kill the current heavy-weight process. 15217 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15218 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15219 app.cached = false; 15220 app.adjType = "heavy"; 15221 } 15222 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15223 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15224 } 15225 } 15226 15227 if (app == mHomeProcess) { 15228 if (adj > ProcessList.HOME_APP_ADJ) { 15229 // This process is hosting what we currently consider to be the 15230 // home app, so we don't want to let it go into the background. 15231 adj = ProcessList.HOME_APP_ADJ; 15232 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15233 app.cached = false; 15234 app.adjType = "home"; 15235 } 15236 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15237 procState = ActivityManager.PROCESS_STATE_HOME; 15238 } 15239 } 15240 15241 if (app == mPreviousProcess && app.activities.size() > 0) { 15242 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15243 // This was the previous process that showed UI to the user. 15244 // We want to try to keep it around more aggressively, to give 15245 // a good experience around switching between two apps. 15246 adj = ProcessList.PREVIOUS_APP_ADJ; 15247 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15248 app.cached = false; 15249 app.adjType = "previous"; 15250 } 15251 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15252 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15253 } 15254 } 15255 15256 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15257 + " reason=" + app.adjType); 15258 15259 // By default, we use the computed adjustment. It may be changed if 15260 // there are applications dependent on our services or providers, but 15261 // this gives us a baseline and makes sure we don't get into an 15262 // infinite recursion. 15263 app.adjSeq = mAdjSeq; 15264 app.curRawAdj = adj; 15265 app.hasStartedServices = false; 15266 15267 if (mBackupTarget != null && app == mBackupTarget.app) { 15268 // If possible we want to avoid killing apps while they're being backed up 15269 if (adj > ProcessList.BACKUP_APP_ADJ) { 15270 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15271 adj = ProcessList.BACKUP_APP_ADJ; 15272 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15273 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15274 } 15275 app.adjType = "backup"; 15276 app.cached = false; 15277 } 15278 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15279 procState = ActivityManager.PROCESS_STATE_BACKUP; 15280 } 15281 } 15282 15283 boolean mayBeTop = false; 15284 15285 for (int is = app.services.size()-1; 15286 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15287 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15288 || procState > ActivityManager.PROCESS_STATE_TOP); 15289 is--) { 15290 ServiceRecord s = app.services.valueAt(is); 15291 if (s.startRequested) { 15292 app.hasStartedServices = true; 15293 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15294 procState = ActivityManager.PROCESS_STATE_SERVICE; 15295 } 15296 if (app.hasShownUi && app != mHomeProcess) { 15297 // If this process has shown some UI, let it immediately 15298 // go to the LRU list because it may be pretty heavy with 15299 // UI stuff. We'll tag it with a label just to help 15300 // debug and understand what is going on. 15301 if (adj > ProcessList.SERVICE_ADJ) { 15302 app.adjType = "cch-started-ui-services"; 15303 } 15304 } else { 15305 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15306 // This service has seen some activity within 15307 // recent memory, so we will keep its process ahead 15308 // of the background processes. 15309 if (adj > ProcessList.SERVICE_ADJ) { 15310 adj = ProcessList.SERVICE_ADJ; 15311 app.adjType = "started-services"; 15312 app.cached = false; 15313 } 15314 } 15315 // If we have let the service slide into the background 15316 // state, still have some text describing what it is doing 15317 // even though the service no longer has an impact. 15318 if (adj > ProcessList.SERVICE_ADJ) { 15319 app.adjType = "cch-started-services"; 15320 } 15321 } 15322 // Don't kill this process because it is doing work; it 15323 // has said it is doing work. 15324 app.keeping = true; 15325 } 15326 for (int conni = s.connections.size()-1; 15327 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15328 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15329 || procState > ActivityManager.PROCESS_STATE_TOP); 15330 conni--) { 15331 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15332 for (int i = 0; 15333 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15334 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15335 || procState > ActivityManager.PROCESS_STATE_TOP); 15336 i++) { 15337 // XXX should compute this based on the max of 15338 // all connected clients. 15339 ConnectionRecord cr = clist.get(i); 15340 if (cr.binding.client == app) { 15341 // Binding to ourself is not interesting. 15342 continue; 15343 } 15344 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15345 ProcessRecord client = cr.binding.client; 15346 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15347 TOP_APP, doingAll, now); 15348 int clientProcState = client.curProcState; 15349 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15350 // If the other app is cached for any reason, for purposes here 15351 // we are going to consider it empty. The specific cached state 15352 // doesn't propagate except under certain conditions. 15353 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15354 } 15355 String adjType = null; 15356 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15357 // Not doing bind OOM management, so treat 15358 // this guy more like a started service. 15359 if (app.hasShownUi && app != mHomeProcess) { 15360 // If this process has shown some UI, let it immediately 15361 // go to the LRU list because it may be pretty heavy with 15362 // UI stuff. We'll tag it with a label just to help 15363 // debug and understand what is going on. 15364 if (adj > clientAdj) { 15365 adjType = "cch-bound-ui-services"; 15366 } 15367 app.cached = false; 15368 clientAdj = adj; 15369 clientProcState = procState; 15370 } else { 15371 if (now >= (s.lastActivity 15372 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15373 // This service has not seen activity within 15374 // recent memory, so allow it to drop to the 15375 // LRU list if there is no other reason to keep 15376 // it around. We'll also tag it with a label just 15377 // to help debug and undertand what is going on. 15378 if (adj > clientAdj) { 15379 adjType = "cch-bound-services"; 15380 } 15381 clientAdj = adj; 15382 } 15383 } 15384 } 15385 if (adj > clientAdj) { 15386 // If this process has recently shown UI, and 15387 // the process that is binding to it is less 15388 // important than being visible, then we don't 15389 // care about the binding as much as we care 15390 // about letting this process get into the LRU 15391 // list to be killed and restarted if needed for 15392 // memory. 15393 if (app.hasShownUi && app != mHomeProcess 15394 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15395 adjType = "cch-bound-ui-services"; 15396 } else { 15397 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15398 |Context.BIND_IMPORTANT)) != 0) { 15399 adj = clientAdj; 15400 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15401 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15402 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15403 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15404 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15405 adj = clientAdj; 15406 } else { 15407 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15408 adj = ProcessList.VISIBLE_APP_ADJ; 15409 } 15410 } 15411 if (!client.cached) { 15412 app.cached = false; 15413 } 15414 if (client.keeping) { 15415 app.keeping = true; 15416 } 15417 adjType = "service"; 15418 } 15419 } 15420 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15421 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15422 schedGroup = Process.THREAD_GROUP_DEFAULT; 15423 } 15424 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15425 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15426 // Special handling of clients who are in the top state. 15427 // We *may* want to consider this process to be in the 15428 // top state as well, but only if there is not another 15429 // reason for it to be running. Being on the top is a 15430 // special state, meaning you are specifically running 15431 // for the current top app. If the process is already 15432 // running in the background for some other reason, it 15433 // is more important to continue considering it to be 15434 // in the background state. 15435 mayBeTop = true; 15436 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15437 } else { 15438 // Special handling for above-top states (persistent 15439 // processes). These should not bring the current process 15440 // into the top state, since they are not on top. Instead 15441 // give them the best state after that. 15442 clientProcState = 15443 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15444 } 15445 } 15446 } else { 15447 if (clientProcState < 15448 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15449 clientProcState = 15450 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15451 } 15452 } 15453 if (procState > clientProcState) { 15454 procState = clientProcState; 15455 } 15456 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15457 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15458 app.pendingUiClean = true; 15459 } 15460 if (adjType != null) { 15461 app.adjType = adjType; 15462 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15463 .REASON_SERVICE_IN_USE; 15464 app.adjSource = cr.binding.client; 15465 app.adjSourceOom = clientAdj; 15466 app.adjTarget = s.name; 15467 } 15468 } 15469 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15470 app.treatLikeActivity = true; 15471 } 15472 final ActivityRecord a = cr.activity; 15473 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15474 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15475 (a.visible || a.state == ActivityState.RESUMED 15476 || a.state == ActivityState.PAUSING)) { 15477 adj = ProcessList.FOREGROUND_APP_ADJ; 15478 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15479 schedGroup = Process.THREAD_GROUP_DEFAULT; 15480 } 15481 app.cached = false; 15482 app.adjType = "service"; 15483 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15484 .REASON_SERVICE_IN_USE; 15485 app.adjSource = a; 15486 app.adjSourceOom = adj; 15487 app.adjTarget = s.name; 15488 } 15489 } 15490 } 15491 } 15492 } 15493 15494 for (int provi = app.pubProviders.size()-1; 15495 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15496 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15497 || procState > ActivityManager.PROCESS_STATE_TOP); 15498 provi--) { 15499 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15500 for (int i = cpr.connections.size()-1; 15501 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15502 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15503 || procState > ActivityManager.PROCESS_STATE_TOP); 15504 i--) { 15505 ContentProviderConnection conn = cpr.connections.get(i); 15506 ProcessRecord client = conn.client; 15507 if (client == app) { 15508 // Being our own client is not interesting. 15509 continue; 15510 } 15511 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15512 int clientProcState = client.curProcState; 15513 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15514 // If the other app is cached for any reason, for purposes here 15515 // we are going to consider it empty. 15516 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15517 } 15518 if (adj > clientAdj) { 15519 if (app.hasShownUi && app != mHomeProcess 15520 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15521 app.adjType = "cch-ui-provider"; 15522 } else { 15523 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15524 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15525 app.adjType = "provider"; 15526 } 15527 app.cached &= client.cached; 15528 app.keeping |= client.keeping; 15529 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15530 .REASON_PROVIDER_IN_USE; 15531 app.adjSource = client; 15532 app.adjSourceOom = clientAdj; 15533 app.adjTarget = cpr.name; 15534 } 15535 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15536 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15537 // Special handling of clients who are in the top state. 15538 // We *may* want to consider this process to be in the 15539 // top state as well, but only if there is not another 15540 // reason for it to be running. Being on the top is a 15541 // special state, meaning you are specifically running 15542 // for the current top app. If the process is already 15543 // running in the background for some other reason, it 15544 // is more important to continue considering it to be 15545 // in the background state. 15546 mayBeTop = true; 15547 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15548 } else { 15549 // Special handling for above-top states (persistent 15550 // processes). These should not bring the current process 15551 // into the top state, since they are not on top. Instead 15552 // give them the best state after that. 15553 clientProcState = 15554 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15555 } 15556 } 15557 if (procState > clientProcState) { 15558 procState = clientProcState; 15559 } 15560 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15561 schedGroup = Process.THREAD_GROUP_DEFAULT; 15562 } 15563 } 15564 // If the provider has external (non-framework) process 15565 // dependencies, ensure that its adjustment is at least 15566 // FOREGROUND_APP_ADJ. 15567 if (cpr.hasExternalProcessHandles()) { 15568 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15569 adj = ProcessList.FOREGROUND_APP_ADJ; 15570 schedGroup = Process.THREAD_GROUP_DEFAULT; 15571 app.cached = false; 15572 app.keeping = true; 15573 app.adjType = "provider"; 15574 app.adjTarget = cpr.name; 15575 } 15576 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15577 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15578 } 15579 } 15580 } 15581 15582 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15583 // A client of one of our services or providers is in the top state. We 15584 // *may* want to be in the top state, but not if we are already running in 15585 // the background for some other reason. For the decision here, we are going 15586 // to pick out a few specific states that we want to remain in when a client 15587 // is top (states that tend to be longer-term) and otherwise allow it to go 15588 // to the top state. 15589 switch (procState) { 15590 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15591 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15592 case ActivityManager.PROCESS_STATE_SERVICE: 15593 // These all are longer-term states, so pull them up to the top 15594 // of the background states, but not all the way to the top state. 15595 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15596 break; 15597 default: 15598 // Otherwise, top is a better choice, so take it. 15599 procState = ActivityManager.PROCESS_STATE_TOP; 15600 break; 15601 } 15602 } 15603 15604 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15605 if (app.hasClientActivities) { 15606 // This is a cached process, but with client activities. Mark it so. 15607 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15608 app.adjType = "cch-client-act"; 15609 } else if (app.treatLikeActivity) { 15610 // This is a cached process, but somebody wants us to treat it like it has 15611 // an activity, okay! 15612 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15613 app.adjType = "cch-as-act"; 15614 } 15615 } 15616 15617 if (adj == ProcessList.SERVICE_ADJ) { 15618 if (doingAll) { 15619 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15620 mNewNumServiceProcs++; 15621 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15622 if (!app.serviceb) { 15623 // This service isn't far enough down on the LRU list to 15624 // normally be a B service, but if we are low on RAM and it 15625 // is large we want to force it down since we would prefer to 15626 // keep launcher over it. 15627 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15628 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15629 app.serviceHighRam = true; 15630 app.serviceb = true; 15631 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15632 } else { 15633 mNewNumAServiceProcs++; 15634 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15635 } 15636 } else { 15637 app.serviceHighRam = false; 15638 } 15639 } 15640 if (app.serviceb) { 15641 adj = ProcessList.SERVICE_B_ADJ; 15642 } 15643 } 15644 15645 app.curRawAdj = adj; 15646 15647 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15648 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15649 if (adj > app.maxAdj) { 15650 adj = app.maxAdj; 15651 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15652 schedGroup = Process.THREAD_GROUP_DEFAULT; 15653 } 15654 } 15655 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15656 app.keeping = true; 15657 } 15658 15659 // Do final modification to adj. Everything we do between here and applying 15660 // the final setAdj must be done in this function, because we will also use 15661 // it when computing the final cached adj later. Note that we don't need to 15662 // worry about this for max adj above, since max adj will always be used to 15663 // keep it out of the cached vaues. 15664 app.curAdj = app.modifyRawOomAdj(adj); 15665 app.curSchedGroup = schedGroup; 15666 app.curProcState = procState; 15667 app.foregroundActivities = foregroundActivities; 15668 15669 return app.curRawAdj; 15670 } 15671 15672 /** 15673 * Schedule PSS collection of a process. 15674 */ 15675 void requestPssLocked(ProcessRecord proc, int procState) { 15676 if (mPendingPssProcesses.contains(proc)) { 15677 return; 15678 } 15679 if (mPendingPssProcesses.size() == 0) { 15680 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15681 } 15682 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15683 proc.pssProcState = procState; 15684 mPendingPssProcesses.add(proc); 15685 } 15686 15687 /** 15688 * Schedule PSS collection of all processes. 15689 */ 15690 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15691 if (!always) { 15692 if (now < (mLastFullPssTime + 15693 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15694 return; 15695 } 15696 } 15697 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15698 mLastFullPssTime = now; 15699 mFullPssPending = true; 15700 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15701 mPendingPssProcesses.clear(); 15702 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15703 ProcessRecord app = mLruProcesses.get(i); 15704 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15705 app.pssProcState = app.setProcState; 15706 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15707 isSleeping(), now); 15708 mPendingPssProcesses.add(app); 15709 } 15710 } 15711 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15712 } 15713 15714 /** 15715 * Ask a given process to GC right now. 15716 */ 15717 final void performAppGcLocked(ProcessRecord app) { 15718 try { 15719 app.lastRequestedGc = SystemClock.uptimeMillis(); 15720 if (app.thread != null) { 15721 if (app.reportLowMemory) { 15722 app.reportLowMemory = false; 15723 app.thread.scheduleLowMemory(); 15724 } else { 15725 app.thread.processInBackground(); 15726 } 15727 } 15728 } catch (Exception e) { 15729 // whatever. 15730 } 15731 } 15732 15733 /** 15734 * Returns true if things are idle enough to perform GCs. 15735 */ 15736 private final boolean canGcNowLocked() { 15737 boolean processingBroadcasts = false; 15738 for (BroadcastQueue q : mBroadcastQueues) { 15739 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15740 processingBroadcasts = true; 15741 } 15742 } 15743 return !processingBroadcasts 15744 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15745 } 15746 15747 /** 15748 * Perform GCs on all processes that are waiting for it, but only 15749 * if things are idle. 15750 */ 15751 final void performAppGcsLocked() { 15752 final int N = mProcessesToGc.size(); 15753 if (N <= 0) { 15754 return; 15755 } 15756 if (canGcNowLocked()) { 15757 while (mProcessesToGc.size() > 0) { 15758 ProcessRecord proc = mProcessesToGc.remove(0); 15759 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15760 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15761 <= SystemClock.uptimeMillis()) { 15762 // To avoid spamming the system, we will GC processes one 15763 // at a time, waiting a few seconds between each. 15764 performAppGcLocked(proc); 15765 scheduleAppGcsLocked(); 15766 return; 15767 } else { 15768 // It hasn't been long enough since we last GCed this 15769 // process... put it in the list to wait for its time. 15770 addProcessToGcListLocked(proc); 15771 break; 15772 } 15773 } 15774 } 15775 15776 scheduleAppGcsLocked(); 15777 } 15778 } 15779 15780 /** 15781 * If all looks good, perform GCs on all processes waiting for them. 15782 */ 15783 final void performAppGcsIfAppropriateLocked() { 15784 if (canGcNowLocked()) { 15785 performAppGcsLocked(); 15786 return; 15787 } 15788 // Still not idle, wait some more. 15789 scheduleAppGcsLocked(); 15790 } 15791 15792 /** 15793 * Schedule the execution of all pending app GCs. 15794 */ 15795 final void scheduleAppGcsLocked() { 15796 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15797 15798 if (mProcessesToGc.size() > 0) { 15799 // Schedule a GC for the time to the next process. 15800 ProcessRecord proc = mProcessesToGc.get(0); 15801 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15802 15803 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15804 long now = SystemClock.uptimeMillis(); 15805 if (when < (now+GC_TIMEOUT)) { 15806 when = now + GC_TIMEOUT; 15807 } 15808 mHandler.sendMessageAtTime(msg, when); 15809 } 15810 } 15811 15812 /** 15813 * Add a process to the array of processes waiting to be GCed. Keeps the 15814 * list in sorted order by the last GC time. The process can't already be 15815 * on the list. 15816 */ 15817 final void addProcessToGcListLocked(ProcessRecord proc) { 15818 boolean added = false; 15819 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15820 if (mProcessesToGc.get(i).lastRequestedGc < 15821 proc.lastRequestedGc) { 15822 added = true; 15823 mProcessesToGc.add(i+1, proc); 15824 break; 15825 } 15826 } 15827 if (!added) { 15828 mProcessesToGc.add(0, proc); 15829 } 15830 } 15831 15832 /** 15833 * Set up to ask a process to GC itself. This will either do it 15834 * immediately, or put it on the list of processes to gc the next 15835 * time things are idle. 15836 */ 15837 final void scheduleAppGcLocked(ProcessRecord app) { 15838 long now = SystemClock.uptimeMillis(); 15839 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15840 return; 15841 } 15842 if (!mProcessesToGc.contains(app)) { 15843 addProcessToGcListLocked(app); 15844 scheduleAppGcsLocked(); 15845 } 15846 } 15847 15848 final void checkExcessivePowerUsageLocked(boolean doKills) { 15849 updateCpuStatsNow(); 15850 15851 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15852 boolean doWakeKills = doKills; 15853 boolean doCpuKills = doKills; 15854 if (mLastPowerCheckRealtime == 0) { 15855 doWakeKills = false; 15856 } 15857 if (mLastPowerCheckUptime == 0) { 15858 doCpuKills = false; 15859 } 15860 if (stats.isScreenOn()) { 15861 doWakeKills = false; 15862 } 15863 final long curRealtime = SystemClock.elapsedRealtime(); 15864 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15865 final long curUptime = SystemClock.uptimeMillis(); 15866 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15867 mLastPowerCheckRealtime = curRealtime; 15868 mLastPowerCheckUptime = curUptime; 15869 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15870 doWakeKills = false; 15871 } 15872 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15873 doCpuKills = false; 15874 } 15875 int i = mLruProcesses.size(); 15876 while (i > 0) { 15877 i--; 15878 ProcessRecord app = mLruProcesses.get(i); 15879 if (!app.keeping) { 15880 long wtime; 15881 synchronized (stats) { 15882 wtime = stats.getProcessWakeTime(app.info.uid, 15883 app.pid, curRealtime); 15884 } 15885 long wtimeUsed = wtime - app.lastWakeTime; 15886 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15887 if (DEBUG_POWER) { 15888 StringBuilder sb = new StringBuilder(128); 15889 sb.append("Wake for "); 15890 app.toShortString(sb); 15891 sb.append(": over "); 15892 TimeUtils.formatDuration(realtimeSince, sb); 15893 sb.append(" used "); 15894 TimeUtils.formatDuration(wtimeUsed, sb); 15895 sb.append(" ("); 15896 sb.append((wtimeUsed*100)/realtimeSince); 15897 sb.append("%)"); 15898 Slog.i(TAG, sb.toString()); 15899 sb.setLength(0); 15900 sb.append("CPU for "); 15901 app.toShortString(sb); 15902 sb.append(": over "); 15903 TimeUtils.formatDuration(uptimeSince, sb); 15904 sb.append(" used "); 15905 TimeUtils.formatDuration(cputimeUsed, sb); 15906 sb.append(" ("); 15907 sb.append((cputimeUsed*100)/uptimeSince); 15908 sb.append("%)"); 15909 Slog.i(TAG, sb.toString()); 15910 } 15911 // If a process has held a wake lock for more 15912 // than 50% of the time during this period, 15913 // that sounds bad. Kill! 15914 if (doWakeKills && realtimeSince > 0 15915 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15916 synchronized (stats) { 15917 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15918 realtimeSince, wtimeUsed); 15919 } 15920 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15921 + " during " + realtimeSince); 15922 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15923 } else if (doCpuKills && uptimeSince > 0 15924 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15925 synchronized (stats) { 15926 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15927 uptimeSince, cputimeUsed); 15928 } 15929 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15930 + " during " + uptimeSince); 15931 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15932 } else { 15933 app.lastWakeTime = wtime; 15934 app.lastCpuTime = app.curCpuTime; 15935 } 15936 } 15937 } 15938 } 15939 15940 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15941 ProcessRecord TOP_APP, boolean doingAll, long now) { 15942 boolean success = true; 15943 15944 if (app.curRawAdj != app.setRawAdj) { 15945 if (wasKeeping && !app.keeping) { 15946 // This app is no longer something we want to keep. Note 15947 // its current wake lock time to later know to kill it if 15948 // it is not behaving well. 15949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15950 synchronized (stats) { 15951 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15952 app.pid, SystemClock.elapsedRealtime()); 15953 } 15954 app.lastCpuTime = app.curCpuTime; 15955 } 15956 15957 app.setRawAdj = app.curRawAdj; 15958 } 15959 15960 int changes = 0; 15961 15962 if (app.curAdj != app.setAdj) { 15963 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 15964 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15965 TAG, "Set " + app.pid + " " + app.processName + 15966 " adj " + app.curAdj + ": " + app.adjType); 15967 app.setAdj = app.curAdj; 15968 } 15969 15970 if (app.setSchedGroup != app.curSchedGroup) { 15971 app.setSchedGroup = app.curSchedGroup; 15972 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15973 "Setting process group of " + app.processName 15974 + " to " + app.curSchedGroup); 15975 if (app.waitingToKill != null && 15976 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15977 killUnneededProcessLocked(app, app.waitingToKill); 15978 success = false; 15979 } else { 15980 if (true) { 15981 long oldId = Binder.clearCallingIdentity(); 15982 try { 15983 Process.setProcessGroup(app.pid, app.curSchedGroup); 15984 } catch (Exception e) { 15985 Slog.w(TAG, "Failed setting process group of " + app.pid 15986 + " to " + app.curSchedGroup); 15987 e.printStackTrace(); 15988 } finally { 15989 Binder.restoreCallingIdentity(oldId); 15990 } 15991 } else { 15992 if (app.thread != null) { 15993 try { 15994 app.thread.setSchedulingGroup(app.curSchedGroup); 15995 } catch (RemoteException e) { 15996 } 15997 } 15998 } 15999 Process.setSwappiness(app.pid, 16000 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16001 } 16002 } 16003 if (app.repForegroundActivities != app.foregroundActivities) { 16004 app.repForegroundActivities = app.foregroundActivities; 16005 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16006 } 16007 if (app.repProcState != app.curProcState) { 16008 app.repProcState = app.curProcState; 16009 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16010 if (app.thread != null) { 16011 try { 16012 if (false) { 16013 //RuntimeException h = new RuntimeException("here"); 16014 Slog.i(TAG, "Sending new process state " + app.repProcState 16015 + " to " + app /*, h*/); 16016 } 16017 app.thread.setProcessState(app.repProcState); 16018 } catch (RemoteException e) { 16019 } 16020 } 16021 } 16022 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16023 app.setProcState)) { 16024 app.lastStateTime = now; 16025 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16026 isSleeping(), now); 16027 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16028 + ProcessList.makeProcStateString(app.setProcState) + " to " 16029 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16030 + (app.nextPssTime-now) + ": " + app); 16031 } else { 16032 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16033 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16034 requestPssLocked(app, app.setProcState); 16035 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16036 isSleeping(), now); 16037 } else if (false && DEBUG_PSS) { 16038 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16039 } 16040 } 16041 if (app.setProcState != app.curProcState) { 16042 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16043 "Proc state change of " + app.processName 16044 + " to " + app.curProcState); 16045 app.setProcState = app.curProcState; 16046 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16047 app.notCachedSinceIdle = false; 16048 } 16049 if (!doingAll) { 16050 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16051 } else { 16052 app.procStateChanged = true; 16053 } 16054 } 16055 16056 if (changes != 0) { 16057 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16058 int i = mPendingProcessChanges.size()-1; 16059 ProcessChangeItem item = null; 16060 while (i >= 0) { 16061 item = mPendingProcessChanges.get(i); 16062 if (item.pid == app.pid) { 16063 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16064 break; 16065 } 16066 i--; 16067 } 16068 if (i < 0) { 16069 // No existing item in pending changes; need a new one. 16070 final int NA = mAvailProcessChanges.size(); 16071 if (NA > 0) { 16072 item = mAvailProcessChanges.remove(NA-1); 16073 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16074 } else { 16075 item = new ProcessChangeItem(); 16076 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16077 } 16078 item.changes = 0; 16079 item.pid = app.pid; 16080 item.uid = app.info.uid; 16081 if (mPendingProcessChanges.size() == 0) { 16082 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16083 "*** Enqueueing dispatch processes changed!"); 16084 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16085 } 16086 mPendingProcessChanges.add(item); 16087 } 16088 item.changes |= changes; 16089 item.processState = app.repProcState; 16090 item.foregroundActivities = app.repForegroundActivities; 16091 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16092 + Integer.toHexString(System.identityHashCode(item)) 16093 + " " + app.toShortString() + ": changes=" + item.changes 16094 + " procState=" + item.processState 16095 + " foreground=" + item.foregroundActivities 16096 + " type=" + app.adjType + " source=" + app.adjSource 16097 + " target=" + app.adjTarget); 16098 } 16099 16100 return success; 16101 } 16102 16103 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16104 if (proc.thread != null) { 16105 if (proc.baseProcessTracker != null) { 16106 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16107 } 16108 if (proc.repProcState >= 0) { 16109 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16110 proc.repProcState); 16111 } 16112 } 16113 } 16114 16115 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16116 ProcessRecord TOP_APP, boolean doingAll, long now) { 16117 if (app.thread == null) { 16118 return false; 16119 } 16120 16121 final boolean wasKeeping = app.keeping; 16122 16123 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16124 16125 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16126 } 16127 16128 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16129 boolean oomAdj) { 16130 if (isForeground != proc.foregroundServices) { 16131 proc.foregroundServices = isForeground; 16132 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16133 proc.info.uid); 16134 if (isForeground) { 16135 if (curProcs == null) { 16136 curProcs = new ArrayList<ProcessRecord>(); 16137 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16138 } 16139 if (!curProcs.contains(proc)) { 16140 curProcs.add(proc); 16141 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16142 proc.info.packageName, proc.info.uid); 16143 } 16144 } else { 16145 if (curProcs != null) { 16146 if (curProcs.remove(proc)) { 16147 mBatteryStatsService.noteEvent( 16148 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16149 proc.info.packageName, proc.info.uid); 16150 if (curProcs.size() <= 0) { 16151 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16152 } 16153 } 16154 } 16155 } 16156 if (oomAdj) { 16157 updateOomAdjLocked(); 16158 } 16159 } 16160 } 16161 16162 private final ActivityRecord resumedAppLocked() { 16163 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16164 String pkg; 16165 int uid; 16166 if (act != null) { 16167 pkg = act.packageName; 16168 uid = act.info.applicationInfo.uid; 16169 } else { 16170 pkg = null; 16171 uid = -1; 16172 } 16173 // Has the UID or resumed package name changed? 16174 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16175 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16176 if (mCurResumedPackage != null) { 16177 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16178 mCurResumedPackage, mCurResumedUid); 16179 } 16180 mCurResumedPackage = pkg; 16181 mCurResumedUid = uid; 16182 if (mCurResumedPackage != null) { 16183 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16184 mCurResumedPackage, mCurResumedUid); 16185 } 16186 } 16187 return act; 16188 } 16189 16190 final boolean updateOomAdjLocked(ProcessRecord app) { 16191 final ActivityRecord TOP_ACT = resumedAppLocked(); 16192 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16193 final boolean wasCached = app.cached; 16194 16195 mAdjSeq++; 16196 16197 // This is the desired cached adjusment we want to tell it to use. 16198 // If our app is currently cached, we know it, and that is it. Otherwise, 16199 // we don't know it yet, and it needs to now be cached we will then 16200 // need to do a complete oom adj. 16201 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16202 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16203 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16204 SystemClock.uptimeMillis()); 16205 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16206 // Changed to/from cached state, so apps after it in the LRU 16207 // list may also be changed. 16208 updateOomAdjLocked(); 16209 } 16210 return success; 16211 } 16212 16213 final void updateOomAdjLocked() { 16214 final ActivityRecord TOP_ACT = resumedAppLocked(); 16215 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16216 final long now = SystemClock.uptimeMillis(); 16217 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16218 final int N = mLruProcesses.size(); 16219 16220 if (false) { 16221 RuntimeException e = new RuntimeException(); 16222 e.fillInStackTrace(); 16223 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16224 } 16225 16226 mAdjSeq++; 16227 mNewNumServiceProcs = 0; 16228 mNewNumAServiceProcs = 0; 16229 16230 final int emptyProcessLimit; 16231 final int cachedProcessLimit; 16232 if (mProcessLimit <= 0) { 16233 emptyProcessLimit = cachedProcessLimit = 0; 16234 } else if (mProcessLimit == 1) { 16235 emptyProcessLimit = 1; 16236 cachedProcessLimit = 0; 16237 } else { 16238 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16239 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16240 } 16241 16242 // Let's determine how many processes we have running vs. 16243 // how many slots we have for background processes; we may want 16244 // to put multiple processes in a slot of there are enough of 16245 // them. 16246 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16247 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16248 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16249 if (numEmptyProcs > cachedProcessLimit) { 16250 // If there are more empty processes than our limit on cached 16251 // processes, then use the cached process limit for the factor. 16252 // This ensures that the really old empty processes get pushed 16253 // down to the bottom, so if we are running low on memory we will 16254 // have a better chance at keeping around more cached processes 16255 // instead of a gazillion empty processes. 16256 numEmptyProcs = cachedProcessLimit; 16257 } 16258 int emptyFactor = numEmptyProcs/numSlots; 16259 if (emptyFactor < 1) emptyFactor = 1; 16260 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16261 if (cachedFactor < 1) cachedFactor = 1; 16262 int stepCached = 0; 16263 int stepEmpty = 0; 16264 int numCached = 0; 16265 int numEmpty = 0; 16266 int numTrimming = 0; 16267 16268 mNumNonCachedProcs = 0; 16269 mNumCachedHiddenProcs = 0; 16270 16271 // First update the OOM adjustment for each of the 16272 // application processes based on their current state. 16273 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16274 int nextCachedAdj = curCachedAdj+1; 16275 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16276 int nextEmptyAdj = curEmptyAdj+2; 16277 for (int i=N-1; i>=0; i--) { 16278 ProcessRecord app = mLruProcesses.get(i); 16279 if (!app.killedByAm && app.thread != null) { 16280 app.procStateChanged = false; 16281 final boolean wasKeeping = app.keeping; 16282 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16283 16284 // If we haven't yet assigned the final cached adj 16285 // to the process, do that now. 16286 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16287 switch (app.curProcState) { 16288 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16289 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16290 // This process is a cached process holding activities... 16291 // assign it the next cached value for that type, and then 16292 // step that cached level. 16293 app.curRawAdj = curCachedAdj; 16294 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16295 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16296 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16297 + ")"); 16298 if (curCachedAdj != nextCachedAdj) { 16299 stepCached++; 16300 if (stepCached >= cachedFactor) { 16301 stepCached = 0; 16302 curCachedAdj = nextCachedAdj; 16303 nextCachedAdj += 2; 16304 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16305 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16306 } 16307 } 16308 } 16309 break; 16310 default: 16311 // For everything else, assign next empty cached process 16312 // level and bump that up. Note that this means that 16313 // long-running services that have dropped down to the 16314 // cached level will be treated as empty (since their process 16315 // state is still as a service), which is what we want. 16316 app.curRawAdj = curEmptyAdj; 16317 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16318 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16319 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16320 + ")"); 16321 if (curEmptyAdj != nextEmptyAdj) { 16322 stepEmpty++; 16323 if (stepEmpty >= emptyFactor) { 16324 stepEmpty = 0; 16325 curEmptyAdj = nextEmptyAdj; 16326 nextEmptyAdj += 2; 16327 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16328 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16329 } 16330 } 16331 } 16332 break; 16333 } 16334 } 16335 16336 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16337 16338 // Count the number of process types. 16339 switch (app.curProcState) { 16340 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16341 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16342 mNumCachedHiddenProcs++; 16343 numCached++; 16344 if (numCached > cachedProcessLimit) { 16345 killUnneededProcessLocked(app, "cached #" + numCached); 16346 } 16347 break; 16348 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16349 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16350 && app.lastActivityTime < oldTime) { 16351 killUnneededProcessLocked(app, "empty for " 16352 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16353 / 1000) + "s"); 16354 } else { 16355 numEmpty++; 16356 if (numEmpty > emptyProcessLimit) { 16357 killUnneededProcessLocked(app, "empty #" + numEmpty); 16358 } 16359 } 16360 break; 16361 default: 16362 mNumNonCachedProcs++; 16363 break; 16364 } 16365 16366 if (app.isolated && app.services.size() <= 0) { 16367 // If this is an isolated process, and there are no 16368 // services running in it, then the process is no longer 16369 // needed. We agressively kill these because we can by 16370 // definition not re-use the same process again, and it is 16371 // good to avoid having whatever code was running in them 16372 // left sitting around after no longer needed. 16373 killUnneededProcessLocked(app, "isolated not needed"); 16374 } 16375 16376 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16377 && !app.killedByAm) { 16378 numTrimming++; 16379 } 16380 } 16381 } 16382 16383 mNumServiceProcs = mNewNumServiceProcs; 16384 16385 // Now determine the memory trimming level of background processes. 16386 // Unfortunately we need to start at the back of the list to do this 16387 // properly. We only do this if the number of background apps we 16388 // are managing to keep around is less than half the maximum we desire; 16389 // if we are keeping a good number around, we'll let them use whatever 16390 // memory they want. 16391 final int numCachedAndEmpty = numCached + numEmpty; 16392 int memFactor; 16393 if (numCached <= ProcessList.TRIM_CACHED_APPS 16394 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16395 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16396 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16397 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16398 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16399 } else { 16400 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16401 } 16402 } else { 16403 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16404 } 16405 // We always allow the memory level to go up (better). We only allow it to go 16406 // down if we are in a state where that is allowed, *and* the total number of processes 16407 // has gone down since last time. 16408 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16409 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16410 + " last=" + mLastNumProcesses); 16411 if (memFactor > mLastMemoryLevel) { 16412 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16413 memFactor = mLastMemoryLevel; 16414 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16415 } 16416 } 16417 mLastMemoryLevel = memFactor; 16418 mLastNumProcesses = mLruProcesses.size(); 16419 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16420 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16421 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16422 if (mLowRamStartTime == 0) { 16423 mLowRamStartTime = now; 16424 } 16425 int step = 0; 16426 int fgTrimLevel; 16427 switch (memFactor) { 16428 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16429 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16430 break; 16431 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16432 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16433 break; 16434 default: 16435 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16436 break; 16437 } 16438 int factor = numTrimming/3; 16439 int minFactor = 2; 16440 if (mHomeProcess != null) minFactor++; 16441 if (mPreviousProcess != null) minFactor++; 16442 if (factor < minFactor) factor = minFactor; 16443 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16444 for (int i=N-1; i>=0; i--) { 16445 ProcessRecord app = mLruProcesses.get(i); 16446 if (allChanged || app.procStateChanged) { 16447 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16448 app.procStateChanged = false; 16449 } 16450 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16451 && !app.killedByAm) { 16452 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16453 try { 16454 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16455 "Trimming memory of " + app.processName 16456 + " to " + curLevel); 16457 app.thread.scheduleTrimMemory(curLevel); 16458 } catch (RemoteException e) { 16459 } 16460 if (false) { 16461 // For now we won't do this; our memory trimming seems 16462 // to be good enough at this point that destroying 16463 // activities causes more harm than good. 16464 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16465 && app != mHomeProcess && app != mPreviousProcess) { 16466 // Need to do this on its own message because the stack may not 16467 // be in a consistent state at this point. 16468 // For these apps we will also finish their activities 16469 // to help them free memory. 16470 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16471 } 16472 } 16473 } 16474 app.trimMemoryLevel = curLevel; 16475 step++; 16476 if (step >= factor) { 16477 step = 0; 16478 switch (curLevel) { 16479 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16480 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16481 break; 16482 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16483 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16484 break; 16485 } 16486 } 16487 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16488 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16489 && app.thread != null) { 16490 try { 16491 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16492 "Trimming memory of heavy-weight " + app.processName 16493 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16494 app.thread.scheduleTrimMemory( 16495 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16496 } catch (RemoteException e) { 16497 } 16498 } 16499 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16500 } else { 16501 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16502 || app.systemNoUi) && app.pendingUiClean) { 16503 // If this application is now in the background and it 16504 // had done UI, then give it the special trim level to 16505 // have it free UI resources. 16506 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16507 if (app.trimMemoryLevel < level && app.thread != null) { 16508 try { 16509 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16510 "Trimming memory of bg-ui " + app.processName 16511 + " to " + level); 16512 app.thread.scheduleTrimMemory(level); 16513 } catch (RemoteException e) { 16514 } 16515 } 16516 app.pendingUiClean = false; 16517 } 16518 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16519 try { 16520 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16521 "Trimming memory of fg " + app.processName 16522 + " to " + fgTrimLevel); 16523 app.thread.scheduleTrimMemory(fgTrimLevel); 16524 } catch (RemoteException e) { 16525 } 16526 } 16527 app.trimMemoryLevel = fgTrimLevel; 16528 } 16529 } 16530 } else { 16531 if (mLowRamStartTime != 0) { 16532 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16533 mLowRamStartTime = 0; 16534 } 16535 for (int i=N-1; i>=0; i--) { 16536 ProcessRecord app = mLruProcesses.get(i); 16537 if (allChanged || app.procStateChanged) { 16538 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16539 app.procStateChanged = false; 16540 } 16541 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16542 || app.systemNoUi) && app.pendingUiClean) { 16543 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16544 && app.thread != null) { 16545 try { 16546 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16547 "Trimming memory of ui hidden " + app.processName 16548 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16549 app.thread.scheduleTrimMemory( 16550 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16551 } catch (RemoteException e) { 16552 } 16553 } 16554 app.pendingUiClean = false; 16555 } 16556 app.trimMemoryLevel = 0; 16557 } 16558 } 16559 16560 if (mAlwaysFinishActivities) { 16561 // Need to do this on its own message because the stack may not 16562 // be in a consistent state at this point. 16563 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16564 } 16565 16566 if (allChanged) { 16567 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16568 } 16569 16570 if (mProcessStats.shouldWriteNowLocked(now)) { 16571 mHandler.post(new Runnable() { 16572 @Override public void run() { 16573 synchronized (ActivityManagerService.this) { 16574 mProcessStats.writeStateAsyncLocked(); 16575 } 16576 } 16577 }); 16578 } 16579 16580 if (DEBUG_OOM_ADJ) { 16581 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16582 } 16583 } 16584 16585 final void trimApplications() { 16586 synchronized (this) { 16587 int i; 16588 16589 // First remove any unused application processes whose package 16590 // has been removed. 16591 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16592 final ProcessRecord app = mRemovedProcesses.get(i); 16593 if (app.activities.size() == 0 16594 && app.curReceiver == null && app.services.size() == 0) { 16595 Slog.i( 16596 TAG, "Exiting empty application process " 16597 + app.processName + " (" 16598 + (app.thread != null ? app.thread.asBinder() : null) 16599 + ")\n"); 16600 if (app.pid > 0 && app.pid != MY_PID) { 16601 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16602 app.processName, app.setAdj, "empty"); 16603 app.killedByAm = true; 16604 Process.killProcessQuiet(app.pid); 16605 Process.killProcessGroup(app.info.uid, app.pid); 16606 } else { 16607 try { 16608 app.thread.scheduleExit(); 16609 } catch (Exception e) { 16610 // Ignore exceptions. 16611 } 16612 } 16613 cleanUpApplicationRecordLocked(app, false, true, -1); 16614 mRemovedProcesses.remove(i); 16615 16616 if (app.persistent) { 16617 addAppLocked(app.info, false, null /* ABI override */); 16618 } 16619 } 16620 } 16621 16622 // Now update the oom adj for all processes. 16623 updateOomAdjLocked(); 16624 } 16625 } 16626 16627 /** This method sends the specified signal to each of the persistent apps */ 16628 public void signalPersistentProcesses(int sig) throws RemoteException { 16629 if (sig != Process.SIGNAL_USR1) { 16630 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16631 } 16632 16633 synchronized (this) { 16634 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16635 != PackageManager.PERMISSION_GRANTED) { 16636 throw new SecurityException("Requires permission " 16637 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16638 } 16639 16640 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16641 ProcessRecord r = mLruProcesses.get(i); 16642 if (r.thread != null && r.persistent) { 16643 Process.sendSignal(r.pid, sig); 16644 } 16645 } 16646 } 16647 } 16648 16649 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16650 if (proc == null || proc == mProfileProc) { 16651 proc = mProfileProc; 16652 path = mProfileFile; 16653 profileType = mProfileType; 16654 clearProfilerLocked(); 16655 } 16656 if (proc == null) { 16657 return; 16658 } 16659 try { 16660 proc.thread.profilerControl(false, path, null, profileType); 16661 } catch (RemoteException e) { 16662 throw new IllegalStateException("Process disappeared"); 16663 } 16664 } 16665 16666 private void clearProfilerLocked() { 16667 if (mProfileFd != null) { 16668 try { 16669 mProfileFd.close(); 16670 } catch (IOException e) { 16671 } 16672 } 16673 mProfileApp = null; 16674 mProfileProc = null; 16675 mProfileFile = null; 16676 mProfileType = 0; 16677 mAutoStopProfiler = false; 16678 } 16679 16680 public boolean profileControl(String process, int userId, boolean start, 16681 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16682 16683 try { 16684 synchronized (this) { 16685 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16686 // its own permission. 16687 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16688 != PackageManager.PERMISSION_GRANTED) { 16689 throw new SecurityException("Requires permission " 16690 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16691 } 16692 16693 if (start && fd == null) { 16694 throw new IllegalArgumentException("null fd"); 16695 } 16696 16697 ProcessRecord proc = null; 16698 if (process != null) { 16699 proc = findProcessLocked(process, userId, "profileControl"); 16700 } 16701 16702 if (start && (proc == null || proc.thread == null)) { 16703 throw new IllegalArgumentException("Unknown process: " + process); 16704 } 16705 16706 if (start) { 16707 stopProfilerLocked(null, null, 0); 16708 setProfileApp(proc.info, proc.processName, path, fd, false); 16709 mProfileProc = proc; 16710 mProfileType = profileType; 16711 try { 16712 fd = fd.dup(); 16713 } catch (IOException e) { 16714 fd = null; 16715 } 16716 proc.thread.profilerControl(start, path, fd, profileType); 16717 fd = null; 16718 mProfileFd = null; 16719 } else { 16720 stopProfilerLocked(proc, path, profileType); 16721 if (fd != null) { 16722 try { 16723 fd.close(); 16724 } catch (IOException e) { 16725 } 16726 } 16727 } 16728 16729 return true; 16730 } 16731 } catch (RemoteException e) { 16732 throw new IllegalStateException("Process disappeared"); 16733 } finally { 16734 if (fd != null) { 16735 try { 16736 fd.close(); 16737 } catch (IOException e) { 16738 } 16739 } 16740 } 16741 } 16742 16743 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16744 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16745 userId, true, true, callName, null); 16746 ProcessRecord proc = null; 16747 try { 16748 int pid = Integer.parseInt(process); 16749 synchronized (mPidsSelfLocked) { 16750 proc = mPidsSelfLocked.get(pid); 16751 } 16752 } catch (NumberFormatException e) { 16753 } 16754 16755 if (proc == null) { 16756 ArrayMap<String, SparseArray<ProcessRecord>> all 16757 = mProcessNames.getMap(); 16758 SparseArray<ProcessRecord> procs = all.get(process); 16759 if (procs != null && procs.size() > 0) { 16760 proc = procs.valueAt(0); 16761 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16762 for (int i=1; i<procs.size(); i++) { 16763 ProcessRecord thisProc = procs.valueAt(i); 16764 if (thisProc.userId == userId) { 16765 proc = thisProc; 16766 break; 16767 } 16768 } 16769 } 16770 } 16771 } 16772 16773 return proc; 16774 } 16775 16776 public boolean dumpHeap(String process, int userId, boolean managed, 16777 String path, ParcelFileDescriptor fd) throws RemoteException { 16778 16779 try { 16780 synchronized (this) { 16781 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16782 // its own permission (same as profileControl). 16783 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16784 != PackageManager.PERMISSION_GRANTED) { 16785 throw new SecurityException("Requires permission " 16786 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16787 } 16788 16789 if (fd == null) { 16790 throw new IllegalArgumentException("null fd"); 16791 } 16792 16793 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16794 if (proc == null || proc.thread == null) { 16795 throw new IllegalArgumentException("Unknown process: " + process); 16796 } 16797 16798 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16799 if (!isDebuggable) { 16800 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16801 throw new SecurityException("Process not debuggable: " + proc); 16802 } 16803 } 16804 16805 proc.thread.dumpHeap(managed, path, fd); 16806 fd = null; 16807 return true; 16808 } 16809 } catch (RemoteException e) { 16810 throw new IllegalStateException("Process disappeared"); 16811 } finally { 16812 if (fd != null) { 16813 try { 16814 fd.close(); 16815 } catch (IOException e) { 16816 } 16817 } 16818 } 16819 } 16820 16821 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16822 public void monitor() { 16823 synchronized (this) { } 16824 } 16825 16826 void onCoreSettingsChange(Bundle settings) { 16827 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16828 ProcessRecord processRecord = mLruProcesses.get(i); 16829 try { 16830 if (processRecord.thread != null) { 16831 processRecord.thread.setCoreSettings(settings); 16832 } 16833 } catch (RemoteException re) { 16834 /* ignore */ 16835 } 16836 } 16837 } 16838 16839 // Multi-user methods 16840 16841 /** 16842 * Start user, if its not already running, but don't bring it to foreground. 16843 */ 16844 @Override 16845 public boolean startUserInBackground(final int userId) { 16846 return startUser(userId, /* foreground */ false); 16847 } 16848 16849 /** 16850 * Refreshes the list of users related to the current user when either a 16851 * user switch happens or when a new related user is started in the 16852 * background. 16853 */ 16854 private void updateCurrentProfileIdsLocked() { 16855 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16856 mCurrentUserId, false /* enabledOnly */); 16857 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16858 for (int i = 0; i < currentProfileIds.length; i++) { 16859 currentProfileIds[i] = profiles.get(i).id; 16860 } 16861 mCurrentProfileIds = currentProfileIds; 16862 } 16863 16864 private Set getProfileIdsLocked(int userId) { 16865 Set userIds = new HashSet<Integer>(); 16866 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16867 userId, false /* enabledOnly */); 16868 for (UserInfo user : profiles) { 16869 userIds.add(Integer.valueOf(user.id)); 16870 } 16871 return userIds; 16872 } 16873 16874 @Override 16875 public boolean switchUser(final int userId) { 16876 return startUser(userId, /* foregound */ true); 16877 } 16878 16879 private boolean startUser(final int userId, boolean foreground) { 16880 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16881 != PackageManager.PERMISSION_GRANTED) { 16882 String msg = "Permission Denial: switchUser() from pid=" 16883 + Binder.getCallingPid() 16884 + ", uid=" + Binder.getCallingUid() 16885 + " requires " + INTERACT_ACROSS_USERS_FULL; 16886 Slog.w(TAG, msg); 16887 throw new SecurityException(msg); 16888 } 16889 16890 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16891 16892 final long ident = Binder.clearCallingIdentity(); 16893 try { 16894 synchronized (this) { 16895 final int oldUserId = mCurrentUserId; 16896 if (oldUserId == userId) { 16897 return true; 16898 } 16899 16900 mStackSupervisor.setLockTaskModeLocked(null, false); 16901 16902 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16903 if (userInfo == null) { 16904 Slog.w(TAG, "No user info for user #" + userId); 16905 return false; 16906 } 16907 16908 if (foreground) { 16909 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16910 R.anim.screen_user_enter); 16911 } 16912 16913 boolean needStart = false; 16914 16915 // If the user we are switching to is not currently started, then 16916 // we need to start it now. 16917 if (mStartedUsers.get(userId) == null) { 16918 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16919 updateStartedUserArrayLocked(); 16920 needStart = true; 16921 } 16922 16923 final Integer userIdInt = Integer.valueOf(userId); 16924 mUserLru.remove(userIdInt); 16925 mUserLru.add(userIdInt); 16926 16927 if (foreground) { 16928 mCurrentUserId = userId; 16929 updateCurrentProfileIdsLocked(); 16930 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16931 // Once the internal notion of the active user has switched, we lock the device 16932 // with the option to show the user switcher on the keyguard. 16933 mWindowManager.lockNow(null); 16934 } else { 16935 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16936 updateCurrentProfileIdsLocked(); 16937 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16938 mUserLru.remove(currentUserIdInt); 16939 mUserLru.add(currentUserIdInt); 16940 } 16941 16942 final UserStartedState uss = mStartedUsers.get(userId); 16943 16944 // Make sure user is in the started state. If it is currently 16945 // stopping, we need to knock that off. 16946 if (uss.mState == UserStartedState.STATE_STOPPING) { 16947 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16948 // so we can just fairly silently bring the user back from 16949 // the almost-dead. 16950 uss.mState = UserStartedState.STATE_RUNNING; 16951 updateStartedUserArrayLocked(); 16952 needStart = true; 16953 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16954 // This means ACTION_SHUTDOWN has been sent, so we will 16955 // need to treat this as a new boot of the user. 16956 uss.mState = UserStartedState.STATE_BOOTING; 16957 updateStartedUserArrayLocked(); 16958 needStart = true; 16959 } 16960 16961 if (uss.mState == UserStartedState.STATE_BOOTING) { 16962 // Booting up a new user, need to tell system services about it. 16963 // Note that this is on the same handler as scheduling of broadcasts, 16964 // which is important because it needs to go first. 16965 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16966 } 16967 16968 if (foreground) { 16969 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16970 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16971 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16972 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16973 oldUserId, userId, uss)); 16974 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16975 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16976 } 16977 16978 if (needStart) { 16979 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16980 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16981 | Intent.FLAG_RECEIVER_FOREGROUND); 16982 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16983 broadcastIntentLocked(null, null, intent, 16984 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16985 false, false, MY_PID, Process.SYSTEM_UID, userId); 16986 } 16987 16988 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16989 if (userId != UserHandle.USER_OWNER) { 16990 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16991 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16992 broadcastIntentLocked(null, null, intent, null, 16993 new IIntentReceiver.Stub() { 16994 public void performReceive(Intent intent, int resultCode, 16995 String data, Bundle extras, boolean ordered, 16996 boolean sticky, int sendingUser) { 16997 userInitialized(uss, userId); 16998 } 16999 }, 0, null, null, null, AppOpsManager.OP_NONE, 17000 true, false, MY_PID, Process.SYSTEM_UID, 17001 userId); 17002 uss.initializing = true; 17003 } else { 17004 getUserManagerLocked().makeInitialized(userInfo.id); 17005 } 17006 } 17007 17008 if (foreground) { 17009 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17010 if (homeInFront) { 17011 startHomeActivityLocked(userId); 17012 } else { 17013 mStackSupervisor.resumeTopActivitiesLocked(); 17014 } 17015 EventLogTags.writeAmSwitchUser(userId); 17016 getUserManagerLocked().userForeground(userId); 17017 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17018 } else { 17019 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17020 } 17021 17022 if (needStart) { 17023 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17024 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17025 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17026 broadcastIntentLocked(null, null, intent, 17027 null, new IIntentReceiver.Stub() { 17028 @Override 17029 public void performReceive(Intent intent, int resultCode, String data, 17030 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17031 throws RemoteException { 17032 } 17033 }, 0, null, null, 17034 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17035 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17036 } 17037 } 17038 } finally { 17039 Binder.restoreCallingIdentity(ident); 17040 } 17041 17042 return true; 17043 } 17044 17045 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17046 long ident = Binder.clearCallingIdentity(); 17047 try { 17048 Intent intent; 17049 if (oldUserId >= 0) { 17050 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17051 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17052 int count = profiles.size(); 17053 for (int i = 0; i < count; i++) { 17054 int profileUserId = profiles.get(i).id; 17055 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17056 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17057 | Intent.FLAG_RECEIVER_FOREGROUND); 17058 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17059 broadcastIntentLocked(null, null, intent, 17060 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17061 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17062 } 17063 } 17064 if (newUserId >= 0) { 17065 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17066 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17067 int count = profiles.size(); 17068 for (int i = 0; i < count; i++) { 17069 int profileUserId = profiles.get(i).id; 17070 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17071 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17072 | Intent.FLAG_RECEIVER_FOREGROUND); 17073 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17074 broadcastIntentLocked(null, null, intent, 17075 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17076 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17077 } 17078 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17079 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17080 | Intent.FLAG_RECEIVER_FOREGROUND); 17081 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17082 broadcastIntentLocked(null, null, intent, 17083 null, null, 0, null, null, 17084 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17085 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17086 } 17087 } finally { 17088 Binder.restoreCallingIdentity(ident); 17089 } 17090 } 17091 17092 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17093 final int newUserId) { 17094 final int N = mUserSwitchObservers.beginBroadcast(); 17095 if (N > 0) { 17096 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17097 int mCount = 0; 17098 @Override 17099 public void sendResult(Bundle data) throws RemoteException { 17100 synchronized (ActivityManagerService.this) { 17101 if (mCurUserSwitchCallback == this) { 17102 mCount++; 17103 if (mCount == N) { 17104 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17105 } 17106 } 17107 } 17108 } 17109 }; 17110 synchronized (this) { 17111 uss.switching = true; 17112 mCurUserSwitchCallback = callback; 17113 } 17114 for (int i=0; i<N; i++) { 17115 try { 17116 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17117 newUserId, callback); 17118 } catch (RemoteException e) { 17119 } 17120 } 17121 } else { 17122 synchronized (this) { 17123 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17124 } 17125 } 17126 mUserSwitchObservers.finishBroadcast(); 17127 } 17128 17129 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17130 synchronized (this) { 17131 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17132 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17133 } 17134 } 17135 17136 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17137 mCurUserSwitchCallback = null; 17138 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17139 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17140 oldUserId, newUserId, uss)); 17141 } 17142 17143 void userInitialized(UserStartedState uss, int newUserId) { 17144 completeSwitchAndInitalize(uss, newUserId, true, false); 17145 } 17146 17147 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17148 completeSwitchAndInitalize(uss, newUserId, false, true); 17149 } 17150 17151 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17152 boolean clearInitializing, boolean clearSwitching) { 17153 boolean unfrozen = false; 17154 synchronized (this) { 17155 if (clearInitializing) { 17156 uss.initializing = false; 17157 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17158 } 17159 if (clearSwitching) { 17160 uss.switching = false; 17161 } 17162 if (!uss.switching && !uss.initializing) { 17163 mWindowManager.stopFreezingScreen(); 17164 unfrozen = true; 17165 } 17166 } 17167 if (unfrozen) { 17168 final int N = mUserSwitchObservers.beginBroadcast(); 17169 for (int i=0; i<N; i++) { 17170 try { 17171 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17172 } catch (RemoteException e) { 17173 } 17174 } 17175 mUserSwitchObservers.finishBroadcast(); 17176 } 17177 } 17178 17179 void scheduleStartProfilesLocked() { 17180 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17181 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17182 DateUtils.SECOND_IN_MILLIS); 17183 } 17184 } 17185 17186 void startProfilesLocked() { 17187 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17188 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17189 mCurrentUserId, false /* enabledOnly */); 17190 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17191 for (UserInfo user : profiles) { 17192 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17193 && user.id != mCurrentUserId) { 17194 toStart.add(user); 17195 } 17196 } 17197 final int n = toStart.size(); 17198 int i = 0; 17199 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17200 startUserInBackground(toStart.get(i).id); 17201 } 17202 if (i < n) { 17203 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17204 } 17205 } 17206 17207 void finishUserBoot(UserStartedState uss) { 17208 synchronized (this) { 17209 if (uss.mState == UserStartedState.STATE_BOOTING 17210 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17211 uss.mState = UserStartedState.STATE_RUNNING; 17212 final int userId = uss.mHandle.getIdentifier(); 17213 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17214 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17215 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17216 broadcastIntentLocked(null, null, intent, 17217 null, null, 0, null, null, 17218 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17219 true, false, MY_PID, Process.SYSTEM_UID, userId); 17220 } 17221 } 17222 } 17223 17224 void finishUserSwitch(UserStartedState uss) { 17225 synchronized (this) { 17226 finishUserBoot(uss); 17227 17228 startProfilesLocked(); 17229 17230 int num = mUserLru.size(); 17231 int i = 0; 17232 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17233 Integer oldUserId = mUserLru.get(i); 17234 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17235 if (oldUss == null) { 17236 // Shouldn't happen, but be sane if it does. 17237 mUserLru.remove(i); 17238 num--; 17239 continue; 17240 } 17241 if (oldUss.mState == UserStartedState.STATE_STOPPING 17242 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17243 // This user is already stopping, doesn't count. 17244 num--; 17245 i++; 17246 continue; 17247 } 17248 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17249 // Owner and current can't be stopped, but count as running. 17250 i++; 17251 continue; 17252 } 17253 // This is a user to be stopped. 17254 stopUserLocked(oldUserId, null); 17255 num--; 17256 i++; 17257 } 17258 } 17259 } 17260 17261 @Override 17262 public int stopUser(final int userId, final IStopUserCallback callback) { 17263 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17264 != PackageManager.PERMISSION_GRANTED) { 17265 String msg = "Permission Denial: switchUser() from pid=" 17266 + Binder.getCallingPid() 17267 + ", uid=" + Binder.getCallingUid() 17268 + " requires " + INTERACT_ACROSS_USERS_FULL; 17269 Slog.w(TAG, msg); 17270 throw new SecurityException(msg); 17271 } 17272 if (userId <= 0) { 17273 throw new IllegalArgumentException("Can't stop primary user " + userId); 17274 } 17275 synchronized (this) { 17276 return stopUserLocked(userId, callback); 17277 } 17278 } 17279 17280 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17281 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17282 if (mCurrentUserId == userId) { 17283 return ActivityManager.USER_OP_IS_CURRENT; 17284 } 17285 17286 final UserStartedState uss = mStartedUsers.get(userId); 17287 if (uss == null) { 17288 // User is not started, nothing to do... but we do need to 17289 // callback if requested. 17290 if (callback != null) { 17291 mHandler.post(new Runnable() { 17292 @Override 17293 public void run() { 17294 try { 17295 callback.userStopped(userId); 17296 } catch (RemoteException e) { 17297 } 17298 } 17299 }); 17300 } 17301 return ActivityManager.USER_OP_SUCCESS; 17302 } 17303 17304 if (callback != null) { 17305 uss.mStopCallbacks.add(callback); 17306 } 17307 17308 if (uss.mState != UserStartedState.STATE_STOPPING 17309 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17310 uss.mState = UserStartedState.STATE_STOPPING; 17311 updateStartedUserArrayLocked(); 17312 17313 long ident = Binder.clearCallingIdentity(); 17314 try { 17315 // We are going to broadcast ACTION_USER_STOPPING and then 17316 // once that is done send a final ACTION_SHUTDOWN and then 17317 // stop the user. 17318 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17319 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17320 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17321 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17322 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17323 // This is the result receiver for the final shutdown broadcast. 17324 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17325 @Override 17326 public void performReceive(Intent intent, int resultCode, String data, 17327 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17328 finishUserStop(uss); 17329 } 17330 }; 17331 // This is the result receiver for the initial stopping broadcast. 17332 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17333 @Override 17334 public void performReceive(Intent intent, int resultCode, String data, 17335 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17336 // On to the next. 17337 synchronized (ActivityManagerService.this) { 17338 if (uss.mState != UserStartedState.STATE_STOPPING) { 17339 // Whoops, we are being started back up. Abort, abort! 17340 return; 17341 } 17342 uss.mState = UserStartedState.STATE_SHUTDOWN; 17343 } 17344 mSystemServiceManager.stopUser(userId); 17345 broadcastIntentLocked(null, null, shutdownIntent, 17346 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17347 true, false, MY_PID, Process.SYSTEM_UID, userId); 17348 } 17349 }; 17350 // Kick things off. 17351 broadcastIntentLocked(null, null, stoppingIntent, 17352 null, stoppingReceiver, 0, null, null, 17353 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17354 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17355 } finally { 17356 Binder.restoreCallingIdentity(ident); 17357 } 17358 } 17359 17360 return ActivityManager.USER_OP_SUCCESS; 17361 } 17362 17363 void finishUserStop(UserStartedState uss) { 17364 final int userId = uss.mHandle.getIdentifier(); 17365 boolean stopped; 17366 ArrayList<IStopUserCallback> callbacks; 17367 synchronized (this) { 17368 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17369 if (mStartedUsers.get(userId) != uss) { 17370 stopped = false; 17371 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17372 stopped = false; 17373 } else { 17374 stopped = true; 17375 // User can no longer run. 17376 mStartedUsers.remove(userId); 17377 mUserLru.remove(Integer.valueOf(userId)); 17378 updateStartedUserArrayLocked(); 17379 17380 // Clean up all state and processes associated with the user. 17381 // Kill all the processes for the user. 17382 forceStopUserLocked(userId, "finish user"); 17383 } 17384 } 17385 17386 for (int i=0; i<callbacks.size(); i++) { 17387 try { 17388 if (stopped) callbacks.get(i).userStopped(userId); 17389 else callbacks.get(i).userStopAborted(userId); 17390 } catch (RemoteException e) { 17391 } 17392 } 17393 17394 if (stopped) { 17395 mSystemServiceManager.cleanupUser(userId); 17396 synchronized (this) { 17397 mStackSupervisor.removeUserLocked(userId); 17398 } 17399 } 17400 } 17401 17402 @Override 17403 public UserInfo getCurrentUser() { 17404 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17405 != PackageManager.PERMISSION_GRANTED) && ( 17406 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17407 != PackageManager.PERMISSION_GRANTED)) { 17408 String msg = "Permission Denial: getCurrentUser() from pid=" 17409 + Binder.getCallingPid() 17410 + ", uid=" + Binder.getCallingUid() 17411 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17412 Slog.w(TAG, msg); 17413 throw new SecurityException(msg); 17414 } 17415 synchronized (this) { 17416 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17417 } 17418 } 17419 17420 int getCurrentUserIdLocked() { 17421 return mCurrentUserId; 17422 } 17423 17424 @Override 17425 public boolean isUserRunning(int userId, boolean orStopped) { 17426 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17427 != PackageManager.PERMISSION_GRANTED) { 17428 String msg = "Permission Denial: isUserRunning() from pid=" 17429 + Binder.getCallingPid() 17430 + ", uid=" + Binder.getCallingUid() 17431 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17432 Slog.w(TAG, msg); 17433 throw new SecurityException(msg); 17434 } 17435 synchronized (this) { 17436 return isUserRunningLocked(userId, orStopped); 17437 } 17438 } 17439 17440 boolean isUserRunningLocked(int userId, boolean orStopped) { 17441 UserStartedState state = mStartedUsers.get(userId); 17442 if (state == null) { 17443 return false; 17444 } 17445 if (orStopped) { 17446 return true; 17447 } 17448 return state.mState != UserStartedState.STATE_STOPPING 17449 && state.mState != UserStartedState.STATE_SHUTDOWN; 17450 } 17451 17452 @Override 17453 public int[] getRunningUserIds() { 17454 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17455 != PackageManager.PERMISSION_GRANTED) { 17456 String msg = "Permission Denial: isUserRunning() from pid=" 17457 + Binder.getCallingPid() 17458 + ", uid=" + Binder.getCallingUid() 17459 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17460 Slog.w(TAG, msg); 17461 throw new SecurityException(msg); 17462 } 17463 synchronized (this) { 17464 return mStartedUserArray; 17465 } 17466 } 17467 17468 private void updateStartedUserArrayLocked() { 17469 int num = 0; 17470 for (int i=0; i<mStartedUsers.size(); i++) { 17471 UserStartedState uss = mStartedUsers.valueAt(i); 17472 // This list does not include stopping users. 17473 if (uss.mState != UserStartedState.STATE_STOPPING 17474 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17475 num++; 17476 } 17477 } 17478 mStartedUserArray = new int[num]; 17479 num = 0; 17480 for (int i=0; i<mStartedUsers.size(); i++) { 17481 UserStartedState uss = mStartedUsers.valueAt(i); 17482 if (uss.mState != UserStartedState.STATE_STOPPING 17483 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17484 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17485 num++; 17486 } 17487 } 17488 } 17489 17490 @Override 17491 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17492 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17493 != PackageManager.PERMISSION_GRANTED) { 17494 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17495 + Binder.getCallingPid() 17496 + ", uid=" + Binder.getCallingUid() 17497 + " requires " + INTERACT_ACROSS_USERS_FULL; 17498 Slog.w(TAG, msg); 17499 throw new SecurityException(msg); 17500 } 17501 17502 mUserSwitchObservers.register(observer); 17503 } 17504 17505 @Override 17506 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17507 mUserSwitchObservers.unregister(observer); 17508 } 17509 17510 private boolean userExists(int userId) { 17511 if (userId == 0) { 17512 return true; 17513 } 17514 UserManagerService ums = getUserManagerLocked(); 17515 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17516 } 17517 17518 int[] getUsersLocked() { 17519 UserManagerService ums = getUserManagerLocked(); 17520 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17521 } 17522 17523 UserManagerService getUserManagerLocked() { 17524 if (mUserManager == null) { 17525 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17526 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17527 } 17528 return mUserManager; 17529 } 17530 17531 private int applyUserId(int uid, int userId) { 17532 return UserHandle.getUid(userId, uid); 17533 } 17534 17535 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17536 if (info == null) return null; 17537 ApplicationInfo newInfo = new ApplicationInfo(info); 17538 newInfo.uid = applyUserId(info.uid, userId); 17539 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17540 + info.packageName; 17541 return newInfo; 17542 } 17543 17544 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17545 if (aInfo == null 17546 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17547 return aInfo; 17548 } 17549 17550 ActivityInfo info = new ActivityInfo(aInfo); 17551 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17552 return info; 17553 } 17554 17555 private final class LocalService extends ActivityManagerInternal { 17556 @Override 17557 public void goingToSleep() { 17558 ActivityManagerService.this.goingToSleep(); 17559 } 17560 17561 @Override 17562 public void wakingUp() { 17563 ActivityManagerService.this.wakingUp(); 17564 } 17565 } 17566 17567 /** 17568 * An implementation of IAppTask, that allows an app to manage its own tasks via 17569 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17570 * only the process that calls getAppTasks() can call the AppTask methods. 17571 */ 17572 class AppTaskImpl extends IAppTask.Stub { 17573 private int mTaskId; 17574 private int mCallingUid; 17575 17576 public AppTaskImpl(int taskId, int callingUid) { 17577 mTaskId = taskId; 17578 mCallingUid = callingUid; 17579 } 17580 17581 @Override 17582 public void finishAndRemoveTask() { 17583 // Ensure that we are called from the same process that created this AppTask 17584 if (mCallingUid != Binder.getCallingUid()) { 17585 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17586 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17587 return; 17588 } 17589 17590 synchronized (ActivityManagerService.this) { 17591 long origId = Binder.clearCallingIdentity(); 17592 try { 17593 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17594 if (tr != null) { 17595 // Only kill the process if we are not a new document 17596 int flags = tr.getBaseIntent().getFlags(); 17597 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17598 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17599 removeTaskByIdLocked(mTaskId, 17600 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17601 } 17602 } finally { 17603 Binder.restoreCallingIdentity(origId); 17604 } 17605 } 17606 } 17607 17608 @Override 17609 public ActivityManager.RecentTaskInfo getTaskInfo() { 17610 // Ensure that we are called from the same process that created this AppTask 17611 if (mCallingUid != Binder.getCallingUid()) { 17612 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17613 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17614 return null; 17615 } 17616 17617 synchronized (ActivityManagerService.this) { 17618 long origId = Binder.clearCallingIdentity(); 17619 try { 17620 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17621 if (tr != null) { 17622 return createRecentTaskInfoFromTaskRecord(tr); 17623 } 17624 } finally { 17625 Binder.restoreCallingIdentity(origId); 17626 } 17627 return null; 17628 } 17629 } 17630 } 17631} 17632