ActivityManagerService.java revision f7097a5b697fedb6976774e55a51471405a23c0e
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200; 274 275 // Amount of time after a call to stopAppSwitches() during which we will 276 // prevent further untrusted switches from happening. 277 static final long APP_SWITCH_DELAY_TIME = 5*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real. 281 static final int PROC_START_TIMEOUT = 10*1000; 282 283 // How long we wait for a launched process to attach to the activity manager 284 // before we decide it's never going to come up for real, when the process was 285 // started with a wrapper for instrumentation (such as Valgrind) because it 286 // could take much longer than usual. 287 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 288 289 // How long to wait after going idle before forcing apps to GC. 290 static final int GC_TIMEOUT = 5*1000; 291 292 // The minimum amount of time between successive GC requests for a process. 293 static final int GC_MIN_INTERVAL = 60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process. 296 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process 299 // when the request is due to the memory state being lowered. 300 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 301 302 // The rate at which we check for apps using excessive power -- 15 mins. 303 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on wake locks to start killing things. 307 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // The minimum sample duration we will allow before deciding we have 310 // enough data on CPU usage to start killing things. 311 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 312 313 // How long we allow a receiver to run before giving up on it. 314 static final int BROADCAST_FG_TIMEOUT = 10*1000; 315 static final int BROADCAST_BG_TIMEOUT = 60*1000; 316 317 // How long we wait until we timeout on key dispatching. 318 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 319 320 // How long we wait until we timeout on key dispatching during instrumentation. 321 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 322 323 // Amount of time we wait for observers to handle a user switch before 324 // giving up on them and unfreezing the screen. 325 static final int USER_SWITCH_TIMEOUT = 2*1000; 326 327 // Maximum number of users we allow to be running at a time. 328 static final int MAX_RUNNING_USERS = 3; 329 330 // How long to wait in getAssistContextExtras for the activity and foreground services 331 // to respond with the result. 332 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 333 334 // Maximum number of persisted Uri grants a package is allowed 335 static final int MAX_PERSISTED_URI_GRANTS = 128; 336 337 static final int MY_PID = Process.myPid(); 338 339 static final String[] EMPTY_STRING_ARRAY = new String[0]; 340 341 // How many bytes to write into the dropbox log before truncating 342 static final int DROPBOX_MAX_SIZE = 256 * 1024; 343 344 /** All system services */ 345 SystemServiceManager mSystemServiceManager; 346 347 /** Run all ActivityStacks through this */ 348 ActivityStackSupervisor mStackSupervisor; 349 350 public IntentFirewall mIntentFirewall; 351 352 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 353 // default actuion automatically. Important for devices without direct input 354 // devices. 355 private boolean mShowDialogs = true; 356 357 /** 358 * Description of a request to start a new activity, which has been held 359 * due to app switches being disabled. 360 */ 361 static class PendingActivityLaunch { 362 final ActivityRecord r; 363 final ActivityRecord sourceRecord; 364 final int startFlags; 365 final ActivityStack stack; 366 367 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 368 int _startFlags, ActivityStack _stack) { 369 r = _r; 370 sourceRecord = _sourceRecord; 371 startFlags = _startFlags; 372 stack = _stack; 373 } 374 } 375 376 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 377 = new ArrayList<PendingActivityLaunch>(); 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 415 public class PendingAssistExtras extends Binder implements Runnable { 416 public final ActivityRecord activity; 417 public boolean haveResult = false; 418 public Bundle result = null; 419 public PendingAssistExtras(ActivityRecord _activity) { 420 activity = _activity; 421 } 422 @Override 423 public void run() { 424 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 425 synchronized (this) { 426 haveResult = true; 427 notifyAll(); 428 } 429 } 430 } 431 432 final ArrayList<PendingAssistExtras> mPendingAssistExtras 433 = new ArrayList<PendingAssistExtras>(); 434 435 /** 436 * Process management. 437 */ 438 final ProcessList mProcessList = new ProcessList(); 439 440 /** 441 * All of the applications we currently have running organized by name. 442 * The keys are strings of the application package name (as 443 * returned by the package manager), and the keys are ApplicationRecord 444 * objects. 445 */ 446 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 447 448 /** 449 * Tracking long-term execution of processes to look for abuse and other 450 * bad app behavior. 451 */ 452 final ProcessStatsService mProcessStats; 453 454 /** 455 * The currently running isolated processes. 456 */ 457 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 458 459 /** 460 * Counter for assigning isolated process uids, to avoid frequently reusing the 461 * same ones. 462 */ 463 int mNextIsolatedProcessUid = 0; 464 465 /** 466 * The currently running heavy-weight process, if any. 467 */ 468 ProcessRecord mHeavyWeightProcess = null; 469 470 /** 471 * The last time that various processes have crashed. 472 */ 473 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 474 475 /** 476 * Information about a process that is currently marked as bad. 477 */ 478 static final class BadProcessInfo { 479 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 480 this.time = time; 481 this.shortMsg = shortMsg; 482 this.longMsg = longMsg; 483 this.stack = stack; 484 } 485 486 final long time; 487 final String shortMsg; 488 final String longMsg; 489 final String stack; 490 } 491 492 /** 493 * Set of applications that we consider to be bad, and will reject 494 * incoming broadcasts from (which the user has no control over). 495 * Processes are added to this set when they have crashed twice within 496 * a minimum amount of time; they are removed from it when they are 497 * later restarted (hopefully due to some user action). The value is the 498 * time it was added to the list. 499 */ 500 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 501 502 /** 503 * All of the processes we currently have running organized by pid. 504 * The keys are the pid running the application. 505 * 506 * <p>NOTE: This object is protected by its own lock, NOT the global 507 * activity manager lock! 508 */ 509 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 510 511 /** 512 * All of the processes that have been forced to be foreground. The key 513 * is the pid of the caller who requested it (we hold a death 514 * link on it). 515 */ 516 abstract class ForegroundToken implements IBinder.DeathRecipient { 517 int pid; 518 IBinder token; 519 } 520 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 521 522 /** 523 * List of records for processes that someone had tried to start before the 524 * system was ready. We don't start them at that point, but ensure they 525 * are started by the time booting is complete. 526 */ 527 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of persistent applications that are in the process 531 * of being started. 532 */ 533 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Processes that are being forcibly torn down. 537 */ 538 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 539 540 /** 541 * List of running applications, sorted by recent usage. 542 * The first entry in the list is the least recently used. 543 */ 544 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Where in mLruProcesses that the processes hosting activities start. 548 */ 549 int mLruProcessActivityStart = 0; 550 551 /** 552 * Where in mLruProcesses that the processes hosting services start. 553 * This is after (lower index) than mLruProcessesActivityStart. 554 */ 555 int mLruProcessServiceStart = 0; 556 557 /** 558 * List of processes that should gc as soon as things are idle. 559 */ 560 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Processes we want to collect PSS data from. 564 */ 565 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 566 567 /** 568 * Last time we requested PSS data of all processes. 569 */ 570 long mLastFullPssTime = SystemClock.uptimeMillis(); 571 572 /** 573 * If set, the next time we collect PSS data we should do a full collection 574 * with data from native processes and the kernel. 575 */ 576 boolean mFullPssPending = false; 577 578 /** 579 * This is the process holding what we currently consider to be 580 * the "home" activity. 581 */ 582 ProcessRecord mHomeProcess; 583 584 /** 585 * This is the process holding the activity the user last visited that 586 * is in a different process from the one they are currently in. 587 */ 588 ProcessRecord mPreviousProcess; 589 590 /** 591 * The time at which the previous process was last visible. 592 */ 593 long mPreviousProcessVisibleTime; 594 595 /** 596 * Which uses have been started, so are allowed to run code. 597 */ 598 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 599 600 /** 601 * LRU list of history of current users. Most recently current is at the end. 602 */ 603 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 604 605 /** 606 * Constant array of the users that are currently started. 607 */ 608 int[] mStartedUserArray = new int[] { 0 }; 609 610 /** 611 * Registered observers of the user switching mechanics. 612 */ 613 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 614 = new RemoteCallbackList<IUserSwitchObserver>(); 615 616 /** 617 * Currently active user switch. 618 */ 619 Object mCurUserSwitchCallback; 620 621 /** 622 * Packages that the user has asked to have run in screen size 623 * compatibility mode instead of filling the screen. 624 */ 625 final CompatModePackages mCompatModePackages; 626 627 /** 628 * Set of IntentSenderRecord objects that are currently active. 629 */ 630 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 631 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 632 633 /** 634 * Fingerprints (hashCode()) of stack traces that we've 635 * already logged DropBox entries for. Guarded by itself. If 636 * something (rogue user app) forces this over 637 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 638 */ 639 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 640 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 641 642 /** 643 * Strict Mode background batched logging state. 644 * 645 * The string buffer is guarded by itself, and its lock is also 646 * used to determine if another batched write is already 647 * in-flight. 648 */ 649 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 650 651 /** 652 * Keeps track of all IIntentReceivers that have been registered for 653 * broadcasts. Hash keys are the receiver IBinder, hash value is 654 * a ReceiverList. 655 */ 656 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 657 new HashMap<IBinder, ReceiverList>(); 658 659 /** 660 * Resolver for broadcast intents to registered receivers. 661 * Holds BroadcastFilter (subclass of IntentFilter). 662 */ 663 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 664 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 665 @Override 666 protected boolean allowFilterResult( 667 BroadcastFilter filter, List<BroadcastFilter> dest) { 668 IBinder target = filter.receiverList.receiver.asBinder(); 669 for (int i=dest.size()-1; i>=0; i--) { 670 if (dest.get(i).receiverList.receiver.asBinder() == target) { 671 return false; 672 } 673 } 674 return true; 675 } 676 677 @Override 678 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 679 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 680 || userId == filter.owningUserId) { 681 return super.newResult(filter, match, userId); 682 } 683 return null; 684 } 685 686 @Override 687 protected BroadcastFilter[] newArray(int size) { 688 return new BroadcastFilter[size]; 689 } 690 691 @Override 692 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 693 return packageName.equals(filter.packageName); 694 } 695 }; 696 697 /** 698 * State of all active sticky broadcasts per user. Keys are the action of the 699 * sticky Intent, values are an ArrayList of all broadcasted intents with 700 * that action (which should usually be one). The SparseArray is keyed 701 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 702 * for stickies that are sent to all users. 703 */ 704 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 705 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 706 707 final ActiveServices mServices; 708 709 /** 710 * Backup/restore process management 711 */ 712 String mBackupAppName = null; 713 BackupRecord mBackupTarget = null; 714 715 final ProviderMap mProviderMap; 716 717 /** 718 * List of content providers who have clients waiting for them. The 719 * application is currently being launched and the provider will be 720 * removed from this list once it is published. 721 */ 722 final ArrayList<ContentProviderRecord> mLaunchingProviders 723 = new ArrayList<ContentProviderRecord>(); 724 725 /** 726 * File storing persisted {@link #mGrantedUriPermissions}. 727 */ 728 private final AtomicFile mGrantFile; 729 730 /** XML constants used in {@link #mGrantFile} */ 731 private static final String TAG_URI_GRANTS = "uri-grants"; 732 private static final String TAG_URI_GRANT = "uri-grant"; 733 private static final String ATTR_USER_HANDLE = "userHandle"; 734 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 735 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 736 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 737 private static final String ATTR_TARGET_PKG = "targetPkg"; 738 private static final String ATTR_URI = "uri"; 739 private static final String ATTR_MODE_FLAGS = "modeFlags"; 740 private static final String ATTR_CREATED_TIME = "createdTime"; 741 private static final String ATTR_PREFIX = "prefix"; 742 743 /** 744 * Global set of specific {@link Uri} permissions that have been granted. 745 * This optimized lookup structure maps from {@link UriPermission#targetUid} 746 * to {@link UriPermission#uri} to {@link UriPermission}. 747 */ 748 @GuardedBy("this") 749 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 750 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 751 752 public static class GrantUri { 753 public final int sourceUserId; 754 public final Uri uri; 755 public boolean prefix; 756 757 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 758 this.sourceUserId = sourceUserId; 759 this.uri = uri; 760 this.prefix = prefix; 761 } 762 763 @Override 764 public int hashCode() { 765 return toString().hashCode(); 766 } 767 768 @Override 769 public boolean equals(Object o) { 770 if (o instanceof GrantUri) { 771 GrantUri other = (GrantUri) o; 772 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 773 && prefix == other.prefix; 774 } 775 return false; 776 } 777 778 @Override 779 public String toString() { 780 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 781 if (prefix) result += " [prefix]"; 782 return result; 783 } 784 785 public String toSafeString() { 786 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 787 if (prefix) result += " [prefix]"; 788 return result; 789 } 790 791 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 792 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 793 ContentProvider.getUriWithoutUserId(uri), false); 794 } 795 } 796 797 CoreSettingsObserver mCoreSettingsObserver; 798 799 /** 800 * Thread-local storage used to carry caller permissions over through 801 * indirect content-provider access. 802 */ 803 private class Identity { 804 public int pid; 805 public int uid; 806 807 Identity(int _pid, int _uid) { 808 pid = _pid; 809 uid = _uid; 810 } 811 } 812 813 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 814 815 /** 816 * All information we have collected about the runtime performance of 817 * any user id that can impact battery performance. 818 */ 819 final BatteryStatsService mBatteryStatsService; 820 821 /** 822 * Information about component usage 823 */ 824 final UsageStatsService mUsageStatsService; 825 826 /** 827 * Information about and control over application operations 828 */ 829 final AppOpsService mAppOpsService; 830 831 /** 832 * Save recent tasks information across reboots. 833 */ 834 final TaskPersister mTaskPersister; 835 836 /** 837 * Current configuration information. HistoryRecord objects are given 838 * a reference to this object to indicate which configuration they are 839 * currently running in, so this object must be kept immutable. 840 */ 841 Configuration mConfiguration = new Configuration(); 842 843 /** 844 * Current sequencing integer of the configuration, for skipping old 845 * configurations. 846 */ 847 int mConfigurationSeq = 0; 848 849 /** 850 * Hardware-reported OpenGLES version. 851 */ 852 final int GL_ES_VERSION; 853 854 /** 855 * List of initialization arguments to pass to all processes when binding applications to them. 856 * For example, references to the commonly used services. 857 */ 858 HashMap<String, IBinder> mAppBindArgs; 859 860 /** 861 * Temporary to avoid allocations. Protected by main lock. 862 */ 863 final StringBuilder mStringBuilder = new StringBuilder(256); 864 865 /** 866 * Used to control how we initialize the service. 867 */ 868 ComponentName mTopComponent; 869 String mTopAction = Intent.ACTION_MAIN; 870 String mTopData; 871 boolean mProcessesReady = false; 872 boolean mSystemReady = false; 873 boolean mBooting = false; 874 boolean mWaitingUpdate = false; 875 boolean mDidUpdate = false; 876 boolean mOnBattery = false; 877 boolean mLaunchWarningShown = false; 878 879 Context mContext; 880 881 int mFactoryTest; 882 883 boolean mCheckedForSetup; 884 885 /** 886 * The time at which we will allow normal application switches again, 887 * after a call to {@link #stopAppSwitches()}. 888 */ 889 long mAppSwitchesAllowedTime; 890 891 /** 892 * This is set to true after the first switch after mAppSwitchesAllowedTime 893 * is set; any switches after that will clear the time. 894 */ 895 boolean mDidAppSwitch; 896 897 /** 898 * Last time (in realtime) at which we checked for power usage. 899 */ 900 long mLastPowerCheckRealtime; 901 902 /** 903 * Last time (in uptime) at which we checked for power usage. 904 */ 905 long mLastPowerCheckUptime; 906 907 /** 908 * Set while we are wanting to sleep, to prevent any 909 * activities from being started/resumed. 910 */ 911 private boolean mSleeping = false; 912 913 /** 914 * Set while we are running a voice interaction. This overrides 915 * sleeping while it is active. 916 */ 917 private boolean mRunningVoice = false; 918 919 /** 920 * State of external calls telling us if the device is asleep. 921 */ 922 private boolean mWentToSleep = false; 923 924 /** 925 * State of external call telling us if the lock screen is shown. 926 */ 927 private boolean mLockScreenShown = false; 928 929 /** 930 * Set if we are shutting down the system, similar to sleeping. 931 */ 932 boolean mShuttingDown = false; 933 934 /** 935 * Current sequence id for oom_adj computation traversal. 936 */ 937 int mAdjSeq = 0; 938 939 /** 940 * Current sequence id for process LRU updating. 941 */ 942 int mLruSeq = 0; 943 944 /** 945 * Keep track of the non-cached/empty process we last found, to help 946 * determine how to distribute cached/empty processes next time. 947 */ 948 int mNumNonCachedProcs = 0; 949 950 /** 951 * Keep track of the number of cached hidden procs, to balance oom adj 952 * distribution between those and empty procs. 953 */ 954 int mNumCachedHiddenProcs = 0; 955 956 /** 957 * Keep track of the number of service processes we last found, to 958 * determine on the next iteration which should be B services. 959 */ 960 int mNumServiceProcs = 0; 961 int mNewNumAServiceProcs = 0; 962 int mNewNumServiceProcs = 0; 963 964 /** 965 * Allow the current computed overall memory level of the system to go down? 966 * This is set to false when we are killing processes for reasons other than 967 * memory management, so that the now smaller process list will not be taken as 968 * an indication that memory is tighter. 969 */ 970 boolean mAllowLowerMemLevel = false; 971 972 /** 973 * The last computed memory level, for holding when we are in a state that 974 * processes are going away for other reasons. 975 */ 976 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 977 978 /** 979 * The last total number of process we have, to determine if changes actually look 980 * like a shrinking number of process due to lower RAM. 981 */ 982 int mLastNumProcesses; 983 984 /** 985 * The uptime of the last time we performed idle maintenance. 986 */ 987 long mLastIdleTime = SystemClock.uptimeMillis(); 988 989 /** 990 * Total time spent with RAM that has been added in the past since the last idle time. 991 */ 992 long mLowRamTimeSinceLastIdle = 0; 993 994 /** 995 * If RAM is currently low, when that horrible situation started. 996 */ 997 long mLowRamStartTime = 0; 998 999 /** 1000 * For reporting to battery stats the current top application. 1001 */ 1002 private String mCurResumedPackage = null; 1003 private int mCurResumedUid = -1; 1004 1005 /** 1006 * For reporting to battery stats the apps currently running foreground 1007 * service. The ProcessMap is package/uid tuples; each of these contain 1008 * an array of the currently foreground processes. 1009 */ 1010 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1011 = new ProcessMap<ArrayList<ProcessRecord>>(); 1012 1013 /** 1014 * This is set if we had to do a delayed dexopt of an app before launching 1015 * it, to increase the ANR timeouts in that case. 1016 */ 1017 boolean mDidDexOpt; 1018 1019 /** 1020 * Set if the systemServer made a call to enterSafeMode. 1021 */ 1022 boolean mSafeMode; 1023 1024 String mDebugApp = null; 1025 boolean mWaitForDebugger = false; 1026 boolean mDebugTransient = false; 1027 String mOrigDebugApp = null; 1028 boolean mOrigWaitForDebugger = false; 1029 boolean mAlwaysFinishActivities = false; 1030 IActivityController mController = null; 1031 String mProfileApp = null; 1032 ProcessRecord mProfileProc = null; 1033 String mProfileFile; 1034 ParcelFileDescriptor mProfileFd; 1035 int mProfileType = 0; 1036 boolean mAutoStopProfiler = false; 1037 String mOpenGlTraceApp = null; 1038 1039 static class ProcessChangeItem { 1040 static final int CHANGE_ACTIVITIES = 1<<0; 1041 static final int CHANGE_PROCESS_STATE = 1<<1; 1042 int changes; 1043 int uid; 1044 int pid; 1045 int processState; 1046 boolean foregroundActivities; 1047 } 1048 1049 final RemoteCallbackList<IProcessObserver> mProcessObservers 1050 = new RemoteCallbackList<IProcessObserver>(); 1051 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1052 1053 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1054 = new ArrayList<ProcessChangeItem>(); 1055 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1056 = new ArrayList<ProcessChangeItem>(); 1057 1058 /** 1059 * Runtime CPU use collection thread. This object's lock is used to 1060 * protect all related state. 1061 */ 1062 final Thread mProcessCpuThread; 1063 1064 /** 1065 * Used to collect process stats when showing not responding dialog. 1066 * Protected by mProcessCpuThread. 1067 */ 1068 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1069 MONITOR_THREAD_CPU_USAGE); 1070 final AtomicLong mLastCpuTime = new AtomicLong(0); 1071 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1072 1073 long mLastWriteTime = 0; 1074 1075 /** 1076 * Used to retain an update lock when the foreground activity is in 1077 * immersive mode. 1078 */ 1079 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1080 1081 /** 1082 * Set to true after the system has finished booting. 1083 */ 1084 boolean mBooted = false; 1085 1086 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1087 int mProcessLimitOverride = -1; 1088 1089 WindowManagerService mWindowManager; 1090 1091 final ActivityThread mSystemThread; 1092 1093 int mCurrentUserId = 0; 1094 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1095 private UserManagerService mUserManager; 1096 1097 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1098 final ProcessRecord mApp; 1099 final int mPid; 1100 final IApplicationThread mAppThread; 1101 1102 AppDeathRecipient(ProcessRecord app, int pid, 1103 IApplicationThread thread) { 1104 if (localLOGV) Slog.v( 1105 TAG, "New death recipient " + this 1106 + " for thread " + thread.asBinder()); 1107 mApp = app; 1108 mPid = pid; 1109 mAppThread = thread; 1110 } 1111 1112 @Override 1113 public void binderDied() { 1114 if (localLOGV) Slog.v( 1115 TAG, "Death received in " + this 1116 + " for thread " + mAppThread.asBinder()); 1117 synchronized(ActivityManagerService.this) { 1118 appDiedLocked(mApp, mPid, mAppThread); 1119 } 1120 } 1121 } 1122 1123 static final int SHOW_ERROR_MSG = 1; 1124 static final int SHOW_NOT_RESPONDING_MSG = 2; 1125 static final int SHOW_FACTORY_ERROR_MSG = 3; 1126 static final int UPDATE_CONFIGURATION_MSG = 4; 1127 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1128 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1129 static final int SERVICE_TIMEOUT_MSG = 12; 1130 static final int UPDATE_TIME_ZONE = 13; 1131 static final int SHOW_UID_ERROR_MSG = 14; 1132 static final int IM_FEELING_LUCKY_MSG = 15; 1133 static final int PROC_START_TIMEOUT_MSG = 20; 1134 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1135 static final int KILL_APPLICATION_MSG = 22; 1136 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1137 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1138 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1139 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1140 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1141 static final int CLEAR_DNS_CACHE_MSG = 28; 1142 static final int UPDATE_HTTP_PROXY_MSG = 29; 1143 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1144 static final int DISPATCH_PROCESSES_CHANGED = 31; 1145 static final int DISPATCH_PROCESS_DIED = 32; 1146 static final int REPORT_MEM_USAGE_MSG = 33; 1147 static final int REPORT_USER_SWITCH_MSG = 34; 1148 static final int CONTINUE_USER_SWITCH_MSG = 35; 1149 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1150 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1151 static final int PERSIST_URI_GRANTS_MSG = 38; 1152 static final int REQUEST_ALL_PSS_MSG = 39; 1153 static final int START_PROFILES_MSG = 40; 1154 static final int UPDATE_TIME = 41; 1155 static final int SYSTEM_USER_START_MSG = 42; 1156 static final int SYSTEM_USER_CURRENT_MSG = 43; 1157 1158 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1159 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1160 static final int FIRST_COMPAT_MODE_MSG = 300; 1161 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1162 1163 AlertDialog mUidAlert; 1164 CompatModeDialog mCompatModeDialog; 1165 long mLastMemUsageReportTime = 0; 1166 1167 /** 1168 * Flag whether the current user is a "monkey", i.e. whether 1169 * the UI is driven by a UI automation tool. 1170 */ 1171 private boolean mUserIsMonkey; 1172 1173 final ServiceThread mHandlerThread; 1174 final MainHandler mHandler; 1175 1176 final class MainHandler extends Handler { 1177 public MainHandler(Looper looper) { 1178 super(looper, null, true); 1179 } 1180 1181 @Override 1182 public void handleMessage(Message msg) { 1183 switch (msg.what) { 1184 case SHOW_ERROR_MSG: { 1185 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1186 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1187 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1188 synchronized (ActivityManagerService.this) { 1189 ProcessRecord proc = (ProcessRecord)data.get("app"); 1190 AppErrorResult res = (AppErrorResult) data.get("result"); 1191 if (proc != null && proc.crashDialog != null) { 1192 Slog.e(TAG, "App already has crash dialog: " + proc); 1193 if (res != null) { 1194 res.set(0); 1195 } 1196 return; 1197 } 1198 if (!showBackground && UserHandle.getAppId(proc.uid) 1199 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1200 && proc.pid != MY_PID) { 1201 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1202 if (res != null) { 1203 res.set(0); 1204 } 1205 return; 1206 } 1207 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1208 Dialog d = new AppErrorDialog(mContext, 1209 ActivityManagerService.this, res, proc); 1210 d.show(); 1211 proc.crashDialog = d; 1212 } else { 1213 // The device is asleep, so just pretend that the user 1214 // saw a crash dialog and hit "force quit". 1215 if (res != null) { 1216 res.set(0); 1217 } 1218 } 1219 } 1220 1221 ensureBootCompleted(); 1222 } break; 1223 case SHOW_NOT_RESPONDING_MSG: { 1224 synchronized (ActivityManagerService.this) { 1225 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1226 ProcessRecord proc = (ProcessRecord)data.get("app"); 1227 if (proc != null && proc.anrDialog != null) { 1228 Slog.e(TAG, "App already has anr dialog: " + proc); 1229 return; 1230 } 1231 1232 Intent intent = new Intent("android.intent.action.ANR"); 1233 if (!mProcessesReady) { 1234 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1235 | Intent.FLAG_RECEIVER_FOREGROUND); 1236 } 1237 broadcastIntentLocked(null, null, intent, 1238 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1239 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1240 1241 if (mShowDialogs) { 1242 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1243 mContext, proc, (ActivityRecord)data.get("activity"), 1244 msg.arg1 != 0); 1245 d.show(); 1246 proc.anrDialog = d; 1247 } else { 1248 // Just kill the app if there is no dialog to be shown. 1249 killAppAtUsersRequest(proc, null); 1250 } 1251 } 1252 1253 ensureBootCompleted(); 1254 } break; 1255 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1256 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1257 synchronized (ActivityManagerService.this) { 1258 ProcessRecord proc = (ProcessRecord) data.get("app"); 1259 if (proc == null) { 1260 Slog.e(TAG, "App not found when showing strict mode dialog."); 1261 break; 1262 } 1263 if (proc.crashDialog != null) { 1264 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1265 return; 1266 } 1267 AppErrorResult res = (AppErrorResult) data.get("result"); 1268 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1269 Dialog d = new StrictModeViolationDialog(mContext, 1270 ActivityManagerService.this, res, proc); 1271 d.show(); 1272 proc.crashDialog = d; 1273 } else { 1274 // The device is asleep, so just pretend that the user 1275 // saw a crash dialog and hit "force quit". 1276 res.set(0); 1277 } 1278 } 1279 ensureBootCompleted(); 1280 } break; 1281 case SHOW_FACTORY_ERROR_MSG: { 1282 Dialog d = new FactoryErrorDialog( 1283 mContext, msg.getData().getCharSequence("msg")); 1284 d.show(); 1285 ensureBootCompleted(); 1286 } break; 1287 case UPDATE_CONFIGURATION_MSG: { 1288 final ContentResolver resolver = mContext.getContentResolver(); 1289 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1290 } break; 1291 case GC_BACKGROUND_PROCESSES_MSG: { 1292 synchronized (ActivityManagerService.this) { 1293 performAppGcsIfAppropriateLocked(); 1294 } 1295 } break; 1296 case WAIT_FOR_DEBUGGER_MSG: { 1297 synchronized (ActivityManagerService.this) { 1298 ProcessRecord app = (ProcessRecord)msg.obj; 1299 if (msg.arg1 != 0) { 1300 if (!app.waitedForDebugger) { 1301 Dialog d = new AppWaitingForDebuggerDialog( 1302 ActivityManagerService.this, 1303 mContext, app); 1304 app.waitDialog = d; 1305 app.waitedForDebugger = true; 1306 d.show(); 1307 } 1308 } else { 1309 if (app.waitDialog != null) { 1310 app.waitDialog.dismiss(); 1311 app.waitDialog = null; 1312 } 1313 } 1314 } 1315 } break; 1316 case SERVICE_TIMEOUT_MSG: { 1317 if (mDidDexOpt) { 1318 mDidDexOpt = false; 1319 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1320 nmsg.obj = msg.obj; 1321 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1322 return; 1323 } 1324 mServices.serviceTimeout((ProcessRecord)msg.obj); 1325 } break; 1326 case UPDATE_TIME_ZONE: { 1327 synchronized (ActivityManagerService.this) { 1328 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1329 ProcessRecord r = mLruProcesses.get(i); 1330 if (r.thread != null) { 1331 try { 1332 r.thread.updateTimeZone(); 1333 } catch (RemoteException ex) { 1334 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1335 } 1336 } 1337 } 1338 } 1339 } break; 1340 case CLEAR_DNS_CACHE_MSG: { 1341 synchronized (ActivityManagerService.this) { 1342 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1343 ProcessRecord r = mLruProcesses.get(i); 1344 if (r.thread != null) { 1345 try { 1346 r.thread.clearDnsCache(); 1347 } catch (RemoteException ex) { 1348 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1349 } 1350 } 1351 } 1352 } 1353 } break; 1354 case UPDATE_HTTP_PROXY_MSG: { 1355 ProxyInfo proxy = (ProxyInfo)msg.obj; 1356 String host = ""; 1357 String port = ""; 1358 String exclList = ""; 1359 Uri pacFileUrl = Uri.EMPTY; 1360 if (proxy != null) { 1361 host = proxy.getHost(); 1362 port = Integer.toString(proxy.getPort()); 1363 exclList = proxy.getExclusionListAsString(); 1364 pacFileUrl = proxy.getPacFileUrl(); 1365 } 1366 synchronized (ActivityManagerService.this) { 1367 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1368 ProcessRecord r = mLruProcesses.get(i); 1369 if (r.thread != null) { 1370 try { 1371 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1372 } catch (RemoteException ex) { 1373 Slog.w(TAG, "Failed to update http proxy for: " + 1374 r.info.processName); 1375 } 1376 } 1377 } 1378 } 1379 } break; 1380 case SHOW_UID_ERROR_MSG: { 1381 String title = "System UIDs Inconsistent"; 1382 String text = "UIDs on the system are inconsistent, you need to wipe your" 1383 + " data partition or your device will be unstable."; 1384 Log.e(TAG, title + ": " + text); 1385 if (mShowDialogs) { 1386 // XXX This is a temporary dialog, no need to localize. 1387 AlertDialog d = new BaseErrorDialog(mContext); 1388 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1389 d.setCancelable(false); 1390 d.setTitle(title); 1391 d.setMessage(text); 1392 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1393 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1394 mUidAlert = d; 1395 d.show(); 1396 } 1397 } break; 1398 case IM_FEELING_LUCKY_MSG: { 1399 if (mUidAlert != null) { 1400 mUidAlert.dismiss(); 1401 mUidAlert = null; 1402 } 1403 } break; 1404 case PROC_START_TIMEOUT_MSG: { 1405 if (mDidDexOpt) { 1406 mDidDexOpt = false; 1407 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1408 nmsg.obj = msg.obj; 1409 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1410 return; 1411 } 1412 ProcessRecord app = (ProcessRecord)msg.obj; 1413 synchronized (ActivityManagerService.this) { 1414 processStartTimedOutLocked(app); 1415 } 1416 } break; 1417 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1418 synchronized (ActivityManagerService.this) { 1419 doPendingActivityLaunchesLocked(true); 1420 } 1421 } break; 1422 case KILL_APPLICATION_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 int appid = msg.arg1; 1425 boolean restart = (msg.arg2 == 1); 1426 Bundle bundle = (Bundle)msg.obj; 1427 String pkg = bundle.getString("pkg"); 1428 String reason = bundle.getString("reason"); 1429 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1430 false, UserHandle.USER_ALL, reason); 1431 } 1432 } break; 1433 case FINALIZE_PENDING_INTENT_MSG: { 1434 ((PendingIntentRecord)msg.obj).completeFinalize(); 1435 } break; 1436 case POST_HEAVY_NOTIFICATION_MSG: { 1437 INotificationManager inm = NotificationManager.getService(); 1438 if (inm == null) { 1439 return; 1440 } 1441 1442 ActivityRecord root = (ActivityRecord)msg.obj; 1443 ProcessRecord process = root.app; 1444 if (process == null) { 1445 return; 1446 } 1447 1448 try { 1449 Context context = mContext.createPackageContext(process.info.packageName, 0); 1450 String text = mContext.getString(R.string.heavy_weight_notification, 1451 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1452 Notification notification = new Notification(); 1453 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1454 notification.when = 0; 1455 notification.flags = Notification.FLAG_ONGOING_EVENT; 1456 notification.tickerText = text; 1457 notification.defaults = 0; // please be quiet 1458 notification.sound = null; 1459 notification.vibrate = null; 1460 notification.setLatestEventInfo(context, text, 1461 mContext.getText(R.string.heavy_weight_notification_detail), 1462 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1463 PendingIntent.FLAG_CANCEL_CURRENT, null, 1464 new UserHandle(root.userId))); 1465 1466 try { 1467 int[] outId = new int[1]; 1468 inm.enqueueNotificationWithTag("android", "android", null, 1469 R.string.heavy_weight_notification, 1470 notification, outId, root.userId); 1471 } catch (RuntimeException e) { 1472 Slog.w(ActivityManagerService.TAG, 1473 "Error showing notification for heavy-weight app", e); 1474 } catch (RemoteException e) { 1475 } 1476 } catch (NameNotFoundException e) { 1477 Slog.w(TAG, "Unable to create context for heavy notification", e); 1478 } 1479 } break; 1480 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1481 INotificationManager inm = NotificationManager.getService(); 1482 if (inm == null) { 1483 return; 1484 } 1485 try { 1486 inm.cancelNotificationWithTag("android", null, 1487 R.string.heavy_weight_notification, msg.arg1); 1488 } catch (RuntimeException e) { 1489 Slog.w(ActivityManagerService.TAG, 1490 "Error canceling notification for service", e); 1491 } catch (RemoteException e) { 1492 } 1493 } break; 1494 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1495 synchronized (ActivityManagerService.this) { 1496 checkExcessivePowerUsageLocked(true); 1497 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1498 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1499 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1500 } 1501 } break; 1502 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1503 synchronized (ActivityManagerService.this) { 1504 ActivityRecord ar = (ActivityRecord)msg.obj; 1505 if (mCompatModeDialog != null) { 1506 if (mCompatModeDialog.mAppInfo.packageName.equals( 1507 ar.info.applicationInfo.packageName)) { 1508 return; 1509 } 1510 mCompatModeDialog.dismiss(); 1511 mCompatModeDialog = null; 1512 } 1513 if (ar != null && false) { 1514 if (mCompatModePackages.getPackageAskCompatModeLocked( 1515 ar.packageName)) { 1516 int mode = mCompatModePackages.computeCompatModeLocked( 1517 ar.info.applicationInfo); 1518 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1519 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1520 mCompatModeDialog = new CompatModeDialog( 1521 ActivityManagerService.this, mContext, 1522 ar.info.applicationInfo); 1523 mCompatModeDialog.show(); 1524 } 1525 } 1526 } 1527 } 1528 break; 1529 } 1530 case DISPATCH_PROCESSES_CHANGED: { 1531 dispatchProcessesChanged(); 1532 break; 1533 } 1534 case DISPATCH_PROCESS_DIED: { 1535 final int pid = msg.arg1; 1536 final int uid = msg.arg2; 1537 dispatchProcessDied(pid, uid); 1538 break; 1539 } 1540 case REPORT_MEM_USAGE_MSG: { 1541 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1542 Thread thread = new Thread() { 1543 @Override public void run() { 1544 final SparseArray<ProcessMemInfo> infoMap 1545 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1546 for (int i=0, N=memInfos.size(); i<N; i++) { 1547 ProcessMemInfo mi = memInfos.get(i); 1548 infoMap.put(mi.pid, mi); 1549 } 1550 updateCpuStatsNow(); 1551 synchronized (mProcessCpuThread) { 1552 final int N = mProcessCpuTracker.countStats(); 1553 for (int i=0; i<N; i++) { 1554 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1555 if (st.vsize > 0) { 1556 long pss = Debug.getPss(st.pid, null); 1557 if (pss > 0) { 1558 if (infoMap.indexOfKey(st.pid) < 0) { 1559 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1560 ProcessList.NATIVE_ADJ, -1, "native", null); 1561 mi.pss = pss; 1562 memInfos.add(mi); 1563 } 1564 } 1565 } 1566 } 1567 } 1568 1569 long totalPss = 0; 1570 for (int i=0, N=memInfos.size(); i<N; i++) { 1571 ProcessMemInfo mi = memInfos.get(i); 1572 if (mi.pss == 0) { 1573 mi.pss = Debug.getPss(mi.pid, null); 1574 } 1575 totalPss += mi.pss; 1576 } 1577 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1578 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1579 if (lhs.oomAdj != rhs.oomAdj) { 1580 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1581 } 1582 if (lhs.pss != rhs.pss) { 1583 return lhs.pss < rhs.pss ? 1 : -1; 1584 } 1585 return 0; 1586 } 1587 }); 1588 1589 StringBuilder tag = new StringBuilder(128); 1590 StringBuilder stack = new StringBuilder(128); 1591 tag.append("Low on memory -- "); 1592 appendMemBucket(tag, totalPss, "total", false); 1593 appendMemBucket(stack, totalPss, "total", true); 1594 1595 StringBuilder logBuilder = new StringBuilder(1024); 1596 logBuilder.append("Low on memory:\n"); 1597 1598 boolean firstLine = true; 1599 int lastOomAdj = Integer.MIN_VALUE; 1600 for (int i=0, N=memInfos.size(); i<N; i++) { 1601 ProcessMemInfo mi = memInfos.get(i); 1602 1603 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1604 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1605 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1606 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1607 if (lastOomAdj != mi.oomAdj) { 1608 lastOomAdj = mi.oomAdj; 1609 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1610 tag.append(" / "); 1611 } 1612 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1613 if (firstLine) { 1614 stack.append(":"); 1615 firstLine = false; 1616 } 1617 stack.append("\n\t at "); 1618 } else { 1619 stack.append("$"); 1620 } 1621 } else { 1622 tag.append(" "); 1623 stack.append("$"); 1624 } 1625 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1626 appendMemBucket(tag, mi.pss, mi.name, false); 1627 } 1628 appendMemBucket(stack, mi.pss, mi.name, true); 1629 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1630 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1631 stack.append("("); 1632 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1633 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1634 stack.append(DUMP_MEM_OOM_LABEL[k]); 1635 stack.append(":"); 1636 stack.append(DUMP_MEM_OOM_ADJ[k]); 1637 } 1638 } 1639 stack.append(")"); 1640 } 1641 } 1642 1643 logBuilder.append(" "); 1644 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1645 logBuilder.append(' '); 1646 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1647 logBuilder.append(' '); 1648 ProcessList.appendRamKb(logBuilder, mi.pss); 1649 logBuilder.append(" kB: "); 1650 logBuilder.append(mi.name); 1651 logBuilder.append(" ("); 1652 logBuilder.append(mi.pid); 1653 logBuilder.append(") "); 1654 logBuilder.append(mi.adjType); 1655 logBuilder.append('\n'); 1656 if (mi.adjReason != null) { 1657 logBuilder.append(" "); 1658 logBuilder.append(mi.adjReason); 1659 logBuilder.append('\n'); 1660 } 1661 } 1662 1663 logBuilder.append(" "); 1664 ProcessList.appendRamKb(logBuilder, totalPss); 1665 logBuilder.append(" kB: TOTAL\n"); 1666 1667 long[] infos = new long[Debug.MEMINFO_COUNT]; 1668 Debug.getMemInfo(infos); 1669 logBuilder.append(" MemInfo: "); 1670 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1671 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1672 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1673 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1674 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1675 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1676 logBuilder.append(" ZRAM: "); 1677 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1678 logBuilder.append(" kB RAM, "); 1679 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1680 logBuilder.append(" kB swap total, "); 1681 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1682 logBuilder.append(" kB swap free\n"); 1683 } 1684 Slog.i(TAG, logBuilder.toString()); 1685 1686 StringBuilder dropBuilder = new StringBuilder(1024); 1687 /* 1688 StringWriter oomSw = new StringWriter(); 1689 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1690 StringWriter catSw = new StringWriter(); 1691 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1692 String[] emptyArgs = new String[] { }; 1693 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1694 oomPw.flush(); 1695 String oomString = oomSw.toString(); 1696 */ 1697 dropBuilder.append(stack); 1698 dropBuilder.append('\n'); 1699 dropBuilder.append('\n'); 1700 dropBuilder.append(logBuilder); 1701 dropBuilder.append('\n'); 1702 /* 1703 dropBuilder.append(oomString); 1704 dropBuilder.append('\n'); 1705 */ 1706 StringWriter catSw = new StringWriter(); 1707 synchronized (ActivityManagerService.this) { 1708 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1709 String[] emptyArgs = new String[] { }; 1710 catPw.println(); 1711 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1712 catPw.println(); 1713 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1714 false, false, null); 1715 catPw.println(); 1716 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1717 catPw.flush(); 1718 } 1719 dropBuilder.append(catSw.toString()); 1720 addErrorToDropBox("lowmem", null, "system_server", null, 1721 null, tag.toString(), dropBuilder.toString(), null, null); 1722 //Slog.i(TAG, "Sent to dropbox:"); 1723 //Slog.i(TAG, dropBuilder.toString()); 1724 synchronized (ActivityManagerService.this) { 1725 long now = SystemClock.uptimeMillis(); 1726 if (mLastMemUsageReportTime < now) { 1727 mLastMemUsageReportTime = now; 1728 } 1729 } 1730 } 1731 }; 1732 thread.start(); 1733 break; 1734 } 1735 case REPORT_USER_SWITCH_MSG: { 1736 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1737 break; 1738 } 1739 case CONTINUE_USER_SWITCH_MSG: { 1740 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1741 break; 1742 } 1743 case USER_SWITCH_TIMEOUT_MSG: { 1744 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1745 break; 1746 } 1747 case IMMERSIVE_MODE_LOCK_MSG: { 1748 final boolean nextState = (msg.arg1 != 0); 1749 if (mUpdateLock.isHeld() != nextState) { 1750 if (DEBUG_IMMERSIVE) { 1751 final ActivityRecord r = (ActivityRecord) msg.obj; 1752 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1753 } 1754 if (nextState) { 1755 mUpdateLock.acquire(); 1756 } else { 1757 mUpdateLock.release(); 1758 } 1759 } 1760 break; 1761 } 1762 case PERSIST_URI_GRANTS_MSG: { 1763 writeGrantedUriPermissions(); 1764 break; 1765 } 1766 case REQUEST_ALL_PSS_MSG: { 1767 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1768 break; 1769 } 1770 case START_PROFILES_MSG: { 1771 synchronized (ActivityManagerService.this) { 1772 startProfilesLocked(); 1773 } 1774 break; 1775 } 1776 case UPDATE_TIME: { 1777 synchronized (ActivityManagerService.this) { 1778 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1779 ProcessRecord r = mLruProcesses.get(i); 1780 if (r.thread != null) { 1781 try { 1782 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1783 } catch (RemoteException ex) { 1784 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1785 } 1786 } 1787 } 1788 } 1789 break; 1790 } 1791 case SYSTEM_USER_START_MSG: { 1792 mSystemServiceManager.startUser(msg.arg1); 1793 break; 1794 } 1795 case SYSTEM_USER_CURRENT_MSG: { 1796 mSystemServiceManager.switchUser(msg.arg1); 1797 break; 1798 } 1799 } 1800 } 1801 }; 1802 1803 static final int COLLECT_PSS_BG_MSG = 1; 1804 1805 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1806 @Override 1807 public void handleMessage(Message msg) { 1808 switch (msg.what) { 1809 case COLLECT_PSS_BG_MSG: { 1810 long start = SystemClock.uptimeMillis(); 1811 MemInfoReader memInfo = null; 1812 synchronized (ActivityManagerService.this) { 1813 if (mFullPssPending) { 1814 mFullPssPending = false; 1815 memInfo = new MemInfoReader(); 1816 } 1817 } 1818 if (memInfo != null) { 1819 updateCpuStatsNow(); 1820 long nativeTotalPss = 0; 1821 synchronized (mProcessCpuThread) { 1822 final int N = mProcessCpuTracker.countStats(); 1823 for (int j=0; j<N; j++) { 1824 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1825 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID 1826 || st.uid == Process.SYSTEM_UID) { 1827 // This is definitely an application process; skip it. 1828 continue; 1829 } 1830 synchronized (mPidsSelfLocked) { 1831 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1832 // This is one of our own processes; skip it. 1833 continue; 1834 } 1835 } 1836 nativeTotalPss += Debug.getPss(st.pid, null); 1837 } 1838 } 1839 memInfo.readMemInfo(); 1840 synchronized (this) { 1841 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1842 + (SystemClock.uptimeMillis()-start) + "ms"); 1843 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1844 memInfo.getFreeSizeKb(), 1845 memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(), 1846 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1847 +memInfo.getSlabSizeKb(), 1848 nativeTotalPss); 1849 } 1850 } 1851 1852 int i=0, num=0; 1853 long[] tmp = new long[1]; 1854 do { 1855 ProcessRecord proc; 1856 int procState; 1857 int pid; 1858 synchronized (ActivityManagerService.this) { 1859 if (i >= mPendingPssProcesses.size()) { 1860 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1861 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1862 mPendingPssProcesses.clear(); 1863 return; 1864 } 1865 proc = mPendingPssProcesses.get(i); 1866 procState = proc.pssProcState; 1867 if (proc.thread != null && procState == proc.setProcState) { 1868 pid = proc.pid; 1869 } else { 1870 proc = null; 1871 pid = 0; 1872 } 1873 i++; 1874 } 1875 if (proc != null) { 1876 long pss = Debug.getPss(pid, tmp); 1877 synchronized (ActivityManagerService.this) { 1878 if (proc.thread != null && proc.setProcState == procState 1879 && proc.pid == pid) { 1880 num++; 1881 proc.lastPssTime = SystemClock.uptimeMillis(); 1882 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1883 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1884 + ": " + pss + " lastPss=" + proc.lastPss 1885 + " state=" + ProcessList.makeProcStateString(procState)); 1886 if (proc.initialIdlePss == 0) { 1887 proc.initialIdlePss = pss; 1888 } 1889 proc.lastPss = pss; 1890 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1891 proc.lastCachedPss = pss; 1892 } 1893 } 1894 } 1895 } 1896 } while (true); 1897 } 1898 } 1899 } 1900 }; 1901 1902 /** 1903 * Monitor for package changes and update our internal state. 1904 */ 1905 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1906 @Override 1907 public void onPackageRemoved(String packageName, int uid) { 1908 // Remove all tasks with activities in the specified package from the list of recent tasks 1909 synchronized (ActivityManagerService.this) { 1910 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1911 TaskRecord tr = mRecentTasks.get(i); 1912 ComponentName cn = tr.intent.getComponent(); 1913 if (cn != null && cn.getPackageName().equals(packageName)) { 1914 // If the package name matches, remove the task and kill the process 1915 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1916 } 1917 } 1918 } 1919 } 1920 1921 @Override 1922 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1923 onPackageModified(packageName); 1924 return true; 1925 } 1926 1927 @Override 1928 public void onPackageModified(String packageName) { 1929 final PackageManager pm = mContext.getPackageManager(); 1930 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1931 new ArrayList<Pair<Intent, Integer>>(); 1932 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1933 // Copy the list of recent tasks so that we don't hold onto the lock on 1934 // ActivityManagerService for long periods while checking if components exist. 1935 synchronized (ActivityManagerService.this) { 1936 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1937 TaskRecord tr = mRecentTasks.get(i); 1938 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1939 } 1940 } 1941 // Check the recent tasks and filter out all tasks with components that no longer exist. 1942 Intent tmpI = new Intent(); 1943 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1944 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1945 ComponentName cn = p.first.getComponent(); 1946 if (cn != null && cn.getPackageName().equals(packageName)) { 1947 try { 1948 // Add the task to the list to remove if the component no longer exists 1949 tmpI.setComponent(cn); 1950 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1951 tasksToRemove.add(p.second); 1952 } 1953 } catch (Exception e) {} 1954 } 1955 } 1956 // Prune all the tasks with removed components from the list of recent tasks 1957 synchronized (ActivityManagerService.this) { 1958 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1959 // Remove the task but don't kill the process (since other components in that 1960 // package may still be running and in the background) 1961 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1962 } 1963 } 1964 } 1965 1966 @Override 1967 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1968 // Force stop the specified packages 1969 if (packages != null) { 1970 for (String pkg : packages) { 1971 synchronized (ActivityManagerService.this) { 1972 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1973 "finished booting")) { 1974 return true; 1975 } 1976 } 1977 } 1978 } 1979 return false; 1980 } 1981 }; 1982 1983 public void setSystemProcess() { 1984 try { 1985 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1986 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1987 ServiceManager.addService("meminfo", new MemBinder(this)); 1988 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1989 ServiceManager.addService("dbinfo", new DbBinder(this)); 1990 if (MONITOR_CPU_USAGE) { 1991 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1992 } 1993 ServiceManager.addService("permission", new PermissionController(this)); 1994 1995 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1996 "android", STOCK_PM_FLAGS); 1997 mSystemThread.installSystemApplicationInfo(info); 1998 1999 synchronized (this) { 2000 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2001 app.persistent = true; 2002 app.pid = MY_PID; 2003 app.maxAdj = ProcessList.SYSTEM_ADJ; 2004 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2005 mProcessNames.put(app.processName, app.uid, app); 2006 synchronized (mPidsSelfLocked) { 2007 mPidsSelfLocked.put(app.pid, app); 2008 } 2009 updateLruProcessLocked(app, false, null); 2010 updateOomAdjLocked(); 2011 } 2012 } catch (PackageManager.NameNotFoundException e) { 2013 throw new RuntimeException( 2014 "Unable to find android system package", e); 2015 } 2016 } 2017 2018 public void setWindowManager(WindowManagerService wm) { 2019 mWindowManager = wm; 2020 mStackSupervisor.setWindowManager(wm); 2021 } 2022 2023 public void startObservingNativeCrashes() { 2024 final NativeCrashListener ncl = new NativeCrashListener(this); 2025 ncl.start(); 2026 } 2027 2028 public IAppOpsService getAppOpsService() { 2029 return mAppOpsService; 2030 } 2031 2032 static class MemBinder extends Binder { 2033 ActivityManagerService mActivityManagerService; 2034 MemBinder(ActivityManagerService activityManagerService) { 2035 mActivityManagerService = activityManagerService; 2036 } 2037 2038 @Override 2039 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2040 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2041 != PackageManager.PERMISSION_GRANTED) { 2042 pw.println("Permission Denial: can't dump meminfo from from pid=" 2043 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2044 + " without permission " + android.Manifest.permission.DUMP); 2045 return; 2046 } 2047 2048 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2049 } 2050 } 2051 2052 static class GraphicsBinder extends Binder { 2053 ActivityManagerService mActivityManagerService; 2054 GraphicsBinder(ActivityManagerService activityManagerService) { 2055 mActivityManagerService = activityManagerService; 2056 } 2057 2058 @Override 2059 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2060 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2061 != PackageManager.PERMISSION_GRANTED) { 2062 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2063 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2064 + " without permission " + android.Manifest.permission.DUMP); 2065 return; 2066 } 2067 2068 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2069 } 2070 } 2071 2072 static class DbBinder extends Binder { 2073 ActivityManagerService mActivityManagerService; 2074 DbBinder(ActivityManagerService activityManagerService) { 2075 mActivityManagerService = activityManagerService; 2076 } 2077 2078 @Override 2079 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2080 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2081 != PackageManager.PERMISSION_GRANTED) { 2082 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2083 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2084 + " without permission " + android.Manifest.permission.DUMP); 2085 return; 2086 } 2087 2088 mActivityManagerService.dumpDbInfo(fd, pw, args); 2089 } 2090 } 2091 2092 static class CpuBinder extends Binder { 2093 ActivityManagerService mActivityManagerService; 2094 CpuBinder(ActivityManagerService activityManagerService) { 2095 mActivityManagerService = activityManagerService; 2096 } 2097 2098 @Override 2099 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2100 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2101 != PackageManager.PERMISSION_GRANTED) { 2102 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2103 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2104 + " without permission " + android.Manifest.permission.DUMP); 2105 return; 2106 } 2107 2108 synchronized (mActivityManagerService.mProcessCpuThread) { 2109 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2110 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2111 SystemClock.uptimeMillis())); 2112 } 2113 } 2114 } 2115 2116 public static final class Lifecycle extends SystemService { 2117 private final ActivityManagerService mService; 2118 2119 public Lifecycle(Context context) { 2120 super(context); 2121 mService = new ActivityManagerService(context); 2122 } 2123 2124 @Override 2125 public void onStart() { 2126 mService.start(); 2127 } 2128 2129 public ActivityManagerService getService() { 2130 return mService; 2131 } 2132 } 2133 2134 // Note: This method is invoked on the main thread but may need to attach various 2135 // handlers to other threads. So take care to be explicit about the looper. 2136 public ActivityManagerService(Context systemContext) { 2137 mContext = systemContext; 2138 mFactoryTest = FactoryTest.getMode(); 2139 mSystemThread = ActivityThread.currentActivityThread(); 2140 2141 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2142 2143 mHandlerThread = new ServiceThread(TAG, 2144 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2145 mHandlerThread.start(); 2146 mHandler = new MainHandler(mHandlerThread.getLooper()); 2147 2148 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2149 "foreground", BROADCAST_FG_TIMEOUT, false); 2150 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2151 "background", BROADCAST_BG_TIMEOUT, true); 2152 mBroadcastQueues[0] = mFgBroadcastQueue; 2153 mBroadcastQueues[1] = mBgBroadcastQueue; 2154 2155 mServices = new ActiveServices(this); 2156 mProviderMap = new ProviderMap(this); 2157 2158 // TODO: Move creation of battery stats service outside of activity manager service. 2159 File dataDir = Environment.getDataDirectory(); 2160 File systemDir = new File(dataDir, "system"); 2161 systemDir.mkdirs(); 2162 mBatteryStatsService = new BatteryStatsService(new File( 2163 systemDir, "batterystats.bin").toString(), mHandler); 2164 mBatteryStatsService.getActiveStatistics().readLocked(); 2165 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2166 mOnBattery = DEBUG_POWER ? true 2167 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2168 mBatteryStatsService.getActiveStatistics().setCallback(this); 2169 2170 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2171 2172 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2173 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2174 2175 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2176 2177 // User 0 is the first and only user that runs at boot. 2178 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2179 mUserLru.add(Integer.valueOf(0)); 2180 updateStartedUserArrayLocked(); 2181 2182 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2183 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2184 2185 mConfiguration.setToDefaults(); 2186 mConfiguration.setLocale(Locale.getDefault()); 2187 2188 mConfigurationSeq = mConfiguration.seq = 1; 2189 mProcessCpuTracker.init(); 2190 2191 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2192 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2193 mStackSupervisor = new ActivityStackSupervisor(this); 2194 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2195 2196 mProcessCpuThread = new Thread("CpuTracker") { 2197 @Override 2198 public void run() { 2199 while (true) { 2200 try { 2201 try { 2202 synchronized(this) { 2203 final long now = SystemClock.uptimeMillis(); 2204 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2205 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2206 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2207 // + ", write delay=" + nextWriteDelay); 2208 if (nextWriteDelay < nextCpuDelay) { 2209 nextCpuDelay = nextWriteDelay; 2210 } 2211 if (nextCpuDelay > 0) { 2212 mProcessCpuMutexFree.set(true); 2213 this.wait(nextCpuDelay); 2214 } 2215 } 2216 } catch (InterruptedException e) { 2217 } 2218 updateCpuStatsNow(); 2219 } catch (Exception e) { 2220 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2221 } 2222 } 2223 } 2224 }; 2225 2226 Watchdog.getInstance().addMonitor(this); 2227 Watchdog.getInstance().addThread(mHandler); 2228 } 2229 2230 public void setSystemServiceManager(SystemServiceManager mgr) { 2231 mSystemServiceManager = mgr; 2232 } 2233 2234 private void start() { 2235 mProcessCpuThread.start(); 2236 2237 mBatteryStatsService.publish(mContext); 2238 mUsageStatsService.publish(mContext); 2239 mAppOpsService.publish(mContext); 2240 Slog.d("AppOps", "AppOpsService published"); 2241 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2242 } 2243 2244 @Override 2245 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2246 throws RemoteException { 2247 if (code == SYSPROPS_TRANSACTION) { 2248 // We need to tell all apps about the system property change. 2249 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2250 synchronized(this) { 2251 final int NP = mProcessNames.getMap().size(); 2252 for (int ip=0; ip<NP; ip++) { 2253 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2254 final int NA = apps.size(); 2255 for (int ia=0; ia<NA; ia++) { 2256 ProcessRecord app = apps.valueAt(ia); 2257 if (app.thread != null) { 2258 procs.add(app.thread.asBinder()); 2259 } 2260 } 2261 } 2262 } 2263 2264 int N = procs.size(); 2265 for (int i=0; i<N; i++) { 2266 Parcel data2 = Parcel.obtain(); 2267 try { 2268 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2269 } catch (RemoteException e) { 2270 } 2271 data2.recycle(); 2272 } 2273 } 2274 try { 2275 return super.onTransact(code, data, reply, flags); 2276 } catch (RuntimeException e) { 2277 // The activity manager only throws security exceptions, so let's 2278 // log all others. 2279 if (!(e instanceof SecurityException)) { 2280 Slog.wtf(TAG, "Activity Manager Crash", e); 2281 } 2282 throw e; 2283 } 2284 } 2285 2286 void updateCpuStats() { 2287 final long now = SystemClock.uptimeMillis(); 2288 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2289 return; 2290 } 2291 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2292 synchronized (mProcessCpuThread) { 2293 mProcessCpuThread.notify(); 2294 } 2295 } 2296 } 2297 2298 void updateCpuStatsNow() { 2299 synchronized (mProcessCpuThread) { 2300 mProcessCpuMutexFree.set(false); 2301 final long now = SystemClock.uptimeMillis(); 2302 boolean haveNewCpuStats = false; 2303 2304 if (MONITOR_CPU_USAGE && 2305 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2306 mLastCpuTime.set(now); 2307 haveNewCpuStats = true; 2308 mProcessCpuTracker.update(); 2309 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2310 //Slog.i(TAG, "Total CPU usage: " 2311 // + mProcessCpu.getTotalCpuPercent() + "%"); 2312 2313 // Slog the cpu usage if the property is set. 2314 if ("true".equals(SystemProperties.get("events.cpu"))) { 2315 int user = mProcessCpuTracker.getLastUserTime(); 2316 int system = mProcessCpuTracker.getLastSystemTime(); 2317 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2318 int irq = mProcessCpuTracker.getLastIrqTime(); 2319 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2320 int idle = mProcessCpuTracker.getLastIdleTime(); 2321 2322 int total = user + system + iowait + irq + softIrq + idle; 2323 if (total == 0) total = 1; 2324 2325 EventLog.writeEvent(EventLogTags.CPU, 2326 ((user+system+iowait+irq+softIrq) * 100) / total, 2327 (user * 100) / total, 2328 (system * 100) / total, 2329 (iowait * 100) / total, 2330 (irq * 100) / total, 2331 (softIrq * 100) / total); 2332 } 2333 } 2334 2335 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2336 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2337 synchronized(bstats) { 2338 synchronized(mPidsSelfLocked) { 2339 if (haveNewCpuStats) { 2340 if (mOnBattery) { 2341 int perc = bstats.startAddingCpuLocked(); 2342 int totalUTime = 0; 2343 int totalSTime = 0; 2344 final int N = mProcessCpuTracker.countStats(); 2345 for (int i=0; i<N; i++) { 2346 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2347 if (!st.working) { 2348 continue; 2349 } 2350 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2351 int otherUTime = (st.rel_utime*perc)/100; 2352 int otherSTime = (st.rel_stime*perc)/100; 2353 totalUTime += otherUTime; 2354 totalSTime += otherSTime; 2355 if (pr != null) { 2356 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2357 if (ps == null || !ps.isActive()) { 2358 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2359 pr.info.uid, pr.processName); 2360 } 2361 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2362 st.rel_stime-otherSTime); 2363 ps.addSpeedStepTimes(cpuSpeedTimes); 2364 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2365 } else { 2366 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2367 if (ps == null || !ps.isActive()) { 2368 st.batteryStats = ps = bstats.getProcessStatsLocked( 2369 bstats.mapUid(st.uid), st.name); 2370 } 2371 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2372 st.rel_stime-otherSTime); 2373 ps.addSpeedStepTimes(cpuSpeedTimes); 2374 } 2375 } 2376 bstats.finishAddingCpuLocked(perc, totalUTime, 2377 totalSTime, cpuSpeedTimes); 2378 } 2379 } 2380 } 2381 2382 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2383 mLastWriteTime = now; 2384 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2385 } 2386 } 2387 } 2388 } 2389 2390 @Override 2391 public void batteryNeedsCpuUpdate() { 2392 updateCpuStatsNow(); 2393 } 2394 2395 @Override 2396 public void batteryPowerChanged(boolean onBattery) { 2397 // When plugging in, update the CPU stats first before changing 2398 // the plug state. 2399 updateCpuStatsNow(); 2400 synchronized (this) { 2401 synchronized(mPidsSelfLocked) { 2402 mOnBattery = DEBUG_POWER ? true : onBattery; 2403 } 2404 } 2405 } 2406 2407 /** 2408 * Initialize the application bind args. These are passed to each 2409 * process when the bindApplication() IPC is sent to the process. They're 2410 * lazily setup to make sure the services are running when they're asked for. 2411 */ 2412 private HashMap<String, IBinder> getCommonServicesLocked() { 2413 if (mAppBindArgs == null) { 2414 mAppBindArgs = new HashMap<String, IBinder>(); 2415 2416 // Setup the application init args 2417 mAppBindArgs.put("package", ServiceManager.getService("package")); 2418 mAppBindArgs.put("window", ServiceManager.getService("window")); 2419 mAppBindArgs.put(Context.ALARM_SERVICE, 2420 ServiceManager.getService(Context.ALARM_SERVICE)); 2421 } 2422 return mAppBindArgs; 2423 } 2424 2425 final void setFocusedActivityLocked(ActivityRecord r) { 2426 if (mFocusedActivity != r) { 2427 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2428 mFocusedActivity = r; 2429 if (r.task != null && r.task.voiceInteractor != null) { 2430 startRunningVoiceLocked(); 2431 } else { 2432 finishRunningVoiceLocked(); 2433 } 2434 mStackSupervisor.setFocusedStack(r); 2435 if (r != null) { 2436 mWindowManager.setFocusedApp(r.appToken, true); 2437 } 2438 applyUpdateLockStateLocked(r); 2439 } 2440 } 2441 2442 final void clearFocusedActivity(ActivityRecord r) { 2443 if (mFocusedActivity == r) { 2444 mFocusedActivity = null; 2445 } 2446 } 2447 2448 @Override 2449 public void setFocusedStack(int stackId) { 2450 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2451 synchronized (ActivityManagerService.this) { 2452 ActivityStack stack = mStackSupervisor.getStack(stackId); 2453 if (stack != null) { 2454 ActivityRecord r = stack.topRunningActivityLocked(null); 2455 if (r != null) { 2456 setFocusedActivityLocked(r); 2457 } 2458 } 2459 } 2460 } 2461 2462 @Override 2463 public void notifyActivityDrawn(IBinder token) { 2464 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2465 synchronized (this) { 2466 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2467 if (r != null) { 2468 r.task.stack.notifyActivityDrawnLocked(r); 2469 } 2470 } 2471 } 2472 2473 final void applyUpdateLockStateLocked(ActivityRecord r) { 2474 // Modifications to the UpdateLock state are done on our handler, outside 2475 // the activity manager's locks. The new state is determined based on the 2476 // state *now* of the relevant activity record. The object is passed to 2477 // the handler solely for logging detail, not to be consulted/modified. 2478 final boolean nextState = r != null && r.immersive; 2479 mHandler.sendMessage( 2480 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2481 } 2482 2483 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2484 Message msg = Message.obtain(); 2485 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2486 msg.obj = r.task.askedCompatMode ? null : r; 2487 mHandler.sendMessage(msg); 2488 } 2489 2490 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2491 String what, Object obj, ProcessRecord srcApp) { 2492 app.lastActivityTime = now; 2493 2494 if (app.activities.size() > 0) { 2495 // Don't want to touch dependent processes that are hosting activities. 2496 return index; 2497 } 2498 2499 int lrui = mLruProcesses.lastIndexOf(app); 2500 if (lrui < 0) { 2501 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2502 + what + " " + obj + " from " + srcApp); 2503 return index; 2504 } 2505 2506 if (lrui >= index) { 2507 // Don't want to cause this to move dependent processes *back* in the 2508 // list as if they were less frequently used. 2509 return index; 2510 } 2511 2512 if (lrui >= mLruProcessActivityStart) { 2513 // Don't want to touch dependent processes that are hosting activities. 2514 return index; 2515 } 2516 2517 mLruProcesses.remove(lrui); 2518 if (index > 0) { 2519 index--; 2520 } 2521 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2522 + " in LRU list: " + app); 2523 mLruProcesses.add(index, app); 2524 return index; 2525 } 2526 2527 final void removeLruProcessLocked(ProcessRecord app) { 2528 int lrui = mLruProcesses.lastIndexOf(app); 2529 if (lrui >= 0) { 2530 if (lrui <= mLruProcessActivityStart) { 2531 mLruProcessActivityStart--; 2532 } 2533 if (lrui <= mLruProcessServiceStart) { 2534 mLruProcessServiceStart--; 2535 } 2536 mLruProcesses.remove(lrui); 2537 } 2538 } 2539 2540 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2541 ProcessRecord client) { 2542 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2543 || app.treatLikeActivity; 2544 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2545 if (!activityChange && hasActivity) { 2546 // The process has activities, so we are only allowing activity-based adjustments 2547 // to move it. It should be kept in the front of the list with other 2548 // processes that have activities, and we don't want those to change their 2549 // order except due to activity operations. 2550 return; 2551 } 2552 2553 mLruSeq++; 2554 final long now = SystemClock.uptimeMillis(); 2555 app.lastActivityTime = now; 2556 2557 // First a quick reject: if the app is already at the position we will 2558 // put it, then there is nothing to do. 2559 if (hasActivity) { 2560 final int N = mLruProcesses.size(); 2561 if (N > 0 && mLruProcesses.get(N-1) == app) { 2562 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2563 return; 2564 } 2565 } else { 2566 if (mLruProcessServiceStart > 0 2567 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2568 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2569 return; 2570 } 2571 } 2572 2573 int lrui = mLruProcesses.lastIndexOf(app); 2574 2575 if (app.persistent && lrui >= 0) { 2576 // We don't care about the position of persistent processes, as long as 2577 // they are in the list. 2578 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2579 return; 2580 } 2581 2582 /* In progress: compute new position first, so we can avoid doing work 2583 if the process is not actually going to move. Not yet working. 2584 int addIndex; 2585 int nextIndex; 2586 boolean inActivity = false, inService = false; 2587 if (hasActivity) { 2588 // Process has activities, put it at the very tipsy-top. 2589 addIndex = mLruProcesses.size(); 2590 nextIndex = mLruProcessServiceStart; 2591 inActivity = true; 2592 } else if (hasService) { 2593 // Process has services, put it at the top of the service list. 2594 addIndex = mLruProcessActivityStart; 2595 nextIndex = mLruProcessServiceStart; 2596 inActivity = true; 2597 inService = true; 2598 } else { 2599 // Process not otherwise of interest, it goes to the top of the non-service area. 2600 addIndex = mLruProcessServiceStart; 2601 if (client != null) { 2602 int clientIndex = mLruProcesses.lastIndexOf(client); 2603 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2604 + app); 2605 if (clientIndex >= 0 && addIndex > clientIndex) { 2606 addIndex = clientIndex; 2607 } 2608 } 2609 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2610 } 2611 2612 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2613 + mLruProcessActivityStart + "): " + app); 2614 */ 2615 2616 if (lrui >= 0) { 2617 if (lrui < mLruProcessActivityStart) { 2618 mLruProcessActivityStart--; 2619 } 2620 if (lrui < mLruProcessServiceStart) { 2621 mLruProcessServiceStart--; 2622 } 2623 /* 2624 if (addIndex > lrui) { 2625 addIndex--; 2626 } 2627 if (nextIndex > lrui) { 2628 nextIndex--; 2629 } 2630 */ 2631 mLruProcesses.remove(lrui); 2632 } 2633 2634 /* 2635 mLruProcesses.add(addIndex, app); 2636 if (inActivity) { 2637 mLruProcessActivityStart++; 2638 } 2639 if (inService) { 2640 mLruProcessActivityStart++; 2641 } 2642 */ 2643 2644 int nextIndex; 2645 if (hasActivity) { 2646 final int N = mLruProcesses.size(); 2647 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2648 // Process doesn't have activities, but has clients with 2649 // activities... move it up, but one below the top (the top 2650 // should always have a real activity). 2651 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2652 mLruProcesses.add(N-1, app); 2653 // To keep it from spamming the LRU list (by making a bunch of clients), 2654 // we will push down any other entries owned by the app. 2655 final int uid = app.info.uid; 2656 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2657 ProcessRecord subProc = mLruProcesses.get(i); 2658 if (subProc.info.uid == uid) { 2659 // We want to push this one down the list. If the process after 2660 // it is for the same uid, however, don't do so, because we don't 2661 // want them internally to be re-ordered. 2662 if (mLruProcesses.get(i-1).info.uid != uid) { 2663 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2664 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2665 ProcessRecord tmp = mLruProcesses.get(i); 2666 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2667 mLruProcesses.set(i-1, tmp); 2668 i--; 2669 } 2670 } else { 2671 // A gap, we can stop here. 2672 break; 2673 } 2674 } 2675 } else { 2676 // Process has activities, put it at the very tipsy-top. 2677 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2678 mLruProcesses.add(app); 2679 } 2680 nextIndex = mLruProcessServiceStart; 2681 } else if (hasService) { 2682 // Process has services, put it at the top of the service list. 2683 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2684 mLruProcesses.add(mLruProcessActivityStart, app); 2685 nextIndex = mLruProcessServiceStart; 2686 mLruProcessActivityStart++; 2687 } else { 2688 // Process not otherwise of interest, it goes to the top of the non-service area. 2689 int index = mLruProcessServiceStart; 2690 if (client != null) { 2691 // If there is a client, don't allow the process to be moved up higher 2692 // in the list than that client. 2693 int clientIndex = mLruProcesses.lastIndexOf(client); 2694 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2695 + " when updating " + app); 2696 if (clientIndex <= lrui) { 2697 // Don't allow the client index restriction to push it down farther in the 2698 // list than it already is. 2699 clientIndex = lrui; 2700 } 2701 if (clientIndex >= 0 && index > clientIndex) { 2702 index = clientIndex; 2703 } 2704 } 2705 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2706 mLruProcesses.add(index, app); 2707 nextIndex = index-1; 2708 mLruProcessActivityStart++; 2709 mLruProcessServiceStart++; 2710 } 2711 2712 // If the app is currently using a content provider or service, 2713 // bump those processes as well. 2714 for (int j=app.connections.size()-1; j>=0; j--) { 2715 ConnectionRecord cr = app.connections.valueAt(j); 2716 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2717 && cr.binding.service.app != null 2718 && cr.binding.service.app.lruSeq != mLruSeq 2719 && !cr.binding.service.app.persistent) { 2720 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2721 "service connection", cr, app); 2722 } 2723 } 2724 for (int j=app.conProviders.size()-1; j>=0; j--) { 2725 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2726 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2727 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2728 "provider reference", cpr, app); 2729 } 2730 } 2731 } 2732 2733 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2734 if (uid == Process.SYSTEM_UID) { 2735 // The system gets to run in any process. If there are multiple 2736 // processes with the same uid, just pick the first (this 2737 // should never happen). 2738 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2739 if (procs == null) return null; 2740 final int N = procs.size(); 2741 for (int i = 0; i < N; i++) { 2742 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2743 } 2744 } 2745 ProcessRecord proc = mProcessNames.get(processName, uid); 2746 if (false && proc != null && !keepIfLarge 2747 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2748 && proc.lastCachedPss >= 4000) { 2749 // Turn this condition on to cause killing to happen regularly, for testing. 2750 if (proc.baseProcessTracker != null) { 2751 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2752 } 2753 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2754 + "k from cached"); 2755 } else if (proc != null && !keepIfLarge 2756 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2757 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2758 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2759 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 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 } 2766 } 2767 return proc; 2768 } 2769 2770 void ensurePackageDexOpt(String packageName) { 2771 IPackageManager pm = AppGlobals.getPackageManager(); 2772 try { 2773 if (pm.performDexOpt(packageName)) { 2774 mDidDexOpt = true; 2775 } 2776 } catch (RemoteException e) { 2777 } 2778 } 2779 2780 boolean isNextTransitionForward() { 2781 int transit = mWindowManager.getPendingAppTransition(); 2782 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2783 || transit == AppTransition.TRANSIT_TASK_OPEN 2784 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2785 } 2786 2787 final ProcessRecord startProcessLocked(String processName, 2788 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2789 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2790 boolean isolated, boolean keepIfLarge) { 2791 ProcessRecord app; 2792 if (!isolated) { 2793 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2794 } else { 2795 // If this is an isolated process, it can't re-use an existing process. 2796 app = null; 2797 } 2798 // We don't have to do anything more if: 2799 // (1) There is an existing application record; and 2800 // (2) The caller doesn't think it is dead, OR there is no thread 2801 // object attached to it so we know it couldn't have crashed; and 2802 // (3) There is a pid assigned to it, so it is either starting or 2803 // already running. 2804 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2805 + " app=" + app + " knownToBeDead=" + knownToBeDead 2806 + " thread=" + (app != null ? app.thread : null) 2807 + " pid=" + (app != null ? app.pid : -1)); 2808 if (app != null && app.pid > 0) { 2809 if (!knownToBeDead || app.thread == null) { 2810 // We already have the app running, or are waiting for it to 2811 // come up (we have a pid but not yet its thread), so keep it. 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2813 // If this is a new package in the process, add the package to the list 2814 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2815 return app; 2816 } 2817 2818 // An application record is attached to a previous process, 2819 // clean it up now. 2820 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2821 handleAppDiedLocked(app, true, true); 2822 } 2823 2824 String hostingNameStr = hostingName != null 2825 ? hostingName.flattenToShortString() : null; 2826 2827 if (!isolated) { 2828 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2829 // If we are in the background, then check to see if this process 2830 // is bad. If so, we will just silently fail. 2831 if (mBadProcesses.get(info.processName, info.uid) != null) { 2832 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2833 + "/" + info.processName); 2834 return null; 2835 } 2836 } else { 2837 // When the user is explicitly starting a process, then clear its 2838 // crash count so that we won't make it bad until they see at 2839 // least one crash dialog again, and make the process good again 2840 // if it had been bad. 2841 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2842 + "/" + info.processName); 2843 mProcessCrashTimes.remove(info.processName, info.uid); 2844 if (mBadProcesses.get(info.processName, info.uid) != null) { 2845 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2846 UserHandle.getUserId(info.uid), info.uid, 2847 info.processName); 2848 mBadProcesses.remove(info.processName, info.uid); 2849 if (app != null) { 2850 app.bad = false; 2851 } 2852 } 2853 } 2854 } 2855 2856 if (app == null) { 2857 app = newProcessRecordLocked(info, processName, isolated); 2858 if (app == null) { 2859 Slog.w(TAG, "Failed making new process record for " 2860 + processName + "/" + info.uid + " isolated=" + isolated); 2861 return null; 2862 } 2863 mProcessNames.put(processName, app.uid, app); 2864 if (isolated) { 2865 mIsolatedProcesses.put(app.uid, app); 2866 } 2867 } else { 2868 // If this is a new package in the process, add the package to the list 2869 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2870 } 2871 2872 // If the system is not ready yet, then hold off on starting this 2873 // process until it is. 2874 if (!mProcessesReady 2875 && !isAllowedWhileBooting(info) 2876 && !allowWhileBooting) { 2877 if (!mProcessesOnHold.contains(app)) { 2878 mProcessesOnHold.add(app); 2879 } 2880 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2881 return app; 2882 } 2883 2884 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2885 return (app.pid != 0) ? app : null; 2886 } 2887 2888 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2889 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2890 } 2891 2892 private final void startProcessLocked(ProcessRecord app, 2893 String hostingType, String hostingNameStr, String abiOverride) { 2894 if (app.pid > 0 && app.pid != MY_PID) { 2895 synchronized (mPidsSelfLocked) { 2896 mPidsSelfLocked.remove(app.pid); 2897 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2898 } 2899 app.setPid(0); 2900 } 2901 2902 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2903 "startProcessLocked removing on hold: " + app); 2904 mProcessesOnHold.remove(app); 2905 2906 updateCpuStats(); 2907 2908 try { 2909 int uid = app.uid; 2910 2911 int[] gids = null; 2912 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2913 if (!app.isolated) { 2914 int[] permGids = null; 2915 try { 2916 final PackageManager pm = mContext.getPackageManager(); 2917 permGids = pm.getPackageGids(app.info.packageName); 2918 2919 if (Environment.isExternalStorageEmulated()) { 2920 if (pm.checkPermission( 2921 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2922 app.info.packageName) == PERMISSION_GRANTED) { 2923 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2924 } else { 2925 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2926 } 2927 } 2928 } catch (PackageManager.NameNotFoundException e) { 2929 Slog.w(TAG, "Unable to retrieve gids", e); 2930 } 2931 2932 /* 2933 * Add shared application and profile GIDs so applications can share some 2934 * resources like shared libraries and access user-wide resources 2935 */ 2936 if (permGids == null) { 2937 gids = new int[2]; 2938 } else { 2939 gids = new int[permGids.length + 2]; 2940 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2941 } 2942 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2943 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2944 } 2945 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2946 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2947 && mTopComponent != null 2948 && app.processName.equals(mTopComponent.getPackageName())) { 2949 uid = 0; 2950 } 2951 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2952 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2953 uid = 0; 2954 } 2955 } 2956 int debugFlags = 0; 2957 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2958 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2959 // Also turn on CheckJNI for debuggable apps. It's quite 2960 // awkward to turn on otherwise. 2961 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2962 } 2963 // Run the app in safe mode if its manifest requests so or the 2964 // system is booted in safe mode. 2965 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2966 mSafeMode == true) { 2967 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2968 } 2969 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2970 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2971 } 2972 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2973 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2974 } 2975 if ("1".equals(SystemProperties.get("debug.assert"))) { 2976 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2977 } 2978 2979 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2980 if (requiredAbi == null) { 2981 requiredAbi = Build.SUPPORTED_ABIS[0]; 2982 } 2983 2984 // Start the process. It will either succeed and return a result containing 2985 // the PID of the new process, or else throw a RuntimeException. 2986 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2987 app.processName, uid, uid, gids, debugFlags, mountExternal, 2988 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2989 2990 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2991 synchronized (bs) { 2992 if (bs.isOnBattery()) { 2993 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2994 } 2995 } 2996 2997 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2998 UserHandle.getUserId(uid), startResult.pid, uid, 2999 app.processName, hostingType, 3000 hostingNameStr != null ? hostingNameStr : ""); 3001 3002 if (app.persistent) { 3003 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3004 } 3005 3006 StringBuilder buf = mStringBuilder; 3007 buf.setLength(0); 3008 buf.append("Start proc "); 3009 buf.append(app.processName); 3010 buf.append(" for "); 3011 buf.append(hostingType); 3012 if (hostingNameStr != null) { 3013 buf.append(" "); 3014 buf.append(hostingNameStr); 3015 } 3016 buf.append(": pid="); 3017 buf.append(startResult.pid); 3018 buf.append(" uid="); 3019 buf.append(uid); 3020 buf.append(" gids={"); 3021 if (gids != null) { 3022 for (int gi=0; gi<gids.length; gi++) { 3023 if (gi != 0) buf.append(", "); 3024 buf.append(gids[gi]); 3025 3026 } 3027 } 3028 buf.append("}"); 3029 if (requiredAbi != null) { 3030 buf.append(" abi="); 3031 buf.append(requiredAbi); 3032 } 3033 Slog.i(TAG, buf.toString()); 3034 app.setPid(startResult.pid); 3035 app.usingWrapper = startResult.usingWrapper; 3036 app.removed = false; 3037 synchronized (mPidsSelfLocked) { 3038 this.mPidsSelfLocked.put(startResult.pid, app); 3039 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3040 msg.obj = app; 3041 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3042 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3043 } 3044 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3045 app.processName, app.info.uid); 3046 if (app.isolated) { 3047 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3048 } 3049 } catch (RuntimeException e) { 3050 // XXX do better error recovery. 3051 app.setPid(0); 3052 Slog.e(TAG, "Failure starting process " + app.processName, e); 3053 } 3054 } 3055 3056 void updateUsageStats(ActivityRecord component, boolean resumed) { 3057 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3058 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3059 if (resumed) { 3060 mUsageStatsService.noteResumeComponent(component.realActivity); 3061 synchronized (stats) { 3062 stats.noteActivityResumedLocked(component.app.uid); 3063 } 3064 } else { 3065 mUsageStatsService.notePauseComponent(component.realActivity); 3066 synchronized (stats) { 3067 stats.noteActivityPausedLocked(component.app.uid); 3068 } 3069 } 3070 } 3071 3072 Intent getHomeIntent() { 3073 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3074 intent.setComponent(mTopComponent); 3075 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3076 intent.addCategory(Intent.CATEGORY_HOME); 3077 } 3078 return intent; 3079 } 3080 3081 boolean startHomeActivityLocked(int userId) { 3082 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3083 && mTopAction == null) { 3084 // We are running in factory test mode, but unable to find 3085 // the factory test app, so just sit around displaying the 3086 // error message and don't try to start anything. 3087 return false; 3088 } 3089 Intent intent = getHomeIntent(); 3090 ActivityInfo aInfo = 3091 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3092 if (aInfo != null) { 3093 intent.setComponent(new ComponentName( 3094 aInfo.applicationInfo.packageName, aInfo.name)); 3095 // Don't do this if the home app is currently being 3096 // instrumented. 3097 aInfo = new ActivityInfo(aInfo); 3098 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3099 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3100 aInfo.applicationInfo.uid, true); 3101 if (app == null || app.instrumentationClass == null) { 3102 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3103 mStackSupervisor.startHomeActivity(intent, aInfo); 3104 } 3105 } 3106 3107 return true; 3108 } 3109 3110 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3111 ActivityInfo ai = null; 3112 ComponentName comp = intent.getComponent(); 3113 try { 3114 if (comp != null) { 3115 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3116 } else { 3117 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3118 intent, 3119 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3120 flags, userId); 3121 3122 if (info != null) { 3123 ai = info.activityInfo; 3124 } 3125 } 3126 } catch (RemoteException e) { 3127 // ignore 3128 } 3129 3130 return ai; 3131 } 3132 3133 /** 3134 * Starts the "new version setup screen" if appropriate. 3135 */ 3136 void startSetupActivityLocked() { 3137 // Only do this once per boot. 3138 if (mCheckedForSetup) { 3139 return; 3140 } 3141 3142 // We will show this screen if the current one is a different 3143 // version than the last one shown, and we are not running in 3144 // low-level factory test mode. 3145 final ContentResolver resolver = mContext.getContentResolver(); 3146 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3147 Settings.Global.getInt(resolver, 3148 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3149 mCheckedForSetup = true; 3150 3151 // See if we should be showing the platform update setup UI. 3152 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3153 List<ResolveInfo> ris = mContext.getPackageManager() 3154 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3155 3156 // We don't allow third party apps to replace this. 3157 ResolveInfo ri = null; 3158 for (int i=0; ris != null && i<ris.size(); i++) { 3159 if ((ris.get(i).activityInfo.applicationInfo.flags 3160 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3161 ri = ris.get(i); 3162 break; 3163 } 3164 } 3165 3166 if (ri != null) { 3167 String vers = ri.activityInfo.metaData != null 3168 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3169 : null; 3170 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3171 vers = ri.activityInfo.applicationInfo.metaData.getString( 3172 Intent.METADATA_SETUP_VERSION); 3173 } 3174 String lastVers = Settings.Secure.getString( 3175 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3176 if (vers != null && !vers.equals(lastVers)) { 3177 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3178 intent.setComponent(new ComponentName( 3179 ri.activityInfo.packageName, ri.activityInfo.name)); 3180 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3181 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3182 } 3183 } 3184 } 3185 } 3186 3187 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3188 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3189 } 3190 3191 void enforceNotIsolatedCaller(String caller) { 3192 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3193 throw new SecurityException("Isolated process not allowed to call " + caller); 3194 } 3195 } 3196 3197 @Override 3198 public int getFrontActivityScreenCompatMode() { 3199 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3200 synchronized (this) { 3201 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3202 } 3203 } 3204 3205 @Override 3206 public void setFrontActivityScreenCompatMode(int mode) { 3207 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3208 "setFrontActivityScreenCompatMode"); 3209 synchronized (this) { 3210 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3211 } 3212 } 3213 3214 @Override 3215 public int getPackageScreenCompatMode(String packageName) { 3216 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3217 synchronized (this) { 3218 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3219 } 3220 } 3221 3222 @Override 3223 public void setPackageScreenCompatMode(String packageName, int mode) { 3224 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3225 "setPackageScreenCompatMode"); 3226 synchronized (this) { 3227 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3228 } 3229 } 3230 3231 @Override 3232 public boolean getPackageAskScreenCompat(String packageName) { 3233 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3234 synchronized (this) { 3235 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3236 } 3237 } 3238 3239 @Override 3240 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3241 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3242 "setPackageAskScreenCompat"); 3243 synchronized (this) { 3244 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3245 } 3246 } 3247 3248 private void dispatchProcessesChanged() { 3249 int N; 3250 synchronized (this) { 3251 N = mPendingProcessChanges.size(); 3252 if (mActiveProcessChanges.length < N) { 3253 mActiveProcessChanges = new ProcessChangeItem[N]; 3254 } 3255 mPendingProcessChanges.toArray(mActiveProcessChanges); 3256 mAvailProcessChanges.addAll(mPendingProcessChanges); 3257 mPendingProcessChanges.clear(); 3258 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3259 } 3260 3261 int i = mProcessObservers.beginBroadcast(); 3262 while (i > 0) { 3263 i--; 3264 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3265 if (observer != null) { 3266 try { 3267 for (int j=0; j<N; j++) { 3268 ProcessChangeItem item = mActiveProcessChanges[j]; 3269 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3270 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3271 + item.pid + " uid=" + item.uid + ": " 3272 + item.foregroundActivities); 3273 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3274 item.foregroundActivities); 3275 } 3276 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3277 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3278 + item.pid + " uid=" + item.uid + ": " + item.processState); 3279 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3280 } 3281 } 3282 } catch (RemoteException e) { 3283 } 3284 } 3285 } 3286 mProcessObservers.finishBroadcast(); 3287 } 3288 3289 private void dispatchProcessDied(int pid, int uid) { 3290 int i = mProcessObservers.beginBroadcast(); 3291 while (i > 0) { 3292 i--; 3293 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3294 if (observer != null) { 3295 try { 3296 observer.onProcessDied(pid, uid); 3297 } catch (RemoteException e) { 3298 } 3299 } 3300 } 3301 mProcessObservers.finishBroadcast(); 3302 } 3303 3304 final void doPendingActivityLaunchesLocked(boolean doResume) { 3305 final int N = mPendingActivityLaunches.size(); 3306 if (N <= 0) { 3307 return; 3308 } 3309 for (int i=0; i<N; i++) { 3310 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3311 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3312 doResume && i == (N-1), null); 3313 } 3314 mPendingActivityLaunches.clear(); 3315 } 3316 3317 @Override 3318 public final int startActivity(IApplicationThread caller, String callingPackage, 3319 Intent intent, String resolvedType, IBinder resultTo, 3320 String resultWho, int requestCode, int startFlags, 3321 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3322 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3323 resultWho, requestCode, 3324 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3325 } 3326 3327 @Override 3328 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3329 Intent intent, String resolvedType, IBinder resultTo, 3330 String resultWho, int requestCode, int startFlags, 3331 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3332 enforceNotIsolatedCaller("startActivity"); 3333 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3334 false, true, "startActivity", null); 3335 // TODO: Switch to user app stacks here. 3336 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3337 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3338 null, null, options, userId, null); 3339 } 3340 3341 @Override 3342 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3343 Intent intent, String resolvedType, IBinder resultTo, 3344 String resultWho, int requestCode, int startFlags, String profileFile, 3345 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3346 enforceNotIsolatedCaller("startActivityAndWait"); 3347 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3348 false, true, "startActivityAndWait", null); 3349 WaitResult res = new WaitResult(); 3350 // TODO: Switch to user app stacks here. 3351 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3352 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3353 res, null, options, UserHandle.getCallingUserId(), null); 3354 return res; 3355 } 3356 3357 @Override 3358 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3359 Intent intent, String resolvedType, IBinder resultTo, 3360 String resultWho, int requestCode, int startFlags, Configuration config, 3361 Bundle options, int userId) { 3362 enforceNotIsolatedCaller("startActivityWithConfig"); 3363 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3364 false, true, "startActivityWithConfig", null); 3365 // TODO: Switch to user app stacks here. 3366 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3367 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3368 null, null, null, config, options, userId, null); 3369 return ret; 3370 } 3371 3372 @Override 3373 public int startActivityIntentSender(IApplicationThread caller, 3374 IntentSender intent, Intent fillInIntent, String resolvedType, 3375 IBinder resultTo, String resultWho, int requestCode, 3376 int flagsMask, int flagsValues, Bundle options) { 3377 enforceNotIsolatedCaller("startActivityIntentSender"); 3378 // Refuse possible leaked file descriptors 3379 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3380 throw new IllegalArgumentException("File descriptors passed in Intent"); 3381 } 3382 3383 IIntentSender sender = intent.getTarget(); 3384 if (!(sender instanceof PendingIntentRecord)) { 3385 throw new IllegalArgumentException("Bad PendingIntent object"); 3386 } 3387 3388 PendingIntentRecord pir = (PendingIntentRecord)sender; 3389 3390 synchronized (this) { 3391 // If this is coming from the currently resumed activity, it is 3392 // effectively saying that app switches are allowed at this point. 3393 final ActivityStack stack = getFocusedStack(); 3394 if (stack.mResumedActivity != null && 3395 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3396 mAppSwitchesAllowedTime = 0; 3397 } 3398 } 3399 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3400 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3401 return ret; 3402 } 3403 3404 @Override 3405 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3406 Intent intent, String resolvedType, IVoiceInteractionSession session, 3407 IVoiceInteractor interactor, int startFlags, String profileFile, 3408 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3409 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3410 != PackageManager.PERMISSION_GRANTED) { 3411 String msg = "Permission Denial: startVoiceActivity() from pid=" 3412 + Binder.getCallingPid() 3413 + ", uid=" + Binder.getCallingUid() 3414 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3415 Slog.w(TAG, msg); 3416 throw new SecurityException(msg); 3417 } 3418 if (session == null || interactor == null) { 3419 throw new NullPointerException("null session or interactor"); 3420 } 3421 userId = handleIncomingUser(callingPid, callingUid, userId, 3422 false, true, "startVoiceActivity", null); 3423 // TODO: Switch to user app stacks here. 3424 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3425 resolvedType, session, interactor, null, null, 0, startFlags, 3426 profileFile, profileFd, null, null, options, userId, null); 3427 } 3428 3429 @Override 3430 public boolean startNextMatchingActivity(IBinder callingActivity, 3431 Intent intent, Bundle options) { 3432 // Refuse possible leaked file descriptors 3433 if (intent != null && intent.hasFileDescriptors() == true) { 3434 throw new IllegalArgumentException("File descriptors passed in Intent"); 3435 } 3436 3437 synchronized (this) { 3438 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3439 if (r == null) { 3440 ActivityOptions.abort(options); 3441 return false; 3442 } 3443 if (r.app == null || r.app.thread == null) { 3444 // The caller is not running... d'oh! 3445 ActivityOptions.abort(options); 3446 return false; 3447 } 3448 intent = new Intent(intent); 3449 // The caller is not allowed to change the data. 3450 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3451 // And we are resetting to find the next component... 3452 intent.setComponent(null); 3453 3454 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3455 3456 ActivityInfo aInfo = null; 3457 try { 3458 List<ResolveInfo> resolves = 3459 AppGlobals.getPackageManager().queryIntentActivities( 3460 intent, r.resolvedType, 3461 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3462 UserHandle.getCallingUserId()); 3463 3464 // Look for the original activity in the list... 3465 final int N = resolves != null ? resolves.size() : 0; 3466 for (int i=0; i<N; i++) { 3467 ResolveInfo rInfo = resolves.get(i); 3468 if (rInfo.activityInfo.packageName.equals(r.packageName) 3469 && rInfo.activityInfo.name.equals(r.info.name)) { 3470 // We found the current one... the next matching is 3471 // after it. 3472 i++; 3473 if (i<N) { 3474 aInfo = resolves.get(i).activityInfo; 3475 } 3476 if (debug) { 3477 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3478 + "/" + r.info.name); 3479 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3480 + "/" + aInfo.name); 3481 } 3482 break; 3483 } 3484 } 3485 } catch (RemoteException e) { 3486 } 3487 3488 if (aInfo == null) { 3489 // Nobody who is next! 3490 ActivityOptions.abort(options); 3491 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3492 return false; 3493 } 3494 3495 intent.setComponent(new ComponentName( 3496 aInfo.applicationInfo.packageName, aInfo.name)); 3497 intent.setFlags(intent.getFlags()&~( 3498 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3499 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3500 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3501 Intent.FLAG_ACTIVITY_NEW_TASK)); 3502 3503 // Okay now we need to start the new activity, replacing the 3504 // currently running activity. This is a little tricky because 3505 // we want to start the new one as if the current one is finished, 3506 // but not finish the current one first so that there is no flicker. 3507 // And thus... 3508 final boolean wasFinishing = r.finishing; 3509 r.finishing = true; 3510 3511 // Propagate reply information over to the new activity. 3512 final ActivityRecord resultTo = r.resultTo; 3513 final String resultWho = r.resultWho; 3514 final int requestCode = r.requestCode; 3515 r.resultTo = null; 3516 if (resultTo != null) { 3517 resultTo.removeResultsLocked(r, resultWho, requestCode); 3518 } 3519 3520 final long origId = Binder.clearCallingIdentity(); 3521 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3522 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3523 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3524 options, false, null, null); 3525 Binder.restoreCallingIdentity(origId); 3526 3527 r.finishing = wasFinishing; 3528 if (res != ActivityManager.START_SUCCESS) { 3529 return false; 3530 } 3531 return true; 3532 } 3533 } 3534 3535 final int startActivityInPackage(int uid, String callingPackage, 3536 Intent intent, String resolvedType, IBinder resultTo, 3537 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3538 IActivityContainer container) { 3539 3540 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3541 false, true, "startActivityInPackage", null); 3542 3543 // TODO: Switch to user app stacks here. 3544 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3545 null, null, resultTo, resultWho, requestCode, startFlags, 3546 null, null, null, null, options, userId, container); 3547 return ret; 3548 } 3549 3550 @Override 3551 public final int startActivities(IApplicationThread caller, String callingPackage, 3552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3553 int userId) { 3554 enforceNotIsolatedCaller("startActivities"); 3555 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3556 false, true, "startActivity", null); 3557 // TODO: Switch to user app stacks here. 3558 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3559 resolvedTypes, resultTo, options, userId); 3560 return ret; 3561 } 3562 3563 final int startActivitiesInPackage(int uid, String callingPackage, 3564 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3565 Bundle options, int userId) { 3566 3567 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3568 false, true, "startActivityInPackage", null); 3569 // TODO: Switch to user app stacks here. 3570 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3571 resultTo, options, userId); 3572 return ret; 3573 } 3574 3575 final void addRecentTaskLocked(TaskRecord task) { 3576 int N = mRecentTasks.size(); 3577 // Quick case: check if the top-most recent task is the same. 3578 if (N > 0 && mRecentTasks.get(0) == task) { 3579 return; 3580 } 3581 // Another quick case: never add voice sessions. 3582 if (task.voiceSession != null) { 3583 return; 3584 } 3585 // Remove any existing entries that are the same kind of task. 3586 final Intent intent = task.intent; 3587 final boolean document = intent != null && intent.isDocument(); 3588 final ComponentName comp = intent.getComponent(); 3589 3590 int maxRecents = task.maxRecents - 1; 3591 for (int i=0; i<N; i++) { 3592 TaskRecord tr = mRecentTasks.get(i); 3593 if (task != tr) { 3594 if (task.userId != tr.userId) { 3595 continue; 3596 } 3597 final Intent trIntent = tr.intent; 3598 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3599 (intent == null || !intent.filterEquals(trIntent))) { 3600 continue; 3601 } 3602 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3603 if (document && trIsDocument) { 3604 // These are the same document activity (not necessarily the same doc). 3605 if (maxRecents > 0) { 3606 --maxRecents; 3607 continue; 3608 } 3609 // Hit the maximum number of documents for this task. Fall through 3610 // and remove this document from recents. 3611 } else if (document || trIsDocument) { 3612 // Only one of these is a document. Not the droid we're looking for. 3613 continue; 3614 } 3615 } 3616 3617 // Either task and tr are the same or, their affinities match or their intents match 3618 // and neither of them is a document, or they are documents using the same activity 3619 // and their maxRecents has been reached. 3620 tr.disposeThumbnail(); 3621 mRecentTasks.remove(i); 3622 i--; 3623 N--; 3624 if (task.intent == null) { 3625 // If the new recent task we are adding is not fully 3626 // specified, then replace it with the existing recent task. 3627 task = tr; 3628 } 3629 mTaskPersister.notify(tr, false); 3630 } 3631 if (N >= MAX_RECENT_TASKS) { 3632 mRecentTasks.remove(N-1).disposeThumbnail(); 3633 } 3634 mRecentTasks.add(0, task); 3635 } 3636 3637 @Override 3638 public void reportActivityFullyDrawn(IBinder token) { 3639 synchronized (this) { 3640 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3641 if (r == null) { 3642 return; 3643 } 3644 r.reportFullyDrawnLocked(); 3645 } 3646 } 3647 3648 @Override 3649 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3650 synchronized (this) { 3651 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3652 if (r == null) { 3653 return; 3654 } 3655 final long origId = Binder.clearCallingIdentity(); 3656 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3657 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3658 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3659 if (config != null) { 3660 r.frozenBeforeDestroy = true; 3661 if (!updateConfigurationLocked(config, r, false, false)) { 3662 mStackSupervisor.resumeTopActivitiesLocked(); 3663 } 3664 } 3665 Binder.restoreCallingIdentity(origId); 3666 } 3667 } 3668 3669 @Override 3670 public int getRequestedOrientation(IBinder token) { 3671 synchronized (this) { 3672 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3673 if (r == null) { 3674 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3675 } 3676 return mWindowManager.getAppOrientation(r.appToken); 3677 } 3678 } 3679 3680 /** 3681 * This is the internal entry point for handling Activity.finish(). 3682 * 3683 * @param token The Binder token referencing the Activity we want to finish. 3684 * @param resultCode Result code, if any, from this Activity. 3685 * @param resultData Result data (Intent), if any, from this Activity. 3686 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3687 * the root Activity in the task. 3688 * 3689 * @return Returns true if the activity successfully finished, or false if it is still running. 3690 */ 3691 @Override 3692 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3693 boolean finishTask) { 3694 // Refuse possible leaked file descriptors 3695 if (resultData != null && resultData.hasFileDescriptors() == true) { 3696 throw new IllegalArgumentException("File descriptors passed in Intent"); 3697 } 3698 3699 synchronized(this) { 3700 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3701 if (r == null) { 3702 return true; 3703 } 3704 // Keep track of the root activity of the task before we finish it 3705 TaskRecord tr = r.task; 3706 ActivityRecord rootR = tr.getRootActivity(); 3707 if (mController != null) { 3708 // Find the first activity that is not finishing. 3709 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3710 if (next != null) { 3711 // ask watcher if this is allowed 3712 boolean resumeOK = true; 3713 try { 3714 resumeOK = mController.activityResuming(next.packageName); 3715 } catch (RemoteException e) { 3716 mController = null; 3717 Watchdog.getInstance().setActivityController(null); 3718 } 3719 3720 if (!resumeOK) { 3721 return false; 3722 } 3723 } 3724 } 3725 final long origId = Binder.clearCallingIdentity(); 3726 try { 3727 boolean res; 3728 if (finishTask && r == rootR) { 3729 // If requested, remove the task that is associated to this activity only if it 3730 // was the root activity in the task. The result code and data is ignored because 3731 // we don't support returning them across task boundaries. 3732 res = removeTaskByIdLocked(tr.taskId, 0); 3733 } else { 3734 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3735 resultData, "app-request", true); 3736 } 3737 return res; 3738 } finally { 3739 Binder.restoreCallingIdentity(origId); 3740 } 3741 } 3742 } 3743 3744 @Override 3745 public final void finishHeavyWeightApp() { 3746 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3747 != PackageManager.PERMISSION_GRANTED) { 3748 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3749 + Binder.getCallingPid() 3750 + ", uid=" + Binder.getCallingUid() 3751 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3752 Slog.w(TAG, msg); 3753 throw new SecurityException(msg); 3754 } 3755 3756 synchronized(this) { 3757 if (mHeavyWeightProcess == null) { 3758 return; 3759 } 3760 3761 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3762 mHeavyWeightProcess.activities); 3763 for (int i=0; i<activities.size(); i++) { 3764 ActivityRecord r = activities.get(i); 3765 if (!r.finishing) { 3766 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3767 null, "finish-heavy", true); 3768 } 3769 } 3770 3771 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3772 mHeavyWeightProcess.userId, 0)); 3773 mHeavyWeightProcess = null; 3774 } 3775 } 3776 3777 @Override 3778 public void crashApplication(int uid, int initialPid, String packageName, 3779 String message) { 3780 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3781 != PackageManager.PERMISSION_GRANTED) { 3782 String msg = "Permission Denial: crashApplication() from pid=" 3783 + Binder.getCallingPid() 3784 + ", uid=" + Binder.getCallingUid() 3785 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3786 Slog.w(TAG, msg); 3787 throw new SecurityException(msg); 3788 } 3789 3790 synchronized(this) { 3791 ProcessRecord proc = null; 3792 3793 // Figure out which process to kill. We don't trust that initialPid 3794 // still has any relation to current pids, so must scan through the 3795 // list. 3796 synchronized (mPidsSelfLocked) { 3797 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3798 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3799 if (p.uid != uid) { 3800 continue; 3801 } 3802 if (p.pid == initialPid) { 3803 proc = p; 3804 break; 3805 } 3806 if (p.pkgList.containsKey(packageName)) { 3807 proc = p; 3808 } 3809 } 3810 } 3811 3812 if (proc == null) { 3813 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3814 + " initialPid=" + initialPid 3815 + " packageName=" + packageName); 3816 return; 3817 } 3818 3819 if (proc.thread != null) { 3820 if (proc.pid == Process.myPid()) { 3821 Log.w(TAG, "crashApplication: trying to crash self!"); 3822 return; 3823 } 3824 long ident = Binder.clearCallingIdentity(); 3825 try { 3826 proc.thread.scheduleCrash(message); 3827 } catch (RemoteException e) { 3828 } 3829 Binder.restoreCallingIdentity(ident); 3830 } 3831 } 3832 } 3833 3834 @Override 3835 public final void finishSubActivity(IBinder token, String resultWho, 3836 int requestCode) { 3837 synchronized(this) { 3838 final long origId = Binder.clearCallingIdentity(); 3839 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3840 if (r != null) { 3841 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3842 } 3843 Binder.restoreCallingIdentity(origId); 3844 } 3845 } 3846 3847 @Override 3848 public boolean finishActivityAffinity(IBinder token) { 3849 synchronized(this) { 3850 final long origId = Binder.clearCallingIdentity(); 3851 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3852 boolean res = false; 3853 if (r != null) { 3854 res = r.task.stack.finishActivityAffinityLocked(r); 3855 } 3856 Binder.restoreCallingIdentity(origId); 3857 return res; 3858 } 3859 } 3860 3861 @Override 3862 public boolean willActivityBeVisible(IBinder token) { 3863 synchronized(this) { 3864 ActivityStack stack = ActivityRecord.getStackLocked(token); 3865 if (stack != null) { 3866 return stack.willActivityBeVisibleLocked(token); 3867 } 3868 return false; 3869 } 3870 } 3871 3872 @Override 3873 public void overridePendingTransition(IBinder token, String packageName, 3874 int enterAnim, int exitAnim) { 3875 synchronized(this) { 3876 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3877 if (self == null) { 3878 return; 3879 } 3880 3881 final long origId = Binder.clearCallingIdentity(); 3882 3883 if (self.state == ActivityState.RESUMED 3884 || self.state == ActivityState.PAUSING) { 3885 mWindowManager.overridePendingAppTransition(packageName, 3886 enterAnim, exitAnim, null); 3887 } 3888 3889 Binder.restoreCallingIdentity(origId); 3890 } 3891 } 3892 3893 /** 3894 * Main function for removing an existing process from the activity manager 3895 * as a result of that process going away. Clears out all connections 3896 * to the process. 3897 */ 3898 private final void handleAppDiedLocked(ProcessRecord app, 3899 boolean restarting, boolean allowRestart) { 3900 int pid = app.pid; 3901 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3902 if (!restarting) { 3903 removeLruProcessLocked(app); 3904 if (pid > 0) { 3905 ProcessList.remove(pid); 3906 } 3907 } 3908 3909 if (mProfileProc == app) { 3910 clearProfilerLocked(); 3911 } 3912 3913 // Remove this application's activities from active lists. 3914 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3915 3916 app.activities.clear(); 3917 3918 if (app.instrumentationClass != null) { 3919 Slog.w(TAG, "Crash of app " + app.processName 3920 + " running instrumentation " + app.instrumentationClass); 3921 Bundle info = new Bundle(); 3922 info.putString("shortMsg", "Process crashed."); 3923 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3924 } 3925 3926 if (!restarting) { 3927 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3928 // If there was nothing to resume, and we are not already 3929 // restarting this process, but there is a visible activity that 3930 // is hosted by the process... then make sure all visible 3931 // activities are running, taking care of restarting this 3932 // process. 3933 if (hasVisibleActivities) { 3934 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3935 } 3936 } 3937 } 3938 } 3939 3940 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3941 IBinder threadBinder = thread.asBinder(); 3942 // Find the application record. 3943 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3944 ProcessRecord rec = mLruProcesses.get(i); 3945 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3946 return i; 3947 } 3948 } 3949 return -1; 3950 } 3951 3952 final ProcessRecord getRecordForAppLocked( 3953 IApplicationThread thread) { 3954 if (thread == null) { 3955 return null; 3956 } 3957 3958 int appIndex = getLRURecordIndexForAppLocked(thread); 3959 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3960 } 3961 3962 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3963 // If there are no longer any background processes running, 3964 // and the app that died was not running instrumentation, 3965 // then tell everyone we are now low on memory. 3966 boolean haveBg = false; 3967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3968 ProcessRecord rec = mLruProcesses.get(i); 3969 if (rec.thread != null 3970 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3971 haveBg = true; 3972 break; 3973 } 3974 } 3975 3976 if (!haveBg) { 3977 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3978 if (doReport) { 3979 long now = SystemClock.uptimeMillis(); 3980 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3981 doReport = false; 3982 } else { 3983 mLastMemUsageReportTime = now; 3984 } 3985 } 3986 final ArrayList<ProcessMemInfo> memInfos 3987 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3988 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3989 long now = SystemClock.uptimeMillis(); 3990 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3991 ProcessRecord rec = mLruProcesses.get(i); 3992 if (rec == dyingProc || rec.thread == null) { 3993 continue; 3994 } 3995 if (doReport) { 3996 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3997 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3998 } 3999 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4000 // The low memory report is overriding any current 4001 // state for a GC request. Make sure to do 4002 // heavy/important/visible/foreground processes first. 4003 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4004 rec.lastRequestedGc = 0; 4005 } else { 4006 rec.lastRequestedGc = rec.lastLowMemory; 4007 } 4008 rec.reportLowMemory = true; 4009 rec.lastLowMemory = now; 4010 mProcessesToGc.remove(rec); 4011 addProcessToGcListLocked(rec); 4012 } 4013 } 4014 if (doReport) { 4015 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4016 mHandler.sendMessage(msg); 4017 } 4018 scheduleAppGcsLocked(); 4019 } 4020 } 4021 4022 final void appDiedLocked(ProcessRecord app, int pid, 4023 IApplicationThread thread) { 4024 4025 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4026 synchronized (stats) { 4027 stats.noteProcessDiedLocked(app.info.uid, pid); 4028 } 4029 4030 // Clean up already done if the process has been re-started. 4031 if (app.pid == pid && app.thread != null && 4032 app.thread.asBinder() == thread.asBinder()) { 4033 boolean doLowMem = app.instrumentationClass == null; 4034 boolean doOomAdj = doLowMem; 4035 if (!app.killedByAm) { 4036 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4037 + ") has died."); 4038 mAllowLowerMemLevel = true; 4039 } else { 4040 // Note that we always want to do oom adj to update our state with the 4041 // new number of procs. 4042 mAllowLowerMemLevel = false; 4043 doLowMem = false; 4044 } 4045 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4046 if (DEBUG_CLEANUP) Slog.v( 4047 TAG, "Dying app: " + app + ", pid: " + pid 4048 + ", thread: " + thread.asBinder()); 4049 handleAppDiedLocked(app, false, true); 4050 4051 if (doOomAdj) { 4052 updateOomAdjLocked(); 4053 } 4054 if (doLowMem) { 4055 doLowMemReportIfNeededLocked(app); 4056 } 4057 } else if (app.pid != pid) { 4058 // A new process has already been started. 4059 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4060 + ") has died and restarted (pid " + app.pid + ")."); 4061 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4062 } else if (DEBUG_PROCESSES) { 4063 Slog.d(TAG, "Received spurious death notification for thread " 4064 + thread.asBinder()); 4065 } 4066 } 4067 4068 /** 4069 * If a stack trace dump file is configured, dump process stack traces. 4070 * @param clearTraces causes the dump file to be erased prior to the new 4071 * traces being written, if true; when false, the new traces will be 4072 * appended to any existing file content. 4073 * @param firstPids of dalvik VM processes to dump stack traces for first 4074 * @param lastPids of dalvik VM processes to dump stack traces for last 4075 * @param nativeProcs optional list of native process names to dump stack crawls 4076 * @return file containing stack traces, or null if no dump file is configured 4077 */ 4078 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4079 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4080 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4081 if (tracesPath == null || tracesPath.length() == 0) { 4082 return null; 4083 } 4084 4085 File tracesFile = new File(tracesPath); 4086 try { 4087 File tracesDir = tracesFile.getParentFile(); 4088 if (!tracesDir.exists()) { 4089 tracesFile.mkdirs(); 4090 if (!SELinux.restorecon(tracesDir)) { 4091 return null; 4092 } 4093 } 4094 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4095 4096 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4097 tracesFile.createNewFile(); 4098 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4099 } catch (IOException e) { 4100 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4101 return null; 4102 } 4103 4104 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4105 return tracesFile; 4106 } 4107 4108 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4109 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4110 // Use a FileObserver to detect when traces finish writing. 4111 // The order of traces is considered important to maintain for legibility. 4112 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4113 @Override 4114 public synchronized void onEvent(int event, String path) { notify(); } 4115 }; 4116 4117 try { 4118 observer.startWatching(); 4119 4120 // First collect all of the stacks of the most important pids. 4121 if (firstPids != null) { 4122 try { 4123 int num = firstPids.size(); 4124 for (int i = 0; i < num; i++) { 4125 synchronized (observer) { 4126 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4127 observer.wait(200); // Wait for write-close, give up after 200msec 4128 } 4129 } 4130 } catch (InterruptedException e) { 4131 Log.wtf(TAG, e); 4132 } 4133 } 4134 4135 // Next collect the stacks of the native pids 4136 if (nativeProcs != null) { 4137 int[] pids = Process.getPidsForCommands(nativeProcs); 4138 if (pids != null) { 4139 for (int pid : pids) { 4140 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4141 } 4142 } 4143 } 4144 4145 // Lastly, measure CPU usage. 4146 if (processCpuTracker != null) { 4147 processCpuTracker.init(); 4148 System.gc(); 4149 processCpuTracker.update(); 4150 try { 4151 synchronized (processCpuTracker) { 4152 processCpuTracker.wait(500); // measure over 1/2 second. 4153 } 4154 } catch (InterruptedException e) { 4155 } 4156 processCpuTracker.update(); 4157 4158 // We'll take the stack crawls of just the top apps using CPU. 4159 final int N = processCpuTracker.countWorkingStats(); 4160 int numProcs = 0; 4161 for (int i=0; i<N && numProcs<5; i++) { 4162 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4163 if (lastPids.indexOfKey(stats.pid) >= 0) { 4164 numProcs++; 4165 try { 4166 synchronized (observer) { 4167 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4168 observer.wait(200); // Wait for write-close, give up after 200msec 4169 } 4170 } catch (InterruptedException e) { 4171 Log.wtf(TAG, e); 4172 } 4173 4174 } 4175 } 4176 } 4177 } finally { 4178 observer.stopWatching(); 4179 } 4180 } 4181 4182 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4183 if (true || IS_USER_BUILD) { 4184 return; 4185 } 4186 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4187 if (tracesPath == null || tracesPath.length() == 0) { 4188 return; 4189 } 4190 4191 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4192 StrictMode.allowThreadDiskWrites(); 4193 try { 4194 final File tracesFile = new File(tracesPath); 4195 final File tracesDir = tracesFile.getParentFile(); 4196 final File tracesTmp = new File(tracesDir, "__tmp__"); 4197 try { 4198 if (!tracesDir.exists()) { 4199 tracesFile.mkdirs(); 4200 if (!SELinux.restorecon(tracesDir.getPath())) { 4201 return; 4202 } 4203 } 4204 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4205 4206 if (tracesFile.exists()) { 4207 tracesTmp.delete(); 4208 tracesFile.renameTo(tracesTmp); 4209 } 4210 StringBuilder sb = new StringBuilder(); 4211 Time tobj = new Time(); 4212 tobj.set(System.currentTimeMillis()); 4213 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4214 sb.append(": "); 4215 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4216 sb.append(" since "); 4217 sb.append(msg); 4218 FileOutputStream fos = new FileOutputStream(tracesFile); 4219 fos.write(sb.toString().getBytes()); 4220 if (app == null) { 4221 fos.write("\n*** No application process!".getBytes()); 4222 } 4223 fos.close(); 4224 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4225 } catch (IOException e) { 4226 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4227 return; 4228 } 4229 4230 if (app != null) { 4231 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4232 firstPids.add(app.pid); 4233 dumpStackTraces(tracesPath, firstPids, null, null, null); 4234 } 4235 4236 File lastTracesFile = null; 4237 File curTracesFile = null; 4238 for (int i=9; i>=0; i--) { 4239 String name = String.format(Locale.US, "slow%02d.txt", i); 4240 curTracesFile = new File(tracesDir, name); 4241 if (curTracesFile.exists()) { 4242 if (lastTracesFile != null) { 4243 curTracesFile.renameTo(lastTracesFile); 4244 } else { 4245 curTracesFile.delete(); 4246 } 4247 } 4248 lastTracesFile = curTracesFile; 4249 } 4250 tracesFile.renameTo(curTracesFile); 4251 if (tracesTmp.exists()) { 4252 tracesTmp.renameTo(tracesFile); 4253 } 4254 } finally { 4255 StrictMode.setThreadPolicy(oldPolicy); 4256 } 4257 } 4258 4259 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4260 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4261 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4262 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4263 4264 if (mController != null) { 4265 try { 4266 // 0 == continue, -1 = kill process immediately 4267 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4268 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4269 } catch (RemoteException e) { 4270 mController = null; 4271 Watchdog.getInstance().setActivityController(null); 4272 } 4273 } 4274 4275 long anrTime = SystemClock.uptimeMillis(); 4276 if (MONITOR_CPU_USAGE) { 4277 updateCpuStatsNow(); 4278 } 4279 4280 synchronized (this) { 4281 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4282 if (mShuttingDown) { 4283 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4284 return; 4285 } else if (app.notResponding) { 4286 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4287 return; 4288 } else if (app.crashing) { 4289 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4290 return; 4291 } 4292 4293 // In case we come through here for the same app before completing 4294 // this one, mark as anring now so we will bail out. 4295 app.notResponding = true; 4296 4297 // Log the ANR to the event log. 4298 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4299 app.processName, app.info.flags, annotation); 4300 4301 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4302 firstPids.add(app.pid); 4303 4304 int parentPid = app.pid; 4305 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4306 if (parentPid != app.pid) firstPids.add(parentPid); 4307 4308 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4309 4310 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4311 ProcessRecord r = mLruProcesses.get(i); 4312 if (r != null && r.thread != null) { 4313 int pid = r.pid; 4314 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4315 if (r.persistent) { 4316 firstPids.add(pid); 4317 } else { 4318 lastPids.put(pid, Boolean.TRUE); 4319 } 4320 } 4321 } 4322 } 4323 } 4324 4325 // Log the ANR to the main log. 4326 StringBuilder info = new StringBuilder(); 4327 info.setLength(0); 4328 info.append("ANR in ").append(app.processName); 4329 if (activity != null && activity.shortComponentName != null) { 4330 info.append(" (").append(activity.shortComponentName).append(")"); 4331 } 4332 info.append("\n"); 4333 info.append("PID: ").append(app.pid).append("\n"); 4334 if (annotation != null) { 4335 info.append("Reason: ").append(annotation).append("\n"); 4336 } 4337 if (parent != null && parent != activity) { 4338 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4339 } 4340 4341 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4342 4343 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4344 NATIVE_STACKS_OF_INTEREST); 4345 4346 String cpuInfo = null; 4347 if (MONITOR_CPU_USAGE) { 4348 updateCpuStatsNow(); 4349 synchronized (mProcessCpuThread) { 4350 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4351 } 4352 info.append(processCpuTracker.printCurrentLoad()); 4353 info.append(cpuInfo); 4354 } 4355 4356 info.append(processCpuTracker.printCurrentState(anrTime)); 4357 4358 Slog.e(TAG, info.toString()); 4359 if (tracesFile == null) { 4360 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4361 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4362 } 4363 4364 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4365 cpuInfo, tracesFile, null); 4366 4367 if (mController != null) { 4368 try { 4369 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4370 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4371 if (res != 0) { 4372 if (res < 0 && app.pid != MY_PID) { 4373 Process.killProcess(app.pid); 4374 } else { 4375 synchronized (this) { 4376 mServices.scheduleServiceTimeoutLocked(app); 4377 } 4378 } 4379 return; 4380 } 4381 } catch (RemoteException e) { 4382 mController = null; 4383 Watchdog.getInstance().setActivityController(null); 4384 } 4385 } 4386 4387 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4388 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4389 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4390 4391 synchronized (this) { 4392 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4393 killUnneededProcessLocked(app, "background ANR"); 4394 return; 4395 } 4396 4397 // Set the app's notResponding state, and look up the errorReportReceiver 4398 makeAppNotRespondingLocked(app, 4399 activity != null ? activity.shortComponentName : null, 4400 annotation != null ? "ANR " + annotation : "ANR", 4401 info.toString()); 4402 4403 // Bring up the infamous App Not Responding dialog 4404 Message msg = Message.obtain(); 4405 HashMap<String, Object> map = new HashMap<String, Object>(); 4406 msg.what = SHOW_NOT_RESPONDING_MSG; 4407 msg.obj = map; 4408 msg.arg1 = aboveSystem ? 1 : 0; 4409 map.put("app", app); 4410 if (activity != null) { 4411 map.put("activity", activity); 4412 } 4413 4414 mHandler.sendMessage(msg); 4415 } 4416 } 4417 4418 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4419 if (!mLaunchWarningShown) { 4420 mLaunchWarningShown = true; 4421 mHandler.post(new Runnable() { 4422 @Override 4423 public void run() { 4424 synchronized (ActivityManagerService.this) { 4425 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4426 d.show(); 4427 mHandler.postDelayed(new Runnable() { 4428 @Override 4429 public void run() { 4430 synchronized (ActivityManagerService.this) { 4431 d.dismiss(); 4432 mLaunchWarningShown = false; 4433 } 4434 } 4435 }, 4000); 4436 } 4437 } 4438 }); 4439 } 4440 } 4441 4442 @Override 4443 public boolean clearApplicationUserData(final String packageName, 4444 final IPackageDataObserver observer, int userId) { 4445 enforceNotIsolatedCaller("clearApplicationUserData"); 4446 int uid = Binder.getCallingUid(); 4447 int pid = Binder.getCallingPid(); 4448 userId = handleIncomingUser(pid, uid, 4449 userId, false, true, "clearApplicationUserData", null); 4450 long callingId = Binder.clearCallingIdentity(); 4451 try { 4452 IPackageManager pm = AppGlobals.getPackageManager(); 4453 int pkgUid = -1; 4454 synchronized(this) { 4455 try { 4456 pkgUid = pm.getPackageUid(packageName, userId); 4457 } catch (RemoteException e) { 4458 } 4459 if (pkgUid == -1) { 4460 Slog.w(TAG, "Invalid packageName: " + packageName); 4461 if (observer != null) { 4462 try { 4463 observer.onRemoveCompleted(packageName, false); 4464 } catch (RemoteException e) { 4465 Slog.i(TAG, "Observer no longer exists."); 4466 } 4467 } 4468 return false; 4469 } 4470 if (uid == pkgUid || checkComponentPermission( 4471 android.Manifest.permission.CLEAR_APP_USER_DATA, 4472 pid, uid, -1, true) 4473 == PackageManager.PERMISSION_GRANTED) { 4474 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4475 } else { 4476 throw new SecurityException("PID " + pid + " does not have permission " 4477 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4478 + " of package " + packageName); 4479 } 4480 } 4481 4482 try { 4483 // Clear application user data 4484 pm.clearApplicationUserData(packageName, observer, userId); 4485 4486 // Remove all permissions granted from/to this package 4487 removeUriPermissionsForPackageLocked(packageName, userId, true); 4488 4489 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4490 Uri.fromParts("package", packageName, null)); 4491 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4492 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4493 null, null, 0, null, null, null, false, false, userId); 4494 } catch (RemoteException e) { 4495 } 4496 } finally { 4497 Binder.restoreCallingIdentity(callingId); 4498 } 4499 return true; 4500 } 4501 4502 @Override 4503 public void killBackgroundProcesses(final String packageName, int userId) { 4504 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4505 != PackageManager.PERMISSION_GRANTED && 4506 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4507 != PackageManager.PERMISSION_GRANTED) { 4508 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4509 + Binder.getCallingPid() 4510 + ", uid=" + Binder.getCallingUid() 4511 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4512 Slog.w(TAG, msg); 4513 throw new SecurityException(msg); 4514 } 4515 4516 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4517 userId, true, true, "killBackgroundProcesses", null); 4518 long callingId = Binder.clearCallingIdentity(); 4519 try { 4520 IPackageManager pm = AppGlobals.getPackageManager(); 4521 synchronized(this) { 4522 int appId = -1; 4523 try { 4524 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4525 } catch (RemoteException e) { 4526 } 4527 if (appId == -1) { 4528 Slog.w(TAG, "Invalid packageName: " + packageName); 4529 return; 4530 } 4531 killPackageProcessesLocked(packageName, appId, userId, 4532 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4533 } 4534 } finally { 4535 Binder.restoreCallingIdentity(callingId); 4536 } 4537 } 4538 4539 @Override 4540 public void killAllBackgroundProcesses() { 4541 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4542 != PackageManager.PERMISSION_GRANTED) { 4543 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4544 + Binder.getCallingPid() 4545 + ", uid=" + Binder.getCallingUid() 4546 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4547 Slog.w(TAG, msg); 4548 throw new SecurityException(msg); 4549 } 4550 4551 long callingId = Binder.clearCallingIdentity(); 4552 try { 4553 synchronized(this) { 4554 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4555 final int NP = mProcessNames.getMap().size(); 4556 for (int ip=0; ip<NP; ip++) { 4557 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4558 final int NA = apps.size(); 4559 for (int ia=0; ia<NA; ia++) { 4560 ProcessRecord app = apps.valueAt(ia); 4561 if (app.persistent) { 4562 // we don't kill persistent processes 4563 continue; 4564 } 4565 if (app.removed) { 4566 procs.add(app); 4567 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4568 app.removed = true; 4569 procs.add(app); 4570 } 4571 } 4572 } 4573 4574 int N = procs.size(); 4575 for (int i=0; i<N; i++) { 4576 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4577 } 4578 mAllowLowerMemLevel = true; 4579 updateOomAdjLocked(); 4580 doLowMemReportIfNeededLocked(null); 4581 } 4582 } finally { 4583 Binder.restoreCallingIdentity(callingId); 4584 } 4585 } 4586 4587 @Override 4588 public void forceStopPackage(final String packageName, int userId) { 4589 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4590 != PackageManager.PERMISSION_GRANTED) { 4591 String msg = "Permission Denial: forceStopPackage() from pid=" 4592 + Binder.getCallingPid() 4593 + ", uid=" + Binder.getCallingUid() 4594 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4595 Slog.w(TAG, msg); 4596 throw new SecurityException(msg); 4597 } 4598 final int callingPid = Binder.getCallingPid(); 4599 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4600 userId, true, true, "forceStopPackage", null); 4601 long callingId = Binder.clearCallingIdentity(); 4602 try { 4603 IPackageManager pm = AppGlobals.getPackageManager(); 4604 synchronized(this) { 4605 int[] users = userId == UserHandle.USER_ALL 4606 ? getUsersLocked() : new int[] { userId }; 4607 for (int user : users) { 4608 int pkgUid = -1; 4609 try { 4610 pkgUid = pm.getPackageUid(packageName, user); 4611 } catch (RemoteException e) { 4612 } 4613 if (pkgUid == -1) { 4614 Slog.w(TAG, "Invalid packageName: " + packageName); 4615 continue; 4616 } 4617 try { 4618 pm.setPackageStoppedState(packageName, true, user); 4619 } catch (RemoteException e) { 4620 } catch (IllegalArgumentException e) { 4621 Slog.w(TAG, "Failed trying to unstop package " 4622 + packageName + ": " + e); 4623 } 4624 if (isUserRunningLocked(user, false)) { 4625 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4626 } 4627 } 4628 } 4629 } finally { 4630 Binder.restoreCallingIdentity(callingId); 4631 } 4632 } 4633 4634 /* 4635 * The pkg name and app id have to be specified. 4636 */ 4637 @Override 4638 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4639 if (pkg == null) { 4640 return; 4641 } 4642 // Make sure the uid is valid. 4643 if (appid < 0) { 4644 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4645 return; 4646 } 4647 int callerUid = Binder.getCallingUid(); 4648 // Only the system server can kill an application 4649 if (callerUid == Process.SYSTEM_UID) { 4650 // Post an aysnc message to kill the application 4651 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4652 msg.arg1 = appid; 4653 msg.arg2 = 0; 4654 Bundle bundle = new Bundle(); 4655 bundle.putString("pkg", pkg); 4656 bundle.putString("reason", reason); 4657 msg.obj = bundle; 4658 mHandler.sendMessage(msg); 4659 } else { 4660 throw new SecurityException(callerUid + " cannot kill pkg: " + 4661 pkg); 4662 } 4663 } 4664 4665 @Override 4666 public void closeSystemDialogs(String reason) { 4667 enforceNotIsolatedCaller("closeSystemDialogs"); 4668 4669 final int pid = Binder.getCallingPid(); 4670 final int uid = Binder.getCallingUid(); 4671 final long origId = Binder.clearCallingIdentity(); 4672 try { 4673 synchronized (this) { 4674 // Only allow this from foreground processes, so that background 4675 // applications can't abuse it to prevent system UI from being shown. 4676 if (uid >= Process.FIRST_APPLICATION_UID) { 4677 ProcessRecord proc; 4678 synchronized (mPidsSelfLocked) { 4679 proc = mPidsSelfLocked.get(pid); 4680 } 4681 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4682 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4683 + " from background process " + proc); 4684 return; 4685 } 4686 } 4687 closeSystemDialogsLocked(reason); 4688 } 4689 } finally { 4690 Binder.restoreCallingIdentity(origId); 4691 } 4692 } 4693 4694 void closeSystemDialogsLocked(String reason) { 4695 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4697 | Intent.FLAG_RECEIVER_FOREGROUND); 4698 if (reason != null) { 4699 intent.putExtra("reason", reason); 4700 } 4701 mWindowManager.closeSystemDialogs(reason); 4702 4703 mStackSupervisor.closeSystemDialogsLocked(); 4704 4705 broadcastIntentLocked(null, null, intent, null, 4706 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4707 Process.SYSTEM_UID, UserHandle.USER_ALL); 4708 } 4709 4710 @Override 4711 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4712 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4713 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4714 for (int i=pids.length-1; i>=0; i--) { 4715 ProcessRecord proc; 4716 int oomAdj; 4717 synchronized (this) { 4718 synchronized (mPidsSelfLocked) { 4719 proc = mPidsSelfLocked.get(pids[i]); 4720 oomAdj = proc != null ? proc.setAdj : 0; 4721 } 4722 } 4723 infos[i] = new Debug.MemoryInfo(); 4724 Debug.getMemoryInfo(pids[i], infos[i]); 4725 if (proc != null) { 4726 synchronized (this) { 4727 if (proc.thread != null && proc.setAdj == oomAdj) { 4728 // Record this for posterity if the process has been stable. 4729 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4730 infos[i].getTotalUss(), false, proc.pkgList); 4731 } 4732 } 4733 } 4734 } 4735 return infos; 4736 } 4737 4738 @Override 4739 public long[] getProcessPss(int[] pids) { 4740 enforceNotIsolatedCaller("getProcessPss"); 4741 long[] pss = new long[pids.length]; 4742 for (int i=pids.length-1; i>=0; i--) { 4743 ProcessRecord proc; 4744 int oomAdj; 4745 synchronized (this) { 4746 synchronized (mPidsSelfLocked) { 4747 proc = mPidsSelfLocked.get(pids[i]); 4748 oomAdj = proc != null ? proc.setAdj : 0; 4749 } 4750 } 4751 long[] tmpUss = new long[1]; 4752 pss[i] = Debug.getPss(pids[i], tmpUss); 4753 if (proc != null) { 4754 synchronized (this) { 4755 if (proc.thread != null && proc.setAdj == oomAdj) { 4756 // Record this for posterity if the process has been stable. 4757 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4758 } 4759 } 4760 } 4761 } 4762 return pss; 4763 } 4764 4765 @Override 4766 public void killApplicationProcess(String processName, int uid) { 4767 if (processName == null) { 4768 return; 4769 } 4770 4771 int callerUid = Binder.getCallingUid(); 4772 // Only the system server can kill an application 4773 if (callerUid == Process.SYSTEM_UID) { 4774 synchronized (this) { 4775 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4776 if (app != null && app.thread != null) { 4777 try { 4778 app.thread.scheduleSuicide(); 4779 } catch (RemoteException e) { 4780 // If the other end already died, then our work here is done. 4781 } 4782 } else { 4783 Slog.w(TAG, "Process/uid not found attempting kill of " 4784 + processName + " / " + uid); 4785 } 4786 } 4787 } else { 4788 throw new SecurityException(callerUid + " cannot kill app process: " + 4789 processName); 4790 } 4791 } 4792 4793 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4794 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4795 false, true, false, false, UserHandle.getUserId(uid), reason); 4796 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4797 Uri.fromParts("package", packageName, null)); 4798 if (!mProcessesReady) { 4799 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4800 | Intent.FLAG_RECEIVER_FOREGROUND); 4801 } 4802 intent.putExtra(Intent.EXTRA_UID, uid); 4803 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4804 broadcastIntentLocked(null, null, intent, 4805 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4806 false, false, 4807 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4808 } 4809 4810 private void forceStopUserLocked(int userId, String reason) { 4811 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4812 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4813 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4814 | Intent.FLAG_RECEIVER_FOREGROUND); 4815 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4816 broadcastIntentLocked(null, null, intent, 4817 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4818 false, false, 4819 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4820 } 4821 4822 private final boolean killPackageProcessesLocked(String packageName, int appId, 4823 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4824 boolean doit, boolean evenPersistent, String reason) { 4825 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4826 4827 // Remove all processes this package may have touched: all with the 4828 // same UID (except for the system or root user), and all whose name 4829 // matches the package name. 4830 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4831 final int NP = mProcessNames.getMap().size(); 4832 for (int ip=0; ip<NP; ip++) { 4833 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4834 final int NA = apps.size(); 4835 for (int ia=0; ia<NA; ia++) { 4836 ProcessRecord app = apps.valueAt(ia); 4837 if (app.persistent && !evenPersistent) { 4838 // we don't kill persistent processes 4839 continue; 4840 } 4841 if (app.removed) { 4842 if (doit) { 4843 procs.add(app); 4844 } 4845 continue; 4846 } 4847 4848 // Skip process if it doesn't meet our oom adj requirement. 4849 if (app.setAdj < minOomAdj) { 4850 continue; 4851 } 4852 4853 // If no package is specified, we call all processes under the 4854 // give user id. 4855 if (packageName == null) { 4856 if (app.userId != userId) { 4857 continue; 4858 } 4859 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4860 continue; 4861 } 4862 // Package has been specified, we want to hit all processes 4863 // that match it. We need to qualify this by the processes 4864 // that are running under the specified app and user ID. 4865 } else { 4866 if (UserHandle.getAppId(app.uid) != appId) { 4867 continue; 4868 } 4869 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4870 continue; 4871 } 4872 if (!app.pkgList.containsKey(packageName)) { 4873 continue; 4874 } 4875 } 4876 4877 // Process has passed all conditions, kill it! 4878 if (!doit) { 4879 return true; 4880 } 4881 app.removed = true; 4882 procs.add(app); 4883 } 4884 } 4885 4886 int N = procs.size(); 4887 for (int i=0; i<N; i++) { 4888 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4889 } 4890 updateOomAdjLocked(); 4891 return N > 0; 4892 } 4893 4894 private final boolean forceStopPackageLocked(String name, int appId, 4895 boolean callerWillRestart, boolean purgeCache, boolean doit, 4896 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4897 int i; 4898 int N; 4899 4900 if (userId == UserHandle.USER_ALL && name == null) { 4901 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4902 } 4903 4904 if (appId < 0 && name != null) { 4905 try { 4906 appId = UserHandle.getAppId( 4907 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4908 } catch (RemoteException e) { 4909 } 4910 } 4911 4912 if (doit) { 4913 if (name != null) { 4914 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4915 + " user=" + userId + ": " + reason); 4916 } else { 4917 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4918 } 4919 4920 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4921 for (int ip=pmap.size()-1; ip>=0; ip--) { 4922 SparseArray<Long> ba = pmap.valueAt(ip); 4923 for (i=ba.size()-1; i>=0; i--) { 4924 boolean remove = false; 4925 final int entUid = ba.keyAt(i); 4926 if (name != null) { 4927 if (userId == UserHandle.USER_ALL) { 4928 if (UserHandle.getAppId(entUid) == appId) { 4929 remove = true; 4930 } 4931 } else { 4932 if (entUid == UserHandle.getUid(userId, appId)) { 4933 remove = true; 4934 } 4935 } 4936 } else if (UserHandle.getUserId(entUid) == userId) { 4937 remove = true; 4938 } 4939 if (remove) { 4940 ba.removeAt(i); 4941 } 4942 } 4943 if (ba.size() == 0) { 4944 pmap.removeAt(ip); 4945 } 4946 } 4947 } 4948 4949 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4950 -100, callerWillRestart, true, doit, evenPersistent, 4951 name == null ? ("stop user " + userId) : ("stop " + name)); 4952 4953 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4954 if (!doit) { 4955 return true; 4956 } 4957 didSomething = true; 4958 } 4959 4960 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4961 if (!doit) { 4962 return true; 4963 } 4964 didSomething = true; 4965 } 4966 4967 if (name == null) { 4968 // Remove all sticky broadcasts from this user. 4969 mStickyBroadcasts.remove(userId); 4970 } 4971 4972 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4973 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4974 userId, providers)) { 4975 if (!doit) { 4976 return true; 4977 } 4978 didSomething = true; 4979 } 4980 N = providers.size(); 4981 for (i=0; i<N; i++) { 4982 removeDyingProviderLocked(null, providers.get(i), true); 4983 } 4984 4985 // Remove transient permissions granted from/to this package/user 4986 removeUriPermissionsForPackageLocked(name, userId, false); 4987 4988 if (name == null || uninstalling) { 4989 // Remove pending intents. For now we only do this when force 4990 // stopping users, because we have some problems when doing this 4991 // for packages -- app widgets are not currently cleaned up for 4992 // such packages, so they can be left with bad pending intents. 4993 if (mIntentSenderRecords.size() > 0) { 4994 Iterator<WeakReference<PendingIntentRecord>> it 4995 = mIntentSenderRecords.values().iterator(); 4996 while (it.hasNext()) { 4997 WeakReference<PendingIntentRecord> wpir = it.next(); 4998 if (wpir == null) { 4999 it.remove(); 5000 continue; 5001 } 5002 PendingIntentRecord pir = wpir.get(); 5003 if (pir == null) { 5004 it.remove(); 5005 continue; 5006 } 5007 if (name == null) { 5008 // Stopping user, remove all objects for the user. 5009 if (pir.key.userId != userId) { 5010 // Not the same user, skip it. 5011 continue; 5012 } 5013 } else { 5014 if (UserHandle.getAppId(pir.uid) != appId) { 5015 // Different app id, skip it. 5016 continue; 5017 } 5018 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5019 // Different user, skip it. 5020 continue; 5021 } 5022 if (!pir.key.packageName.equals(name)) { 5023 // Different package, skip it. 5024 continue; 5025 } 5026 } 5027 if (!doit) { 5028 return true; 5029 } 5030 didSomething = true; 5031 it.remove(); 5032 pir.canceled = true; 5033 if (pir.key.activity != null) { 5034 pir.key.activity.pendingResults.remove(pir.ref); 5035 } 5036 } 5037 } 5038 } 5039 5040 if (doit) { 5041 if (purgeCache && name != null) { 5042 AttributeCache ac = AttributeCache.instance(); 5043 if (ac != null) { 5044 ac.removePackage(name); 5045 } 5046 } 5047 if (mBooted) { 5048 mStackSupervisor.resumeTopActivitiesLocked(); 5049 mStackSupervisor.scheduleIdleLocked(); 5050 } 5051 } 5052 5053 return didSomething; 5054 } 5055 5056 private final boolean removeProcessLocked(ProcessRecord app, 5057 boolean callerWillRestart, boolean allowRestart, String reason) { 5058 final String name = app.processName; 5059 final int uid = app.uid; 5060 if (DEBUG_PROCESSES) Slog.d( 5061 TAG, "Force removing proc " + app.toShortString() + " (" + name 5062 + "/" + uid + ")"); 5063 5064 mProcessNames.remove(name, uid); 5065 mIsolatedProcesses.remove(app.uid); 5066 if (mHeavyWeightProcess == app) { 5067 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5068 mHeavyWeightProcess.userId, 0)); 5069 mHeavyWeightProcess = null; 5070 } 5071 boolean needRestart = false; 5072 if (app.pid > 0 && app.pid != MY_PID) { 5073 int pid = app.pid; 5074 synchronized (mPidsSelfLocked) { 5075 mPidsSelfLocked.remove(pid); 5076 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5077 } 5078 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5079 app.processName, app.info.uid); 5080 if (app.isolated) { 5081 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5082 } 5083 killUnneededProcessLocked(app, reason); 5084 handleAppDiedLocked(app, true, allowRestart); 5085 removeLruProcessLocked(app); 5086 5087 if (app.persistent && !app.isolated) { 5088 if (!callerWillRestart) { 5089 addAppLocked(app.info, false, null /* ABI override */); 5090 } else { 5091 needRestart = true; 5092 } 5093 } 5094 } else { 5095 mRemovedProcesses.add(app); 5096 } 5097 5098 return needRestart; 5099 } 5100 5101 private final void processStartTimedOutLocked(ProcessRecord app) { 5102 final int pid = app.pid; 5103 boolean gone = false; 5104 synchronized (mPidsSelfLocked) { 5105 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5106 if (knownApp != null && knownApp.thread == null) { 5107 mPidsSelfLocked.remove(pid); 5108 gone = true; 5109 } 5110 } 5111 5112 if (gone) { 5113 Slog.w(TAG, "Process " + app + " failed to attach"); 5114 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5115 pid, app.uid, app.processName); 5116 mProcessNames.remove(app.processName, app.uid); 5117 mIsolatedProcesses.remove(app.uid); 5118 if (mHeavyWeightProcess == app) { 5119 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5120 mHeavyWeightProcess.userId, 0)); 5121 mHeavyWeightProcess = null; 5122 } 5123 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5124 app.processName, app.info.uid); 5125 if (app.isolated) { 5126 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5127 } 5128 // Take care of any launching providers waiting for this process. 5129 checkAppInLaunchingProvidersLocked(app, true); 5130 // Take care of any services that are waiting for the process. 5131 mServices.processStartTimedOutLocked(app); 5132 killUnneededProcessLocked(app, "start timeout"); 5133 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5134 Slog.w(TAG, "Unattached app died before backup, skipping"); 5135 try { 5136 IBackupManager bm = IBackupManager.Stub.asInterface( 5137 ServiceManager.getService(Context.BACKUP_SERVICE)); 5138 bm.agentDisconnected(app.info.packageName); 5139 } catch (RemoteException e) { 5140 // Can't happen; the backup manager is local 5141 } 5142 } 5143 if (isPendingBroadcastProcessLocked(pid)) { 5144 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5145 skipPendingBroadcastLocked(pid); 5146 } 5147 } else { 5148 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5149 } 5150 } 5151 5152 private final boolean attachApplicationLocked(IApplicationThread thread, 5153 int pid) { 5154 5155 // Find the application record that is being attached... either via 5156 // the pid if we are running in multiple processes, or just pull the 5157 // next app record if we are emulating process with anonymous threads. 5158 ProcessRecord app; 5159 if (pid != MY_PID && pid >= 0) { 5160 synchronized (mPidsSelfLocked) { 5161 app = mPidsSelfLocked.get(pid); 5162 } 5163 } else { 5164 app = null; 5165 } 5166 5167 if (app == null) { 5168 Slog.w(TAG, "No pending application record for pid " + pid 5169 + " (IApplicationThread " + thread + "); dropping process"); 5170 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5171 if (pid > 0 && pid != MY_PID) { 5172 Process.killProcessQuiet(pid); 5173 } else { 5174 try { 5175 thread.scheduleExit(); 5176 } catch (Exception e) { 5177 // Ignore exceptions. 5178 } 5179 } 5180 return false; 5181 } 5182 5183 // If this application record is still attached to a previous 5184 // process, clean it up now. 5185 if (app.thread != null) { 5186 handleAppDiedLocked(app, true, true); 5187 } 5188 5189 // Tell the process all about itself. 5190 5191 if (localLOGV) Slog.v( 5192 TAG, "Binding process pid " + pid + " to record " + app); 5193 5194 final String processName = app.processName; 5195 try { 5196 AppDeathRecipient adr = new AppDeathRecipient( 5197 app, pid, thread); 5198 thread.asBinder().linkToDeath(adr, 0); 5199 app.deathRecipient = adr; 5200 } catch (RemoteException e) { 5201 app.resetPackageList(mProcessStats); 5202 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5203 return false; 5204 } 5205 5206 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5207 5208 app.makeActive(thread, mProcessStats); 5209 app.curAdj = app.setAdj = -100; 5210 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5211 app.forcingToForeground = null; 5212 updateProcessForegroundLocked(app, false, false); 5213 app.hasShownUi = false; 5214 app.debugging = false; 5215 app.cached = false; 5216 5217 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5218 5219 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5220 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5221 5222 if (!normalMode) { 5223 Slog.i(TAG, "Launching preboot mode app: " + app); 5224 } 5225 5226 if (localLOGV) Slog.v( 5227 TAG, "New app record " + app 5228 + " thread=" + thread.asBinder() + " pid=" + pid); 5229 try { 5230 int testMode = IApplicationThread.DEBUG_OFF; 5231 if (mDebugApp != null && mDebugApp.equals(processName)) { 5232 testMode = mWaitForDebugger 5233 ? IApplicationThread.DEBUG_WAIT 5234 : IApplicationThread.DEBUG_ON; 5235 app.debugging = true; 5236 if (mDebugTransient) { 5237 mDebugApp = mOrigDebugApp; 5238 mWaitForDebugger = mOrigWaitForDebugger; 5239 } 5240 } 5241 String profileFile = app.instrumentationProfileFile; 5242 ParcelFileDescriptor profileFd = null; 5243 boolean profileAutoStop = false; 5244 if (mProfileApp != null && mProfileApp.equals(processName)) { 5245 mProfileProc = app; 5246 profileFile = mProfileFile; 5247 profileFd = mProfileFd; 5248 profileAutoStop = mAutoStopProfiler; 5249 } 5250 boolean enableOpenGlTrace = false; 5251 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5252 enableOpenGlTrace = true; 5253 mOpenGlTraceApp = null; 5254 } 5255 5256 // If the app is being launched for restore or full backup, set it up specially 5257 boolean isRestrictedBackupMode = false; 5258 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5259 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5260 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5261 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5262 } 5263 5264 ensurePackageDexOpt(app.instrumentationInfo != null 5265 ? app.instrumentationInfo.packageName 5266 : app.info.packageName); 5267 if (app.instrumentationClass != null) { 5268 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5269 } 5270 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5271 + processName + " with config " + mConfiguration); 5272 ApplicationInfo appInfo = app.instrumentationInfo != null 5273 ? app.instrumentationInfo : app.info; 5274 app.compat = compatibilityInfoForPackageLocked(appInfo); 5275 if (profileFd != null) { 5276 profileFd = profileFd.dup(); 5277 } 5278 thread.bindApplication(processName, appInfo, providers, 5279 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5280 app.instrumentationArguments, app.instrumentationWatcher, 5281 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5282 isRestrictedBackupMode || !normalMode, app.persistent, 5283 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5284 mCoreSettingsObserver.getCoreSettingsLocked()); 5285 updateLruProcessLocked(app, false, null); 5286 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5287 } catch (Exception e) { 5288 // todo: Yikes! What should we do? For now we will try to 5289 // start another process, but that could easily get us in 5290 // an infinite loop of restarting processes... 5291 Slog.w(TAG, "Exception thrown during bind!", e); 5292 5293 app.resetPackageList(mProcessStats); 5294 app.unlinkDeathRecipient(); 5295 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5296 return false; 5297 } 5298 5299 // Remove this record from the list of starting applications. 5300 mPersistentStartingProcesses.remove(app); 5301 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5302 "Attach application locked removing on hold: " + app); 5303 mProcessesOnHold.remove(app); 5304 5305 boolean badApp = false; 5306 boolean didSomething = false; 5307 5308 // See if the top visible activity is waiting to run in this process... 5309 if (normalMode) { 5310 try { 5311 if (mStackSupervisor.attachApplicationLocked(app)) { 5312 didSomething = true; 5313 } 5314 } catch (Exception e) { 5315 badApp = true; 5316 } 5317 } 5318 5319 // Find any services that should be running in this process... 5320 if (!badApp) { 5321 try { 5322 didSomething |= mServices.attachApplicationLocked(app, processName); 5323 } catch (Exception e) { 5324 badApp = true; 5325 } 5326 } 5327 5328 // Check if a next-broadcast receiver is in this process... 5329 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5330 try { 5331 didSomething |= sendPendingBroadcastsLocked(app); 5332 } catch (Exception e) { 5333 // If the app died trying to launch the receiver we declare it 'bad' 5334 badApp = true; 5335 } 5336 } 5337 5338 // Check whether the next backup agent is in this process... 5339 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5340 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5341 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5342 try { 5343 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5344 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5345 mBackupTarget.backupMode); 5346 } catch (Exception e) { 5347 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5348 e.printStackTrace(); 5349 } 5350 } 5351 5352 if (badApp) { 5353 // todo: Also need to kill application to deal with all 5354 // kinds of exceptions. 5355 handleAppDiedLocked(app, false, true); 5356 return false; 5357 } 5358 5359 if (!didSomething) { 5360 updateOomAdjLocked(); 5361 } 5362 5363 return true; 5364 } 5365 5366 @Override 5367 public final void attachApplication(IApplicationThread thread) { 5368 synchronized (this) { 5369 int callingPid = Binder.getCallingPid(); 5370 final long origId = Binder.clearCallingIdentity(); 5371 attachApplicationLocked(thread, callingPid); 5372 Binder.restoreCallingIdentity(origId); 5373 } 5374 } 5375 5376 @Override 5377 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5378 final long origId = Binder.clearCallingIdentity(); 5379 synchronized (this) { 5380 ActivityStack stack = ActivityRecord.getStackLocked(token); 5381 if (stack != null) { 5382 ActivityRecord r = 5383 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5384 if (stopProfiling) { 5385 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5386 try { 5387 mProfileFd.close(); 5388 } catch (IOException e) { 5389 } 5390 clearProfilerLocked(); 5391 } 5392 } 5393 } 5394 } 5395 Binder.restoreCallingIdentity(origId); 5396 } 5397 5398 void enableScreenAfterBoot() { 5399 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5400 SystemClock.uptimeMillis()); 5401 mWindowManager.enableScreenAfterBoot(); 5402 5403 synchronized (this) { 5404 updateEventDispatchingLocked(); 5405 } 5406 } 5407 5408 @Override 5409 public void showBootMessage(final CharSequence msg, final boolean always) { 5410 enforceNotIsolatedCaller("showBootMessage"); 5411 mWindowManager.showBootMessage(msg, always); 5412 } 5413 5414 @Override 5415 public void dismissKeyguardOnNextActivity() { 5416 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5417 final long token = Binder.clearCallingIdentity(); 5418 try { 5419 synchronized (this) { 5420 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5421 if (mLockScreenShown) { 5422 mLockScreenShown = false; 5423 comeOutOfSleepIfNeededLocked(); 5424 } 5425 mStackSupervisor.setDismissKeyguard(true); 5426 } 5427 } finally { 5428 Binder.restoreCallingIdentity(token); 5429 } 5430 } 5431 5432 final void finishBooting() { 5433 // Register receivers to handle package update events 5434 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5435 5436 synchronized (this) { 5437 // Ensure that any processes we had put on hold are now started 5438 // up. 5439 final int NP = mProcessesOnHold.size(); 5440 if (NP > 0) { 5441 ArrayList<ProcessRecord> procs = 5442 new ArrayList<ProcessRecord>(mProcessesOnHold); 5443 for (int ip=0; ip<NP; ip++) { 5444 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5445 + procs.get(ip)); 5446 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5447 } 5448 } 5449 5450 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5451 // Start looking for apps that are abusing wake locks. 5452 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5453 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5454 // Tell anyone interested that we are done booting! 5455 SystemProperties.set("sys.boot_completed", "1"); 5456 SystemProperties.set("dev.bootcomplete", "1"); 5457 for (int i=0; i<mStartedUsers.size(); i++) { 5458 UserStartedState uss = mStartedUsers.valueAt(i); 5459 if (uss.mState == UserStartedState.STATE_BOOTING) { 5460 uss.mState = UserStartedState.STATE_RUNNING; 5461 final int userId = mStartedUsers.keyAt(i); 5462 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5463 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5464 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5465 broadcastIntentLocked(null, null, intent, null, 5466 new IIntentReceiver.Stub() { 5467 @Override 5468 public void performReceive(Intent intent, int resultCode, 5469 String data, Bundle extras, boolean ordered, 5470 boolean sticky, int sendingUser) { 5471 synchronized (ActivityManagerService.this) { 5472 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5473 true, false); 5474 } 5475 } 5476 }, 5477 0, null, null, 5478 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5479 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5480 userId); 5481 } 5482 } 5483 scheduleStartProfilesLocked(); 5484 } 5485 } 5486 } 5487 5488 final void ensureBootCompleted() { 5489 boolean booting; 5490 boolean enableScreen; 5491 synchronized (this) { 5492 booting = mBooting; 5493 mBooting = false; 5494 enableScreen = !mBooted; 5495 mBooted = true; 5496 } 5497 5498 if (booting) { 5499 finishBooting(); 5500 } 5501 5502 if (enableScreen) { 5503 enableScreenAfterBoot(); 5504 } 5505 } 5506 5507 @Override 5508 public final void activityResumed(IBinder token) { 5509 final long origId = Binder.clearCallingIdentity(); 5510 synchronized(this) { 5511 ActivityStack stack = ActivityRecord.getStackLocked(token); 5512 if (stack != null) { 5513 ActivityRecord.activityResumedLocked(token); 5514 } 5515 } 5516 Binder.restoreCallingIdentity(origId); 5517 } 5518 5519 @Override 5520 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5521 final long origId = Binder.clearCallingIdentity(); 5522 synchronized(this) { 5523 ActivityStack stack = ActivityRecord.getStackLocked(token); 5524 if (stack != null) { 5525 stack.activityPausedLocked(token, false, persistentState); 5526 } 5527 } 5528 Binder.restoreCallingIdentity(origId); 5529 } 5530 5531 @Override 5532 public final void activityStopped(IBinder token, Bundle icicle, 5533 PersistableBundle persistentState, CharSequence description) { 5534 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5535 5536 // Refuse possible leaked file descriptors 5537 if (icicle != null && icicle.hasFileDescriptors()) { 5538 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5539 } 5540 5541 final long origId = Binder.clearCallingIdentity(); 5542 5543 synchronized (this) { 5544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5545 if (r != null) { 5546 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5547 } 5548 } 5549 5550 trimApplications(); 5551 5552 Binder.restoreCallingIdentity(origId); 5553 } 5554 5555 @Override 5556 public final void activityDestroyed(IBinder token) { 5557 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5558 synchronized (this) { 5559 ActivityStack stack = ActivityRecord.getStackLocked(token); 5560 if (stack != null) { 5561 stack.activityDestroyedLocked(token); 5562 } 5563 } 5564 } 5565 5566 @Override 5567 public String getCallingPackage(IBinder token) { 5568 synchronized (this) { 5569 ActivityRecord r = getCallingRecordLocked(token); 5570 return r != null ? r.info.packageName : null; 5571 } 5572 } 5573 5574 @Override 5575 public ComponentName getCallingActivity(IBinder token) { 5576 synchronized (this) { 5577 ActivityRecord r = getCallingRecordLocked(token); 5578 return r != null ? r.intent.getComponent() : null; 5579 } 5580 } 5581 5582 private ActivityRecord getCallingRecordLocked(IBinder token) { 5583 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5584 if (r == null) { 5585 return null; 5586 } 5587 return r.resultTo; 5588 } 5589 5590 @Override 5591 public ComponentName getActivityClassForToken(IBinder token) { 5592 synchronized(this) { 5593 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5594 if (r == null) { 5595 return null; 5596 } 5597 return r.intent.getComponent(); 5598 } 5599 } 5600 5601 @Override 5602 public String getPackageForToken(IBinder token) { 5603 synchronized(this) { 5604 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5605 if (r == null) { 5606 return null; 5607 } 5608 return r.packageName; 5609 } 5610 } 5611 5612 @Override 5613 public IIntentSender getIntentSender(int type, 5614 String packageName, IBinder token, String resultWho, 5615 int requestCode, Intent[] intents, String[] resolvedTypes, 5616 int flags, Bundle options, int userId) { 5617 enforceNotIsolatedCaller("getIntentSender"); 5618 // Refuse possible leaked file descriptors 5619 if (intents != null) { 5620 if (intents.length < 1) { 5621 throw new IllegalArgumentException("Intents array length must be >= 1"); 5622 } 5623 for (int i=0; i<intents.length; i++) { 5624 Intent intent = intents[i]; 5625 if (intent != null) { 5626 if (intent.hasFileDescriptors()) { 5627 throw new IllegalArgumentException("File descriptors passed in Intent"); 5628 } 5629 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5630 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5631 throw new IllegalArgumentException( 5632 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5633 } 5634 intents[i] = new Intent(intent); 5635 } 5636 } 5637 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5638 throw new IllegalArgumentException( 5639 "Intent array length does not match resolvedTypes length"); 5640 } 5641 } 5642 if (options != null) { 5643 if (options.hasFileDescriptors()) { 5644 throw new IllegalArgumentException("File descriptors passed in options"); 5645 } 5646 } 5647 5648 synchronized(this) { 5649 int callingUid = Binder.getCallingUid(); 5650 int origUserId = userId; 5651 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5652 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5653 "getIntentSender", null); 5654 if (origUserId == UserHandle.USER_CURRENT) { 5655 // We don't want to evaluate this until the pending intent is 5656 // actually executed. However, we do want to always do the 5657 // security checking for it above. 5658 userId = UserHandle.USER_CURRENT; 5659 } 5660 try { 5661 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5662 int uid = AppGlobals.getPackageManager() 5663 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5664 if (!UserHandle.isSameApp(callingUid, uid)) { 5665 String msg = "Permission Denial: getIntentSender() from pid=" 5666 + Binder.getCallingPid() 5667 + ", uid=" + Binder.getCallingUid() 5668 + ", (need uid=" + uid + ")" 5669 + " is not allowed to send as package " + packageName; 5670 Slog.w(TAG, msg); 5671 throw new SecurityException(msg); 5672 } 5673 } 5674 5675 return getIntentSenderLocked(type, packageName, callingUid, userId, 5676 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5677 5678 } catch (RemoteException e) { 5679 throw new SecurityException(e); 5680 } 5681 } 5682 } 5683 5684 IIntentSender getIntentSenderLocked(int type, String packageName, 5685 int callingUid, int userId, IBinder token, String resultWho, 5686 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5687 Bundle options) { 5688 if (DEBUG_MU) 5689 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5690 ActivityRecord activity = null; 5691 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5692 activity = ActivityRecord.isInStackLocked(token); 5693 if (activity == null) { 5694 return null; 5695 } 5696 if (activity.finishing) { 5697 return null; 5698 } 5699 } 5700 5701 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5702 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5703 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5704 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5705 |PendingIntent.FLAG_UPDATE_CURRENT); 5706 5707 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5708 type, packageName, activity, resultWho, 5709 requestCode, intents, resolvedTypes, flags, options, userId); 5710 WeakReference<PendingIntentRecord> ref; 5711 ref = mIntentSenderRecords.get(key); 5712 PendingIntentRecord rec = ref != null ? ref.get() : null; 5713 if (rec != null) { 5714 if (!cancelCurrent) { 5715 if (updateCurrent) { 5716 if (rec.key.requestIntent != null) { 5717 rec.key.requestIntent.replaceExtras(intents != null ? 5718 intents[intents.length - 1] : null); 5719 } 5720 if (intents != null) { 5721 intents[intents.length-1] = rec.key.requestIntent; 5722 rec.key.allIntents = intents; 5723 rec.key.allResolvedTypes = resolvedTypes; 5724 } else { 5725 rec.key.allIntents = null; 5726 rec.key.allResolvedTypes = null; 5727 } 5728 } 5729 return rec; 5730 } 5731 rec.canceled = true; 5732 mIntentSenderRecords.remove(key); 5733 } 5734 if (noCreate) { 5735 return rec; 5736 } 5737 rec = new PendingIntentRecord(this, key, callingUid); 5738 mIntentSenderRecords.put(key, rec.ref); 5739 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5740 if (activity.pendingResults == null) { 5741 activity.pendingResults 5742 = new HashSet<WeakReference<PendingIntentRecord>>(); 5743 } 5744 activity.pendingResults.add(rec.ref); 5745 } 5746 return rec; 5747 } 5748 5749 @Override 5750 public void cancelIntentSender(IIntentSender sender) { 5751 if (!(sender instanceof PendingIntentRecord)) { 5752 return; 5753 } 5754 synchronized(this) { 5755 PendingIntentRecord rec = (PendingIntentRecord)sender; 5756 try { 5757 int uid = AppGlobals.getPackageManager() 5758 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5759 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5760 String msg = "Permission Denial: cancelIntentSender() from pid=" 5761 + Binder.getCallingPid() 5762 + ", uid=" + Binder.getCallingUid() 5763 + " is not allowed to cancel packges " 5764 + rec.key.packageName; 5765 Slog.w(TAG, msg); 5766 throw new SecurityException(msg); 5767 } 5768 } catch (RemoteException e) { 5769 throw new SecurityException(e); 5770 } 5771 cancelIntentSenderLocked(rec, true); 5772 } 5773 } 5774 5775 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5776 rec.canceled = true; 5777 mIntentSenderRecords.remove(rec.key); 5778 if (cleanActivity && rec.key.activity != null) { 5779 rec.key.activity.pendingResults.remove(rec.ref); 5780 } 5781 } 5782 5783 @Override 5784 public String getPackageForIntentSender(IIntentSender pendingResult) { 5785 if (!(pendingResult instanceof PendingIntentRecord)) { 5786 return null; 5787 } 5788 try { 5789 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5790 return res.key.packageName; 5791 } catch (ClassCastException e) { 5792 } 5793 return null; 5794 } 5795 5796 @Override 5797 public int getUidForIntentSender(IIntentSender sender) { 5798 if (sender instanceof PendingIntentRecord) { 5799 try { 5800 PendingIntentRecord res = (PendingIntentRecord)sender; 5801 return res.uid; 5802 } catch (ClassCastException e) { 5803 } 5804 } 5805 return -1; 5806 } 5807 5808 @Override 5809 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5810 if (!(pendingResult instanceof PendingIntentRecord)) { 5811 return false; 5812 } 5813 try { 5814 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5815 if (res.key.allIntents == null) { 5816 return false; 5817 } 5818 for (int i=0; i<res.key.allIntents.length; i++) { 5819 Intent intent = res.key.allIntents[i]; 5820 if (intent.getPackage() != null && intent.getComponent() != null) { 5821 return false; 5822 } 5823 } 5824 return true; 5825 } catch (ClassCastException e) { 5826 } 5827 return false; 5828 } 5829 5830 @Override 5831 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5832 if (!(pendingResult instanceof PendingIntentRecord)) { 5833 return false; 5834 } 5835 try { 5836 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5837 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5838 return true; 5839 } 5840 return false; 5841 } catch (ClassCastException e) { 5842 } 5843 return false; 5844 } 5845 5846 @Override 5847 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5848 if (!(pendingResult instanceof PendingIntentRecord)) { 5849 return null; 5850 } 5851 try { 5852 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5853 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5854 } catch (ClassCastException e) { 5855 } 5856 return null; 5857 } 5858 5859 @Override 5860 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5861 if (!(pendingResult instanceof PendingIntentRecord)) { 5862 return null; 5863 } 5864 try { 5865 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5866 Intent intent = res.key.requestIntent; 5867 if (intent != null) { 5868 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5869 || res.lastTagPrefix.equals(prefix))) { 5870 return res.lastTag; 5871 } 5872 res.lastTagPrefix = prefix; 5873 StringBuilder sb = new StringBuilder(128); 5874 if (prefix != null) { 5875 sb.append(prefix); 5876 } 5877 if (intent.getAction() != null) { 5878 sb.append(intent.getAction()); 5879 } else if (intent.getComponent() != null) { 5880 intent.getComponent().appendShortString(sb); 5881 } else { 5882 sb.append("?"); 5883 } 5884 return res.lastTag = sb.toString(); 5885 } 5886 } catch (ClassCastException e) { 5887 } 5888 return null; 5889 } 5890 5891 @Override 5892 public void setProcessLimit(int max) { 5893 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5894 "setProcessLimit()"); 5895 synchronized (this) { 5896 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5897 mProcessLimitOverride = max; 5898 } 5899 trimApplications(); 5900 } 5901 5902 @Override 5903 public int getProcessLimit() { 5904 synchronized (this) { 5905 return mProcessLimitOverride; 5906 } 5907 } 5908 5909 void foregroundTokenDied(ForegroundToken token) { 5910 synchronized (ActivityManagerService.this) { 5911 synchronized (mPidsSelfLocked) { 5912 ForegroundToken cur 5913 = mForegroundProcesses.get(token.pid); 5914 if (cur != token) { 5915 return; 5916 } 5917 mForegroundProcesses.remove(token.pid); 5918 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5919 if (pr == null) { 5920 return; 5921 } 5922 pr.forcingToForeground = null; 5923 updateProcessForegroundLocked(pr, false, false); 5924 } 5925 updateOomAdjLocked(); 5926 } 5927 } 5928 5929 @Override 5930 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5931 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5932 "setProcessForeground()"); 5933 synchronized(this) { 5934 boolean changed = false; 5935 5936 synchronized (mPidsSelfLocked) { 5937 ProcessRecord pr = mPidsSelfLocked.get(pid); 5938 if (pr == null && isForeground) { 5939 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5940 return; 5941 } 5942 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5943 if (oldToken != null) { 5944 oldToken.token.unlinkToDeath(oldToken, 0); 5945 mForegroundProcesses.remove(pid); 5946 if (pr != null) { 5947 pr.forcingToForeground = null; 5948 } 5949 changed = true; 5950 } 5951 if (isForeground && token != null) { 5952 ForegroundToken newToken = new ForegroundToken() { 5953 @Override 5954 public void binderDied() { 5955 foregroundTokenDied(this); 5956 } 5957 }; 5958 newToken.pid = pid; 5959 newToken.token = token; 5960 try { 5961 token.linkToDeath(newToken, 0); 5962 mForegroundProcesses.put(pid, newToken); 5963 pr.forcingToForeground = token; 5964 changed = true; 5965 } catch (RemoteException e) { 5966 // If the process died while doing this, we will later 5967 // do the cleanup with the process death link. 5968 } 5969 } 5970 } 5971 5972 if (changed) { 5973 updateOomAdjLocked(); 5974 } 5975 } 5976 } 5977 5978 // ========================================================= 5979 // PERMISSIONS 5980 // ========================================================= 5981 5982 static class PermissionController extends IPermissionController.Stub { 5983 ActivityManagerService mActivityManagerService; 5984 PermissionController(ActivityManagerService activityManagerService) { 5985 mActivityManagerService = activityManagerService; 5986 } 5987 5988 @Override 5989 public boolean checkPermission(String permission, int pid, int uid) { 5990 return mActivityManagerService.checkPermission(permission, pid, 5991 uid) == PackageManager.PERMISSION_GRANTED; 5992 } 5993 } 5994 5995 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5996 @Override 5997 public int checkComponentPermission(String permission, int pid, int uid, 5998 int owningUid, boolean exported) { 5999 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6000 owningUid, exported); 6001 } 6002 6003 @Override 6004 public Object getAMSLock() { 6005 return ActivityManagerService.this; 6006 } 6007 } 6008 6009 /** 6010 * This can be called with or without the global lock held. 6011 */ 6012 int checkComponentPermission(String permission, int pid, int uid, 6013 int owningUid, boolean exported) { 6014 // We might be performing an operation on behalf of an indirect binder 6015 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6016 // client identity accordingly before proceeding. 6017 Identity tlsIdentity = sCallerIdentity.get(); 6018 if (tlsIdentity != null) { 6019 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6020 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6021 uid = tlsIdentity.uid; 6022 pid = tlsIdentity.pid; 6023 } 6024 6025 if (pid == MY_PID) { 6026 return PackageManager.PERMISSION_GRANTED; 6027 } 6028 6029 return ActivityManager.checkComponentPermission(permission, uid, 6030 owningUid, exported); 6031 } 6032 6033 /** 6034 * As the only public entry point for permissions checking, this method 6035 * can enforce the semantic that requesting a check on a null global 6036 * permission is automatically denied. (Internally a null permission 6037 * string is used when calling {@link #checkComponentPermission} in cases 6038 * when only uid-based security is needed.) 6039 * 6040 * This can be called with or without the global lock held. 6041 */ 6042 @Override 6043 public int checkPermission(String permission, int pid, int uid) { 6044 if (permission == null) { 6045 return PackageManager.PERMISSION_DENIED; 6046 } 6047 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6048 } 6049 6050 /** 6051 * Binder IPC calls go through the public entry point. 6052 * This can be called with or without the global lock held. 6053 */ 6054 int checkCallingPermission(String permission) { 6055 return checkPermission(permission, 6056 Binder.getCallingPid(), 6057 UserHandle.getAppId(Binder.getCallingUid())); 6058 } 6059 6060 /** 6061 * This can be called with or without the global lock held. 6062 */ 6063 void enforceCallingPermission(String permission, String func) { 6064 if (checkCallingPermission(permission) 6065 == PackageManager.PERMISSION_GRANTED) { 6066 return; 6067 } 6068 6069 String msg = "Permission Denial: " + func + " from pid=" 6070 + Binder.getCallingPid() 6071 + ", uid=" + Binder.getCallingUid() 6072 + " requires " + permission; 6073 Slog.w(TAG, msg); 6074 throw new SecurityException(msg); 6075 } 6076 6077 /** 6078 * Determine if UID is holding permissions required to access {@link Uri} in 6079 * the given {@link ProviderInfo}. Final permission checking is always done 6080 * in {@link ContentProvider}. 6081 */ 6082 private final boolean checkHoldingPermissionsLocked( 6083 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6085 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6086 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6087 return false; 6088 } 6089 6090 if (pi.applicationInfo.uid == uid) { 6091 return true; 6092 } else if (!pi.exported) { 6093 return false; 6094 } 6095 6096 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6097 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6098 try { 6099 // check if target holds top-level <provider> permissions 6100 if (!readMet && pi.readPermission != null 6101 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6102 readMet = true; 6103 } 6104 if (!writeMet && pi.writePermission != null 6105 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6106 writeMet = true; 6107 } 6108 6109 // track if unprotected read/write is allowed; any denied 6110 // <path-permission> below removes this ability 6111 boolean allowDefaultRead = pi.readPermission == null; 6112 boolean allowDefaultWrite = pi.writePermission == null; 6113 6114 // check if target holds any <path-permission> that match uri 6115 final PathPermission[] pps = pi.pathPermissions; 6116 if (pps != null) { 6117 final String path = grantUri.uri.getPath(); 6118 int i = pps.length; 6119 while (i > 0 && (!readMet || !writeMet)) { 6120 i--; 6121 PathPermission pp = pps[i]; 6122 if (pp.match(path)) { 6123 if (!readMet) { 6124 final String pprperm = pp.getReadPermission(); 6125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6126 + pprperm + " for " + pp.getPath() 6127 + ": match=" + pp.match(path) 6128 + " check=" + pm.checkUidPermission(pprperm, uid)); 6129 if (pprperm != null) { 6130 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6131 readMet = true; 6132 } else { 6133 allowDefaultRead = false; 6134 } 6135 } 6136 } 6137 if (!writeMet) { 6138 final String ppwperm = pp.getWritePermission(); 6139 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6140 + ppwperm + " for " + pp.getPath() 6141 + ": match=" + pp.match(path) 6142 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6143 if (ppwperm != null) { 6144 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6145 writeMet = true; 6146 } else { 6147 allowDefaultWrite = false; 6148 } 6149 } 6150 } 6151 } 6152 } 6153 } 6154 6155 // grant unprotected <provider> read/write, if not blocked by 6156 // <path-permission> above 6157 if (allowDefaultRead) readMet = true; 6158 if (allowDefaultWrite) writeMet = true; 6159 6160 } catch (RemoteException e) { 6161 return false; 6162 } 6163 6164 return readMet && writeMet; 6165 } 6166 6167 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6168 ProviderInfo pi = null; 6169 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6170 if (cpr != null) { 6171 pi = cpr.info; 6172 } else { 6173 try { 6174 pi = AppGlobals.getPackageManager().resolveContentProvider( 6175 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6176 } catch (RemoteException ex) { 6177 } 6178 } 6179 return pi; 6180 } 6181 6182 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6183 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6184 if (targetUris != null) { 6185 return targetUris.get(grantUri); 6186 } 6187 return null; 6188 } 6189 6190 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6191 String targetPkg, int targetUid, GrantUri grantUri) { 6192 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6193 if (targetUris == null) { 6194 targetUris = Maps.newArrayMap(); 6195 mGrantedUriPermissions.put(targetUid, targetUris); 6196 } 6197 6198 UriPermission perm = targetUris.get(grantUri); 6199 if (perm == null) { 6200 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6201 targetUris.put(grantUri, perm); 6202 } 6203 6204 return perm; 6205 } 6206 6207 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6208 final int modeFlags) { 6209 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6210 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6211 : UriPermission.STRENGTH_OWNED; 6212 6213 // Root gets to do everything. 6214 if (uid == 0) { 6215 return true; 6216 } 6217 6218 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6219 if (perms == null) return false; 6220 6221 // First look for exact match 6222 final UriPermission exactPerm = perms.get(grantUri); 6223 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6224 return true; 6225 } 6226 6227 // No exact match, look for prefixes 6228 final int N = perms.size(); 6229 for (int i = 0; i < N; i++) { 6230 final UriPermission perm = perms.valueAt(i); 6231 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6232 && perm.getStrength(modeFlags) >= minStrength) { 6233 return true; 6234 } 6235 } 6236 6237 return false; 6238 } 6239 6240 @Override 6241 public int checkUriPermission(Uri uri, int pid, int uid, 6242 final int modeFlags, int userId) { 6243 enforceNotIsolatedCaller("checkUriPermission"); 6244 6245 // Another redirected-binder-call permissions check as in 6246 // {@link checkComponentPermission}. 6247 Identity tlsIdentity = sCallerIdentity.get(); 6248 if (tlsIdentity != null) { 6249 uid = tlsIdentity.uid; 6250 pid = tlsIdentity.pid; 6251 } 6252 6253 // Our own process gets to do everything. 6254 if (pid == MY_PID) { 6255 return PackageManager.PERMISSION_GRANTED; 6256 } 6257 synchronized (this) { 6258 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6259 ? PackageManager.PERMISSION_GRANTED 6260 : PackageManager.PERMISSION_DENIED; 6261 } 6262 } 6263 6264 /** 6265 * Check if the targetPkg can be granted permission to access uri by 6266 * the callingUid using the given modeFlags. Throws a security exception 6267 * if callingUid is not allowed to do this. Returns the uid of the target 6268 * if the URI permission grant should be performed; returns -1 if it is not 6269 * needed (for example targetPkg already has permission to access the URI). 6270 * If you already know the uid of the target, you can supply it in 6271 * lastTargetUid else set that to -1. 6272 */ 6273 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6274 final int modeFlags, int lastTargetUid) { 6275 if (!Intent.isAccessUriMode(modeFlags)) { 6276 return -1; 6277 } 6278 6279 if (targetPkg != null) { 6280 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6281 "Checking grant " + targetPkg + " permission to " + grantUri); 6282 } 6283 6284 final IPackageManager pm = AppGlobals.getPackageManager(); 6285 6286 // If this is not a content: uri, we can't do anything with it. 6287 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6288 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6289 "Can't grant URI permission for non-content URI: " + grantUri); 6290 return -1; 6291 } 6292 6293 final String authority = grantUri.uri.getAuthority(); 6294 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6295 if (pi == null) { 6296 Slog.w(TAG, "No content provider found for permission check: " + 6297 grantUri.uri.toSafeString()); 6298 return -1; 6299 } 6300 6301 int targetUid = lastTargetUid; 6302 if (targetUid < 0 && targetPkg != null) { 6303 try { 6304 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6305 if (targetUid < 0) { 6306 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6307 "Can't grant URI permission no uid for: " + targetPkg); 6308 return -1; 6309 } 6310 } catch (RemoteException ex) { 6311 return -1; 6312 } 6313 } 6314 6315 if (targetUid >= 0) { 6316 // First... does the target actually need this permission? 6317 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6318 // No need to grant the target this permission. 6319 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6320 "Target " + targetPkg + " already has full permission to " + grantUri); 6321 return -1; 6322 } 6323 } else { 6324 // First... there is no target package, so can anyone access it? 6325 boolean allowed = pi.exported; 6326 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6327 if (pi.readPermission != null) { 6328 allowed = false; 6329 } 6330 } 6331 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6332 if (pi.writePermission != null) { 6333 allowed = false; 6334 } 6335 } 6336 if (allowed) { 6337 return -1; 6338 } 6339 } 6340 6341 // Second... is the provider allowing granting of URI permissions? 6342 if (!pi.grantUriPermissions) { 6343 throw new SecurityException("Provider " + pi.packageName 6344 + "/" + pi.name 6345 + " does not allow granting of Uri permissions (uri " 6346 + grantUri + ")"); 6347 } 6348 if (pi.uriPermissionPatterns != null) { 6349 final int N = pi.uriPermissionPatterns.length; 6350 boolean allowed = false; 6351 for (int i=0; i<N; i++) { 6352 if (pi.uriPermissionPatterns[i] != null 6353 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6354 allowed = true; 6355 break; 6356 } 6357 } 6358 if (!allowed) { 6359 throw new SecurityException("Provider " + pi.packageName 6360 + "/" + pi.name 6361 + " does not allow granting of permission to path of Uri " 6362 + grantUri); 6363 } 6364 } 6365 6366 // Third... does the caller itself have permission to access 6367 // this uri? 6368 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6369 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6370 // Require they hold a strong enough Uri permission 6371 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6372 throw new SecurityException("Uid " + callingUid 6373 + " does not have permission to uri " + grantUri); 6374 } 6375 } 6376 } 6377 return targetUid; 6378 } 6379 6380 @Override 6381 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6382 final int modeFlags, int userId) { 6383 enforceNotIsolatedCaller("checkGrantUriPermission"); 6384 synchronized(this) { 6385 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6386 new GrantUri(userId, uri, false), modeFlags, -1); 6387 } 6388 } 6389 6390 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6391 final int modeFlags, UriPermissionOwner owner) { 6392 if (!Intent.isAccessUriMode(modeFlags)) { 6393 return; 6394 } 6395 6396 // So here we are: the caller has the assumed permission 6397 // to the uri, and the target doesn't. Let's now give this to 6398 // the target. 6399 6400 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6401 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6402 6403 final String authority = grantUri.uri.getAuthority(); 6404 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6405 if (pi == null) { 6406 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6407 return; 6408 } 6409 6410 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6411 grantUri.prefix = true; 6412 } 6413 final UriPermission perm = findOrCreateUriPermissionLocked( 6414 pi.packageName, targetPkg, targetUid, grantUri); 6415 perm.grantModes(modeFlags, owner); 6416 } 6417 6418 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6419 final int modeFlags, UriPermissionOwner owner) { 6420 if (targetPkg == null) { 6421 throw new NullPointerException("targetPkg"); 6422 } 6423 6424 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6425 -1); 6426 if (targetUid < 0) { 6427 return; 6428 } 6429 6430 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6431 owner); 6432 } 6433 6434 static class NeededUriGrants extends ArrayList<GrantUri> { 6435 final String targetPkg; 6436 final int targetUid; 6437 final int flags; 6438 6439 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6440 this.targetPkg = targetPkg; 6441 this.targetUid = targetUid; 6442 this.flags = flags; 6443 } 6444 } 6445 6446 /** 6447 * Like checkGrantUriPermissionLocked, but takes an Intent. 6448 */ 6449 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6450 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6451 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6452 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6453 + " clip=" + (intent != null ? intent.getClipData() : null) 6454 + " from " + intent + "; flags=0x" 6455 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6456 6457 if (targetPkg == null) { 6458 throw new NullPointerException("targetPkg"); 6459 } 6460 6461 if (intent == null) { 6462 return null; 6463 } 6464 Uri data = intent.getData(); 6465 ClipData clip = intent.getClipData(); 6466 if (data == null && clip == null) { 6467 return null; 6468 } 6469 final IPackageManager pm = AppGlobals.getPackageManager(); 6470 int targetUid; 6471 if (needed != null) { 6472 targetUid = needed.targetUid; 6473 } else { 6474 try { 6475 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6476 } catch (RemoteException ex) { 6477 return null; 6478 } 6479 if (targetUid < 0) { 6480 if (DEBUG_URI_PERMISSION) { 6481 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6482 + " on user " + targetUserId); 6483 } 6484 return null; 6485 } 6486 } 6487 if (data != null) { 6488 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6489 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6490 targetUid); 6491 if (targetUid > 0) { 6492 if (needed == null) { 6493 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6494 } 6495 needed.add(grantUri); 6496 } 6497 } 6498 if (clip != null) { 6499 for (int i=0; i<clip.getItemCount(); i++) { 6500 Uri uri = clip.getItemAt(i).getUri(); 6501 if (uri != null) { 6502 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6503 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6504 targetUid); 6505 if (targetUid > 0) { 6506 if (needed == null) { 6507 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6508 } 6509 needed.add(grantUri); 6510 } 6511 } else { 6512 Intent clipIntent = clip.getItemAt(i).getIntent(); 6513 if (clipIntent != null) { 6514 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6515 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6516 if (newNeeded != null) { 6517 needed = newNeeded; 6518 } 6519 } 6520 } 6521 } 6522 } 6523 6524 return needed; 6525 } 6526 6527 /** 6528 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6529 */ 6530 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6531 UriPermissionOwner owner) { 6532 if (needed != null) { 6533 for (int i=0; i<needed.size(); i++) { 6534 GrantUri grantUri = needed.get(i); 6535 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6536 grantUri, needed.flags, owner); 6537 } 6538 } 6539 } 6540 6541 void grantUriPermissionFromIntentLocked(int callingUid, 6542 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6543 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6544 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6545 if (needed == null) { 6546 return; 6547 } 6548 6549 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6550 } 6551 6552 @Override 6553 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6554 final int modeFlags, int userId) { 6555 enforceNotIsolatedCaller("grantUriPermission"); 6556 GrantUri grantUri = new GrantUri(userId, uri, false); 6557 synchronized(this) { 6558 final ProcessRecord r = getRecordForAppLocked(caller); 6559 if (r == null) { 6560 throw new SecurityException("Unable to find app for caller " 6561 + caller 6562 + " when granting permission to uri " + grantUri); 6563 } 6564 if (targetPkg == null) { 6565 throw new IllegalArgumentException("null target"); 6566 } 6567 if (grantUri == null) { 6568 throw new IllegalArgumentException("null uri"); 6569 } 6570 6571 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6572 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6573 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6574 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6575 6576 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6577 } 6578 } 6579 6580 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6581 if (perm.modeFlags == 0) { 6582 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6583 perm.targetUid); 6584 if (perms != null) { 6585 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6586 "Removing " + perm.targetUid + " permission to " + perm.uri); 6587 6588 perms.remove(perm.uri); 6589 if (perms.isEmpty()) { 6590 mGrantedUriPermissions.remove(perm.targetUid); 6591 } 6592 } 6593 } 6594 } 6595 6596 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6597 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6598 6599 final IPackageManager pm = AppGlobals.getPackageManager(); 6600 final String authority = grantUri.uri.getAuthority(); 6601 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6602 if (pi == null) { 6603 Slog.w(TAG, "No content provider found for permission revoke: " 6604 + grantUri.toSafeString()); 6605 return; 6606 } 6607 6608 // Does the caller have this permission on the URI? 6609 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6610 // Right now, if you are not the original owner of the permission, 6611 // you are not allowed to revoke it. 6612 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6613 throw new SecurityException("Uid " + callingUid 6614 + " does not have permission to uri " + grantUri); 6615 //} 6616 } 6617 6618 boolean persistChanged = false; 6619 6620 // Go through all of the permissions and remove any that match. 6621 int N = mGrantedUriPermissions.size(); 6622 for (int i = 0; i < N; i++) { 6623 final int targetUid = mGrantedUriPermissions.keyAt(i); 6624 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6625 6626 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6627 final UriPermission perm = it.next(); 6628 if (perm.uri.sourceUserId == grantUri.sourceUserId 6629 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6630 if (DEBUG_URI_PERMISSION) 6631 Slog.v(TAG, 6632 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6633 persistChanged |= perm.revokeModes( 6634 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6635 if (perm.modeFlags == 0) { 6636 it.remove(); 6637 } 6638 } 6639 } 6640 6641 if (perms.isEmpty()) { 6642 mGrantedUriPermissions.remove(targetUid); 6643 N--; 6644 i--; 6645 } 6646 } 6647 6648 if (persistChanged) { 6649 schedulePersistUriGrants(); 6650 } 6651 } 6652 6653 @Override 6654 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6655 int userId) { 6656 enforceNotIsolatedCaller("revokeUriPermission"); 6657 synchronized(this) { 6658 final ProcessRecord r = getRecordForAppLocked(caller); 6659 if (r == null) { 6660 throw new SecurityException("Unable to find app for caller " 6661 + caller 6662 + " when revoking permission to uri " + uri); 6663 } 6664 if (uri == null) { 6665 Slog.w(TAG, "revokeUriPermission: null uri"); 6666 return; 6667 } 6668 6669 if (!Intent.isAccessUriMode(modeFlags)) { 6670 return; 6671 } 6672 6673 final IPackageManager pm = AppGlobals.getPackageManager(); 6674 final String authority = uri.getAuthority(); 6675 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6676 if (pi == null) { 6677 Slog.w(TAG, "No content provider found for permission revoke: " 6678 + uri.toSafeString()); 6679 return; 6680 } 6681 6682 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6683 } 6684 } 6685 6686 /** 6687 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6688 * given package. 6689 * 6690 * @param packageName Package name to match, or {@code null} to apply to all 6691 * packages. 6692 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6693 * to all users. 6694 * @param persistable If persistable grants should be removed. 6695 */ 6696 private void removeUriPermissionsForPackageLocked( 6697 String packageName, int userHandle, boolean persistable) { 6698 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6699 throw new IllegalArgumentException("Must narrow by either package or user"); 6700 } 6701 6702 boolean persistChanged = false; 6703 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 // Only inspect grants matching user 6710 if (userHandle == UserHandle.USER_ALL 6711 || userHandle == UserHandle.getUserId(targetUid)) { 6712 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6713 final UriPermission perm = it.next(); 6714 6715 // Only inspect grants matching package 6716 if (packageName == null || perm.sourcePkg.equals(packageName) 6717 || perm.targetPkg.equals(packageName)) { 6718 persistChanged |= perm.revokeModes( 6719 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6720 6721 // Only remove when no modes remain; any persisted grants 6722 // will keep this alive. 6723 if (perm.modeFlags == 0) { 6724 it.remove(); 6725 } 6726 } 6727 } 6728 6729 if (perms.isEmpty()) { 6730 mGrantedUriPermissions.remove(targetUid); 6731 N--; 6732 i--; 6733 } 6734 } 6735 } 6736 6737 if (persistChanged) { 6738 schedulePersistUriGrants(); 6739 } 6740 } 6741 6742 @Override 6743 public IBinder newUriPermissionOwner(String name) { 6744 enforceNotIsolatedCaller("newUriPermissionOwner"); 6745 synchronized(this) { 6746 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6747 return owner.getExternalTokenLocked(); 6748 } 6749 } 6750 6751 @Override 6752 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6753 final int modeFlags, int userId) { 6754 synchronized(this) { 6755 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6756 if (owner == null) { 6757 throw new IllegalArgumentException("Unknown owner: " + token); 6758 } 6759 if (fromUid != Binder.getCallingUid()) { 6760 if (Binder.getCallingUid() != Process.myUid()) { 6761 // Only system code can grant URI permissions on behalf 6762 // of other users. 6763 throw new SecurityException("nice try"); 6764 } 6765 } 6766 if (targetPkg == null) { 6767 throw new IllegalArgumentException("null target"); 6768 } 6769 if (uri == null) { 6770 throw new IllegalArgumentException("null uri"); 6771 } 6772 6773 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6774 modeFlags, owner); 6775 } 6776 } 6777 6778 @Override 6779 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6780 synchronized(this) { 6781 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6782 if (owner == null) { 6783 throw new IllegalArgumentException("Unknown owner: " + token); 6784 } 6785 6786 if (uri == null) { 6787 owner.removeUriPermissionsLocked(mode); 6788 } else { 6789 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6790 } 6791 } 6792 } 6793 6794 private void schedulePersistUriGrants() { 6795 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6796 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6797 10 * DateUtils.SECOND_IN_MILLIS); 6798 } 6799 } 6800 6801 private void writeGrantedUriPermissions() { 6802 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6803 6804 // Snapshot permissions so we can persist without lock 6805 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6806 synchronized (this) { 6807 final int size = mGrantedUriPermissions.size(); 6808 for (int i = 0; i < size; i++) { 6809 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6810 for (UriPermission perm : perms.values()) { 6811 if (perm.persistedModeFlags != 0) { 6812 persist.add(perm.snapshot()); 6813 } 6814 } 6815 } 6816 } 6817 6818 FileOutputStream fos = null; 6819 try { 6820 fos = mGrantFile.startWrite(); 6821 6822 XmlSerializer out = new FastXmlSerializer(); 6823 out.setOutput(fos, "utf-8"); 6824 out.startDocument(null, true); 6825 out.startTag(null, TAG_URI_GRANTS); 6826 for (UriPermission.Snapshot perm : persist) { 6827 out.startTag(null, TAG_URI_GRANT); 6828 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6829 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6830 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6831 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6832 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6833 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6834 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6835 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6836 out.endTag(null, TAG_URI_GRANT); 6837 } 6838 out.endTag(null, TAG_URI_GRANTS); 6839 out.endDocument(); 6840 6841 mGrantFile.finishWrite(fos); 6842 } catch (IOException e) { 6843 if (fos != null) { 6844 mGrantFile.failWrite(fos); 6845 } 6846 } 6847 } 6848 6849 private void readGrantedUriPermissionsLocked() { 6850 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6851 6852 final long now = System.currentTimeMillis(); 6853 6854 FileInputStream fis = null; 6855 try { 6856 fis = mGrantFile.openRead(); 6857 final XmlPullParser in = Xml.newPullParser(); 6858 in.setInput(fis, null); 6859 6860 int type; 6861 while ((type = in.next()) != END_DOCUMENT) { 6862 final String tag = in.getName(); 6863 if (type == START_TAG) { 6864 if (TAG_URI_GRANT.equals(tag)) { 6865 final int sourceUserId; 6866 final int targetUserId; 6867 final int userHandle = readIntAttribute(in, 6868 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6869 if (userHandle != UserHandle.USER_NULL) { 6870 // For backwards compatibility. 6871 sourceUserId = userHandle; 6872 targetUserId = userHandle; 6873 } else { 6874 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6875 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6876 } 6877 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6878 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6879 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6880 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6881 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6882 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6883 6884 // Sanity check that provider still belongs to source package 6885 final ProviderInfo pi = getProviderInfoLocked( 6886 uri.getAuthority(), sourceUserId); 6887 if (pi != null && sourcePkg.equals(pi.packageName)) { 6888 int targetUid = -1; 6889 try { 6890 targetUid = AppGlobals.getPackageManager() 6891 .getPackageUid(targetPkg, targetUserId); 6892 } catch (RemoteException e) { 6893 } 6894 if (targetUid != -1) { 6895 final UriPermission perm = findOrCreateUriPermissionLocked( 6896 sourcePkg, targetPkg, targetUid, 6897 new GrantUri(sourceUserId, uri, prefix)); 6898 perm.initPersistedModes(modeFlags, createdTime); 6899 } 6900 } else { 6901 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6902 + " but instead found " + pi); 6903 } 6904 } 6905 } 6906 } 6907 } catch (FileNotFoundException e) { 6908 // Missing grants is okay 6909 } catch (IOException e) { 6910 Log.wtf(TAG, "Failed reading Uri grants", e); 6911 } catch (XmlPullParserException e) { 6912 Log.wtf(TAG, "Failed reading Uri grants", e); 6913 } finally { 6914 IoUtils.closeQuietly(fis); 6915 } 6916 } 6917 6918 @Override 6919 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6920 enforceNotIsolatedCaller("takePersistableUriPermission"); 6921 6922 Preconditions.checkFlagsArgument(modeFlags, 6923 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6924 6925 synchronized (this) { 6926 final int callingUid = Binder.getCallingUid(); 6927 boolean persistChanged = false; 6928 GrantUri grantUri = new GrantUri(userId, uri, false); 6929 6930 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6931 new GrantUri(userId, uri, false)); 6932 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6933 new GrantUri(userId, uri, true)); 6934 6935 final boolean exactValid = (exactPerm != null) 6936 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6937 final boolean prefixValid = (prefixPerm != null) 6938 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6939 6940 if (!(exactValid || prefixValid)) { 6941 throw new SecurityException("No persistable permission grants found for UID " 6942 + callingUid + " and Uri " + grantUri.toSafeString()); 6943 } 6944 6945 if (exactValid) { 6946 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6947 } 6948 if (prefixValid) { 6949 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6950 } 6951 6952 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6953 6954 if (persistChanged) { 6955 schedulePersistUriGrants(); 6956 } 6957 } 6958 } 6959 6960 @Override 6961 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6962 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6963 6964 Preconditions.checkFlagsArgument(modeFlags, 6965 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6966 6967 synchronized (this) { 6968 final int callingUid = Binder.getCallingUid(); 6969 boolean persistChanged = false; 6970 6971 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6972 new GrantUri(userId, uri, false)); 6973 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6974 new GrantUri(userId, uri, true)); 6975 if (exactPerm == null && prefixPerm == null) { 6976 throw new SecurityException("No permission grants found for UID " + callingUid 6977 + " and Uri " + uri.toSafeString()); 6978 } 6979 6980 if (exactPerm != null) { 6981 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6982 removeUriPermissionIfNeededLocked(exactPerm); 6983 } 6984 if (prefixPerm != null) { 6985 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6986 removeUriPermissionIfNeededLocked(prefixPerm); 6987 } 6988 6989 if (persistChanged) { 6990 schedulePersistUriGrants(); 6991 } 6992 } 6993 } 6994 6995 /** 6996 * Prune any older {@link UriPermission} for the given UID until outstanding 6997 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6998 * 6999 * @return if any mutations occured that require persisting. 7000 */ 7001 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7002 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7003 if (perms == null) return false; 7004 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7005 7006 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7007 for (UriPermission perm : perms.values()) { 7008 if (perm.persistedModeFlags != 0) { 7009 persisted.add(perm); 7010 } 7011 } 7012 7013 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7014 if (trimCount <= 0) return false; 7015 7016 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7017 for (int i = 0; i < trimCount; i++) { 7018 final UriPermission perm = persisted.get(i); 7019 7020 if (DEBUG_URI_PERMISSION) { 7021 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7022 } 7023 7024 perm.releasePersistableModes(~0); 7025 removeUriPermissionIfNeededLocked(perm); 7026 } 7027 7028 return true; 7029 } 7030 7031 @Override 7032 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7033 String packageName, boolean incoming) { 7034 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7035 Preconditions.checkNotNull(packageName, "packageName"); 7036 7037 final int callingUid = Binder.getCallingUid(); 7038 final IPackageManager pm = AppGlobals.getPackageManager(); 7039 try { 7040 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7041 if (packageUid != callingUid) { 7042 throw new SecurityException( 7043 "Package " + packageName + " does not belong to calling UID " + callingUid); 7044 } 7045 } catch (RemoteException e) { 7046 throw new SecurityException("Failed to verify package name ownership"); 7047 } 7048 7049 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7050 synchronized (this) { 7051 if (incoming) { 7052 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7053 callingUid); 7054 if (perms == null) { 7055 Slog.w(TAG, "No permission grants found for " + packageName); 7056 } else { 7057 for (UriPermission perm : perms.values()) { 7058 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7059 result.add(perm.buildPersistedPublicApiObject()); 7060 } 7061 } 7062 } 7063 } else { 7064 final int size = mGrantedUriPermissions.size(); 7065 for (int i = 0; i < size; i++) { 7066 final ArrayMap<GrantUri, UriPermission> perms = 7067 mGrantedUriPermissions.valueAt(i); 7068 for (UriPermission perm : perms.values()) { 7069 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7070 result.add(perm.buildPersistedPublicApiObject()); 7071 } 7072 } 7073 } 7074 } 7075 } 7076 return new ParceledListSlice<android.content.UriPermission>(result); 7077 } 7078 7079 @Override 7080 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7081 synchronized (this) { 7082 ProcessRecord app = 7083 who != null ? getRecordForAppLocked(who) : null; 7084 if (app == null) return; 7085 7086 Message msg = Message.obtain(); 7087 msg.what = WAIT_FOR_DEBUGGER_MSG; 7088 msg.obj = app; 7089 msg.arg1 = waiting ? 1 : 0; 7090 mHandler.sendMessage(msg); 7091 } 7092 } 7093 7094 @Override 7095 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7096 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7097 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7098 outInfo.availMem = Process.getFreeMemory(); 7099 outInfo.totalMem = Process.getTotalMemory(); 7100 outInfo.threshold = homeAppMem; 7101 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7102 outInfo.hiddenAppThreshold = cachedAppMem; 7103 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7104 ProcessList.SERVICE_ADJ); 7105 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7106 ProcessList.VISIBLE_APP_ADJ); 7107 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7108 ProcessList.FOREGROUND_APP_ADJ); 7109 } 7110 7111 // ========================================================= 7112 // TASK MANAGEMENT 7113 // ========================================================= 7114 7115 @Override 7116 public List<IAppTask> getAppTasks() { 7117 int callingUid = Binder.getCallingUid(); 7118 long ident = Binder.clearCallingIdentity(); 7119 synchronized(this) { 7120 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7121 try { 7122 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7123 7124 final int N = mRecentTasks.size(); 7125 for (int i = 0; i < N; i++) { 7126 TaskRecord tr = mRecentTasks.get(i); 7127 // Skip tasks that are not created by the caller 7128 if (tr.creatorUid == callingUid) { 7129 ActivityManager.RecentTaskInfo taskInfo = 7130 createRecentTaskInfoFromTaskRecord(tr); 7131 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7132 list.add(taskImpl); 7133 } 7134 } 7135 } finally { 7136 Binder.restoreCallingIdentity(ident); 7137 } 7138 return list; 7139 } 7140 } 7141 7142 @Override 7143 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7144 final int callingUid = Binder.getCallingUid(); 7145 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7146 7147 synchronized(this) { 7148 if (localLOGV) Slog.v( 7149 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7150 7151 final boolean allowed = checkCallingPermission( 7152 android.Manifest.permission.GET_TASKS) 7153 == PackageManager.PERMISSION_GRANTED; 7154 if (!allowed) { 7155 Slog.w(TAG, "getTasks: caller " + callingUid 7156 + " does not hold GET_TASKS; limiting output"); 7157 } 7158 7159 // TODO: Improve with MRU list from all ActivityStacks. 7160 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7161 } 7162 7163 return list; 7164 } 7165 7166 TaskRecord getMostRecentTask() { 7167 return mRecentTasks.get(0); 7168 } 7169 7170 /** 7171 * Creates a new RecentTaskInfo from a TaskRecord. 7172 */ 7173 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7174 // Update the task description to reflect any changes in the task stack 7175 tr.updateTaskDescription(); 7176 7177 // Compose the recent task info 7178 ActivityManager.RecentTaskInfo rti 7179 = new ActivityManager.RecentTaskInfo(); 7180 rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId; 7181 rti.persistentId = tr.taskId; 7182 rti.baseIntent = new Intent(tr.getBaseIntent()); 7183 rti.origActivity = tr.origActivity; 7184 rti.description = tr.lastDescription; 7185 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7186 rti.userId = tr.userId; 7187 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7188 return rti; 7189 } 7190 7191 @Override 7192 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7193 int flags, int userId) { 7194 final int callingUid = Binder.getCallingUid(); 7195 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7196 false, true, "getRecentTasks", null); 7197 7198 synchronized (this) { 7199 final boolean allowed = checkCallingPermission( 7200 android.Manifest.permission.GET_TASKS) 7201 == PackageManager.PERMISSION_GRANTED; 7202 if (!allowed) { 7203 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7204 + " does not hold GET_TASKS; limiting output"); 7205 } 7206 final boolean detailed = checkCallingPermission( 7207 android.Manifest.permission.GET_DETAILED_TASKS) 7208 == PackageManager.PERMISSION_GRANTED; 7209 7210 IPackageManager pm = AppGlobals.getPackageManager(); 7211 7212 final int N = mRecentTasks.size(); 7213 ArrayList<ActivityManager.RecentTaskInfo> res 7214 = new ArrayList<ActivityManager.RecentTaskInfo>( 7215 maxNum < N ? maxNum : N); 7216 7217 final Set<Integer> includedUsers; 7218 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7219 includedUsers = getProfileIdsLocked(userId); 7220 } else { 7221 includedUsers = new HashSet<Integer>(); 7222 } 7223 includedUsers.add(Integer.valueOf(userId)); 7224 for (int i=0; i<N && maxNum > 0; i++) { 7225 TaskRecord tr = mRecentTasks.get(i); 7226 // Only add calling user or related users recent tasks 7227 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7228 7229 // Return the entry if desired by the caller. We always return 7230 // the first entry, because callers always expect this to be the 7231 // foreground app. We may filter others if the caller has 7232 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7233 // we should exclude the entry. 7234 7235 if (i == 0 7236 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7237 || (tr.intent == null) 7238 || ((tr.intent.getFlags() 7239 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7240 if (!allowed) { 7241 // If the caller doesn't have the GET_TASKS permission, then only 7242 // allow them to see a small subset of tasks -- their own and home. 7243 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7244 continue; 7245 } 7246 } 7247 7248 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7249 if (!detailed) { 7250 rti.baseIntent.replaceExtras((Bundle)null); 7251 } 7252 7253 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7254 // Check whether this activity is currently available. 7255 try { 7256 if (rti.origActivity != null) { 7257 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7258 == null) { 7259 continue; 7260 } 7261 } else if (rti.baseIntent != null) { 7262 if (pm.queryIntentActivities(rti.baseIntent, 7263 null, 0, userId) == null) { 7264 continue; 7265 } 7266 } 7267 } catch (RemoteException e) { 7268 // Will never happen. 7269 } 7270 } 7271 7272 res.add(rti); 7273 maxNum--; 7274 } 7275 } 7276 return res; 7277 } 7278 } 7279 7280 private TaskRecord recentTaskForIdLocked(int id) { 7281 final int N = mRecentTasks.size(); 7282 for (int i=0; i<N; i++) { 7283 TaskRecord tr = mRecentTasks.get(i); 7284 if (tr.taskId == id) { 7285 return tr; 7286 } 7287 } 7288 return null; 7289 } 7290 7291 @Override 7292 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7293 synchronized (this) { 7294 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7295 "getTaskThumbnails()"); 7296 TaskRecord tr = recentTaskForIdLocked(id); 7297 if (tr != null) { 7298 return tr.getTaskThumbnailsLocked(); 7299 } 7300 } 7301 return null; 7302 } 7303 7304 @Override 7305 public Bitmap getTaskTopThumbnail(int id) { 7306 synchronized (this) { 7307 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7308 "getTaskTopThumbnail()"); 7309 TaskRecord tr = recentTaskForIdLocked(id); 7310 if (tr != null) { 7311 return tr.getTaskTopThumbnailLocked(); 7312 } 7313 } 7314 return null; 7315 } 7316 7317 @Override 7318 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7319 synchronized (this) { 7320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7321 if (r != null) { 7322 r.taskDescription = td; 7323 r.task.updateTaskDescription(); 7324 } 7325 } 7326 } 7327 7328 @Override 7329 public boolean removeSubTask(int taskId, int subTaskIndex) { 7330 synchronized (this) { 7331 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7332 "removeSubTask()"); 7333 long ident = Binder.clearCallingIdentity(); 7334 try { 7335 TaskRecord tr = recentTaskForIdLocked(taskId); 7336 if (tr != null) { 7337 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7338 } 7339 return false; 7340 } finally { 7341 Binder.restoreCallingIdentity(ident); 7342 } 7343 } 7344 } 7345 7346 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7347 if (!pr.killedByAm) { 7348 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7349 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7350 pr.processName, pr.setAdj, reason); 7351 pr.killedByAm = true; 7352 Process.killProcessQuiet(pr.pid); 7353 } 7354 } 7355 7356 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7357 tr.disposeThumbnail(); 7358 mRecentTasks.remove(tr); 7359 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7360 Intent baseIntent = new Intent( 7361 tr.intent != null ? tr.intent : tr.affinityIntent); 7362 ComponentName component = baseIntent.getComponent(); 7363 if (component == null) { 7364 Slog.w(TAG, "Now component for base intent of task: " + tr); 7365 return; 7366 } 7367 7368 // Find any running services associated with this app. 7369 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7370 7371 if (killProcesses) { 7372 // Find any running processes associated with this app. 7373 final String pkg = component.getPackageName(); 7374 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7375 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7376 for (int i=0; i<pmap.size(); i++) { 7377 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7378 for (int j=0; j<uids.size(); j++) { 7379 ProcessRecord proc = uids.valueAt(j); 7380 if (proc.userId != tr.userId) { 7381 continue; 7382 } 7383 if (!proc.pkgList.containsKey(pkg)) { 7384 continue; 7385 } 7386 procs.add(proc); 7387 } 7388 } 7389 7390 // Kill the running processes. 7391 for (int i=0; i<procs.size(); i++) { 7392 ProcessRecord pr = procs.get(i); 7393 if (pr == mHomeProcess) { 7394 // Don't kill the home process along with tasks from the same package. 7395 continue; 7396 } 7397 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7398 killUnneededProcessLocked(pr, "remove task"); 7399 } else { 7400 pr.waitingToKill = "remove task"; 7401 } 7402 } 7403 } 7404 } 7405 7406 /** 7407 * Removes the task with the specified task id. 7408 * 7409 * @param taskId Identifier of the task to be removed. 7410 * @param flags Additional operational flags. May be 0 or 7411 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7412 * @return Returns true if the given task was found and removed. 7413 */ 7414 private boolean removeTaskByIdLocked(int taskId, int flags) { 7415 TaskRecord tr = recentTaskForIdLocked(taskId); 7416 if (tr != null) { 7417 tr.removeTaskActivitiesLocked(-1, false); 7418 cleanUpRemovedTaskLocked(tr, flags); 7419 if (tr.isPersistable) { 7420 notifyTaskPersisterLocked(tr, true); 7421 } 7422 return true; 7423 } 7424 return false; 7425 } 7426 7427 @Override 7428 public boolean removeTask(int taskId, int flags) { 7429 synchronized (this) { 7430 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7431 "removeTask()"); 7432 long ident = Binder.clearCallingIdentity(); 7433 try { 7434 return removeTaskByIdLocked(taskId, flags); 7435 } finally { 7436 Binder.restoreCallingIdentity(ident); 7437 } 7438 } 7439 } 7440 7441 /** 7442 * TODO: Add mController hook 7443 */ 7444 @Override 7445 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7446 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7447 "moveTaskToFront()"); 7448 7449 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7450 synchronized(this) { 7451 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7452 Binder.getCallingUid(), "Task to front")) { 7453 ActivityOptions.abort(options); 7454 return; 7455 } 7456 final long origId = Binder.clearCallingIdentity(); 7457 try { 7458 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7459 if (task == null) { 7460 return; 7461 } 7462 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7463 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7464 return; 7465 } 7466 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7467 } finally { 7468 Binder.restoreCallingIdentity(origId); 7469 } 7470 ActivityOptions.abort(options); 7471 } 7472 } 7473 7474 @Override 7475 public void moveTaskToBack(int taskId) { 7476 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7477 "moveTaskToBack()"); 7478 7479 synchronized(this) { 7480 TaskRecord tr = recentTaskForIdLocked(taskId); 7481 if (tr != null) { 7482 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7483 ActivityStack stack = tr.stack; 7484 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7485 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7486 Binder.getCallingUid(), "Task to back")) { 7487 return; 7488 } 7489 } 7490 final long origId = Binder.clearCallingIdentity(); 7491 try { 7492 stack.moveTaskToBackLocked(taskId, null); 7493 } finally { 7494 Binder.restoreCallingIdentity(origId); 7495 } 7496 } 7497 } 7498 } 7499 7500 /** 7501 * Moves an activity, and all of the other activities within the same task, to the bottom 7502 * of the history stack. The activity's order within the task is unchanged. 7503 * 7504 * @param token A reference to the activity we wish to move 7505 * @param nonRoot If false then this only works if the activity is the root 7506 * of a task; if true it will work for any activity in a task. 7507 * @return Returns true if the move completed, false if not. 7508 */ 7509 @Override 7510 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7511 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7512 synchronized(this) { 7513 final long origId = Binder.clearCallingIdentity(); 7514 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7515 if (taskId >= 0) { 7516 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7517 } 7518 Binder.restoreCallingIdentity(origId); 7519 } 7520 return false; 7521 } 7522 7523 @Override 7524 public void moveTaskBackwards(int task) { 7525 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7526 "moveTaskBackwards()"); 7527 7528 synchronized(this) { 7529 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7530 Binder.getCallingUid(), "Task backwards")) { 7531 return; 7532 } 7533 final long origId = Binder.clearCallingIdentity(); 7534 moveTaskBackwardsLocked(task); 7535 Binder.restoreCallingIdentity(origId); 7536 } 7537 } 7538 7539 private final void moveTaskBackwardsLocked(int task) { 7540 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7541 } 7542 7543 @Override 7544 public IBinder getHomeActivityToken() throws RemoteException { 7545 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7546 "getHomeActivityToken()"); 7547 synchronized (this) { 7548 return mStackSupervisor.getHomeActivityToken(); 7549 } 7550 } 7551 7552 @Override 7553 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7554 IActivityContainerCallback callback) throws RemoteException { 7555 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7556 "createActivityContainer()"); 7557 synchronized (this) { 7558 if (parentActivityToken == null) { 7559 throw new IllegalArgumentException("parent token must not be null"); 7560 } 7561 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7562 if (r == null) { 7563 return null; 7564 } 7565 if (callback == null) { 7566 throw new IllegalArgumentException("callback must not be null"); 7567 } 7568 return mStackSupervisor.createActivityContainer(r, callback); 7569 } 7570 } 7571 7572 @Override 7573 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7574 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7575 "deleteActivityContainer()"); 7576 synchronized (this) { 7577 mStackSupervisor.deleteActivityContainer(container); 7578 } 7579 } 7580 7581 @Override 7582 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7583 throws RemoteException { 7584 synchronized (this) { 7585 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7586 if (stack != null) { 7587 return stack.mActivityContainer; 7588 } 7589 return null; 7590 } 7591 } 7592 7593 @Override 7594 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7595 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7596 "moveTaskToStack()"); 7597 if (stackId == HOME_STACK_ID) { 7598 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7599 new RuntimeException("here").fillInStackTrace()); 7600 } 7601 synchronized (this) { 7602 long ident = Binder.clearCallingIdentity(); 7603 try { 7604 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7605 + stackId + " toTop=" + toTop); 7606 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7607 } finally { 7608 Binder.restoreCallingIdentity(ident); 7609 } 7610 } 7611 } 7612 7613 @Override 7614 public void resizeStack(int stackBoxId, Rect bounds) { 7615 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7616 "resizeStackBox()"); 7617 long ident = Binder.clearCallingIdentity(); 7618 try { 7619 mWindowManager.resizeStack(stackBoxId, bounds); 7620 } finally { 7621 Binder.restoreCallingIdentity(ident); 7622 } 7623 } 7624 7625 @Override 7626 public List<StackInfo> getAllStackInfos() { 7627 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7628 "getAllStackInfos()"); 7629 long ident = Binder.clearCallingIdentity(); 7630 try { 7631 synchronized (this) { 7632 return mStackSupervisor.getAllStackInfosLocked(); 7633 } 7634 } finally { 7635 Binder.restoreCallingIdentity(ident); 7636 } 7637 } 7638 7639 @Override 7640 public StackInfo getStackInfo(int stackId) { 7641 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7642 "getStackInfo()"); 7643 long ident = Binder.clearCallingIdentity(); 7644 try { 7645 synchronized (this) { 7646 return mStackSupervisor.getStackInfoLocked(stackId); 7647 } 7648 } finally { 7649 Binder.restoreCallingIdentity(ident); 7650 } 7651 } 7652 7653 @Override 7654 public boolean isInHomeStack(int taskId) { 7655 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7656 "getStackInfo()"); 7657 long ident = Binder.clearCallingIdentity(); 7658 try { 7659 synchronized (this) { 7660 TaskRecord tr = recentTaskForIdLocked(taskId); 7661 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7662 } 7663 } finally { 7664 Binder.restoreCallingIdentity(ident); 7665 } 7666 } 7667 7668 @Override 7669 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7670 synchronized(this) { 7671 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7672 } 7673 } 7674 7675 private boolean isLockTaskAuthorized(ComponentName name) { 7676 final DevicePolicyManager dpm = (DevicePolicyManager) 7677 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7678 return dpm != null && dpm.isLockTaskPermitted(name); 7679 } 7680 7681 private void startLockTaskMode(TaskRecord task) { 7682 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7683 return; 7684 } 7685 long ident = Binder.clearCallingIdentity(); 7686 try { 7687 synchronized (this) { 7688 // Since we lost lock on task, make sure it is still there. 7689 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7690 if (task != null) { 7691 mStackSupervisor.setLockTaskModeLocked(task); 7692 } 7693 } 7694 } finally { 7695 Binder.restoreCallingIdentity(ident); 7696 } 7697 } 7698 7699 @Override 7700 public void startLockTaskMode(int taskId) { 7701 long ident = Binder.clearCallingIdentity(); 7702 try { 7703 final TaskRecord task; 7704 synchronized (this) { 7705 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7706 } 7707 if (task != null) { 7708 startLockTaskMode(task); 7709 } 7710 } finally { 7711 Binder.restoreCallingIdentity(ident); 7712 } 7713 } 7714 7715 @Override 7716 public void startLockTaskMode(IBinder token) { 7717 long ident = Binder.clearCallingIdentity(); 7718 try { 7719 final TaskRecord task; 7720 synchronized (this) { 7721 final ActivityRecord r = ActivityRecord.forToken(token); 7722 if (r == null) { 7723 return; 7724 } 7725 task = r.task; 7726 } 7727 if (task != null) { 7728 startLockTaskMode(task); 7729 } 7730 } finally { 7731 Binder.restoreCallingIdentity(ident); 7732 } 7733 } 7734 7735 @Override 7736 public void stopLockTaskMode() { 7737 // Check if the calling task is eligible to use lock task 7738 final int uid = Binder.getCallingUid(); 7739 try { 7740 final String name = AppGlobals.getPackageManager().getNameForUid(uid); 7741 if (!isLockTaskAuthorized(new ComponentName(name, name))) { 7742 return; 7743 } 7744 } catch (RemoteException e) { 7745 Log.d(TAG, "stopLockTaskMode " + e); 7746 return; 7747 } 7748 // Stop lock task 7749 synchronized (this) { 7750 mStackSupervisor.setLockTaskModeLocked(null); 7751 } 7752 } 7753 7754 @Override 7755 public boolean isInLockTaskMode() { 7756 synchronized (this) { 7757 return mStackSupervisor.isInLockTaskMode(); 7758 } 7759 } 7760 7761 // ========================================================= 7762 // CONTENT PROVIDERS 7763 // ========================================================= 7764 7765 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7766 List<ProviderInfo> providers = null; 7767 try { 7768 providers = AppGlobals.getPackageManager(). 7769 queryContentProviders(app.processName, app.uid, 7770 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7771 } catch (RemoteException ex) { 7772 } 7773 if (DEBUG_MU) 7774 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7775 int userId = app.userId; 7776 if (providers != null) { 7777 int N = providers.size(); 7778 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7779 for (int i=0; i<N; i++) { 7780 ProviderInfo cpi = 7781 (ProviderInfo)providers.get(i); 7782 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7783 cpi.name, cpi.flags); 7784 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7785 // This is a singleton provider, but a user besides the 7786 // default user is asking to initialize a process it runs 7787 // in... well, no, it doesn't actually run in this process, 7788 // it runs in the process of the default user. Get rid of it. 7789 providers.remove(i); 7790 N--; 7791 i--; 7792 continue; 7793 } 7794 7795 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7796 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7797 if (cpr == null) { 7798 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7799 mProviderMap.putProviderByClass(comp, cpr); 7800 } 7801 if (DEBUG_MU) 7802 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7803 app.pubProviders.put(cpi.name, cpr); 7804 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7805 // Don't add this if it is a platform component that is marked 7806 // to run in multiple processes, because this is actually 7807 // part of the framework so doesn't make sense to track as a 7808 // separate apk in the process. 7809 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7810 mProcessStats); 7811 } 7812 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7813 } 7814 } 7815 return providers; 7816 } 7817 7818 /** 7819 * Check if {@link ProcessRecord} has a possible chance at accessing the 7820 * given {@link ProviderInfo}. Final permission checking is always done 7821 * in {@link ContentProvider}. 7822 */ 7823 private final String checkContentProviderPermissionLocked( 7824 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7825 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7826 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7827 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7828 // Looking for cross-user grants before to enforce the typical cross-users permissions 7829 if (userId != UserHandle.getUserId(callingUid)) { 7830 if (perms != null) { 7831 for (GrantUri grantUri : perms.keySet()) { 7832 if (grantUri.sourceUserId == userId) { 7833 String authority = grantUri.uri.getAuthority(); 7834 if (authority.equals(cpi.authority)) { 7835 return null; 7836 } 7837 } 7838 } 7839 } 7840 } 7841 if (checkUser) { 7842 userId = handleIncomingUser(callingPid, callingUid, userId, 7843 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7844 } 7845 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7846 cpi.applicationInfo.uid, cpi.exported) 7847 == PackageManager.PERMISSION_GRANTED) { 7848 return null; 7849 } 7850 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7851 cpi.applicationInfo.uid, cpi.exported) 7852 == PackageManager.PERMISSION_GRANTED) { 7853 return null; 7854 } 7855 7856 PathPermission[] pps = cpi.pathPermissions; 7857 if (pps != null) { 7858 int i = pps.length; 7859 while (i > 0) { 7860 i--; 7861 PathPermission pp = pps[i]; 7862 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7863 cpi.applicationInfo.uid, cpi.exported) 7864 == PackageManager.PERMISSION_GRANTED) { 7865 return null; 7866 } 7867 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7868 cpi.applicationInfo.uid, cpi.exported) 7869 == PackageManager.PERMISSION_GRANTED) { 7870 return null; 7871 } 7872 } 7873 } 7874 7875 if (perms != null) { 7876 for (GrantUri grantUri : perms.keySet()) { 7877 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7878 return null; 7879 } 7880 } 7881 } 7882 7883 String msg; 7884 if (!cpi.exported) { 7885 msg = "Permission Denial: opening provider " + cpi.name 7886 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7887 + ", uid=" + callingUid + ") that is not exported from uid " 7888 + cpi.applicationInfo.uid; 7889 } else { 7890 msg = "Permission Denial: opening provider " + cpi.name 7891 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7892 + ", uid=" + callingUid + ") requires " 7893 + cpi.readPermission + " or " + cpi.writePermission; 7894 } 7895 Slog.w(TAG, msg); 7896 return msg; 7897 } 7898 7899 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7900 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7901 if (r != null) { 7902 for (int i=0; i<r.conProviders.size(); i++) { 7903 ContentProviderConnection conn = r.conProviders.get(i); 7904 if (conn.provider == cpr) { 7905 if (DEBUG_PROVIDER) Slog.v(TAG, 7906 "Adding provider requested by " 7907 + r.processName + " from process " 7908 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7909 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7910 if (stable) { 7911 conn.stableCount++; 7912 conn.numStableIncs++; 7913 } else { 7914 conn.unstableCount++; 7915 conn.numUnstableIncs++; 7916 } 7917 return conn; 7918 } 7919 } 7920 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7921 if (stable) { 7922 conn.stableCount = 1; 7923 conn.numStableIncs = 1; 7924 } else { 7925 conn.unstableCount = 1; 7926 conn.numUnstableIncs = 1; 7927 } 7928 cpr.connections.add(conn); 7929 r.conProviders.add(conn); 7930 return conn; 7931 } 7932 cpr.addExternalProcessHandleLocked(externalProcessToken); 7933 return null; 7934 } 7935 7936 boolean decProviderCountLocked(ContentProviderConnection conn, 7937 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7938 if (conn != null) { 7939 cpr = conn.provider; 7940 if (DEBUG_PROVIDER) Slog.v(TAG, 7941 "Removing provider requested by " 7942 + conn.client.processName + " from process " 7943 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7944 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7945 if (stable) { 7946 conn.stableCount--; 7947 } else { 7948 conn.unstableCount--; 7949 } 7950 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7951 cpr.connections.remove(conn); 7952 conn.client.conProviders.remove(conn); 7953 return true; 7954 } 7955 return false; 7956 } 7957 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7958 return false; 7959 } 7960 7961 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7962 String name, IBinder token, boolean stable, int userId) { 7963 ContentProviderRecord cpr; 7964 ContentProviderConnection conn = null; 7965 ProviderInfo cpi = null; 7966 7967 synchronized(this) { 7968 ProcessRecord r = null; 7969 if (caller != null) { 7970 r = getRecordForAppLocked(caller); 7971 if (r == null) { 7972 throw new SecurityException( 7973 "Unable to find app for caller " + caller 7974 + " (pid=" + Binder.getCallingPid() 7975 + ") when getting content provider " + name); 7976 } 7977 } 7978 7979 boolean checkCrossUser = true; 7980 7981 // First check if this content provider has been published... 7982 cpr = mProviderMap.getProviderByName(name, userId); 7983 // If that didn't work, check if it exists for user 0 and then 7984 // verify that it's a singleton provider before using it. 7985 if (cpr == null && userId != UserHandle.USER_OWNER) { 7986 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 7987 if (cpr != null) { 7988 cpi = cpr.info; 7989 if (isSingleton(cpi.processName, cpi.applicationInfo, 7990 cpi.name, cpi.flags) 7991 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 7992 userId = UserHandle.USER_OWNER; 7993 checkCrossUser = false; 7994 } else { 7995 cpr = null; 7996 cpi = null; 7997 } 7998 } 7999 } 8000 8001 boolean providerRunning = cpr != null; 8002 if (providerRunning) { 8003 cpi = cpr.info; 8004 String msg; 8005 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8006 != null) { 8007 throw new SecurityException(msg); 8008 } 8009 8010 if (r != null && cpr.canRunHere(r)) { 8011 // This provider has been published or is in the process 8012 // of being published... but it is also allowed to run 8013 // in the caller's process, so don't make a connection 8014 // and just let the caller instantiate its own instance. 8015 ContentProviderHolder holder = cpr.newHolder(null); 8016 // don't give caller the provider object, it needs 8017 // to make its own. 8018 holder.provider = null; 8019 return holder; 8020 } 8021 8022 final long origId = Binder.clearCallingIdentity(); 8023 8024 // In this case the provider instance already exists, so we can 8025 // return it right away. 8026 conn = incProviderCountLocked(r, cpr, token, stable); 8027 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8028 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8029 // If this is a perceptible app accessing the provider, 8030 // make sure to count it as being accessed and thus 8031 // back up on the LRU list. This is good because 8032 // content providers are often expensive to start. 8033 updateLruProcessLocked(cpr.proc, false, null); 8034 } 8035 } 8036 8037 if (cpr.proc != null) { 8038 if (false) { 8039 if (cpr.name.flattenToShortString().equals( 8040 "com.android.providers.calendar/.CalendarProvider2")) { 8041 Slog.v(TAG, "****************** KILLING " 8042 + cpr.name.flattenToShortString()); 8043 Process.killProcess(cpr.proc.pid); 8044 } 8045 } 8046 boolean success = updateOomAdjLocked(cpr.proc); 8047 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8048 // NOTE: there is still a race here where a signal could be 8049 // pending on the process even though we managed to update its 8050 // adj level. Not sure what to do about this, but at least 8051 // the race is now smaller. 8052 if (!success) { 8053 // Uh oh... it looks like the provider's process 8054 // has been killed on us. We need to wait for a new 8055 // process to be started, and make sure its death 8056 // doesn't kill our process. 8057 Slog.i(TAG, 8058 "Existing provider " + cpr.name.flattenToShortString() 8059 + " is crashing; detaching " + r); 8060 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8061 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8062 if (!lastRef) { 8063 // This wasn't the last ref our process had on 8064 // the provider... we have now been killed, bail. 8065 return null; 8066 } 8067 providerRunning = false; 8068 conn = null; 8069 } 8070 } 8071 8072 Binder.restoreCallingIdentity(origId); 8073 } 8074 8075 boolean singleton; 8076 if (!providerRunning) { 8077 try { 8078 cpi = AppGlobals.getPackageManager(). 8079 resolveContentProvider(name, 8080 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8081 } catch (RemoteException ex) { 8082 } 8083 if (cpi == null) { 8084 return null; 8085 } 8086 // If the provider is a singleton AND 8087 // (it's a call within the same user || the provider is a 8088 // privileged app) 8089 // Then allow connecting to the singleton provider 8090 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8091 cpi.name, cpi.flags) 8092 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8093 if (singleton) { 8094 userId = UserHandle.USER_OWNER; 8095 } 8096 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8097 8098 String msg; 8099 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8100 != null) { 8101 throw new SecurityException(msg); 8102 } 8103 8104 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8105 && !cpi.processName.equals("system")) { 8106 // If this content provider does not run in the system 8107 // process, and the system is not yet ready to run other 8108 // processes, then fail fast instead of hanging. 8109 throw new IllegalArgumentException( 8110 "Attempt to launch content provider before system ready"); 8111 } 8112 8113 // Make sure that the user who owns this provider is started. If not, 8114 // we don't want to allow it to run. 8115 if (mStartedUsers.get(userId) == null) { 8116 Slog.w(TAG, "Unable to launch app " 8117 + cpi.applicationInfo.packageName + "/" 8118 + cpi.applicationInfo.uid + " for provider " 8119 + name + ": user " + userId + " is stopped"); 8120 return null; 8121 } 8122 8123 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8124 cpr = mProviderMap.getProviderByClass(comp, userId); 8125 final boolean firstClass = cpr == null; 8126 if (firstClass) { 8127 try { 8128 ApplicationInfo ai = 8129 AppGlobals.getPackageManager(). 8130 getApplicationInfo( 8131 cpi.applicationInfo.packageName, 8132 STOCK_PM_FLAGS, userId); 8133 if (ai == null) { 8134 Slog.w(TAG, "No package info for content provider " 8135 + cpi.name); 8136 return null; 8137 } 8138 ai = getAppInfoForUser(ai, userId); 8139 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8140 } catch (RemoteException ex) { 8141 // pm is in same process, this will never happen. 8142 } 8143 } 8144 8145 if (r != null && cpr.canRunHere(r)) { 8146 // If this is a multiprocess provider, then just return its 8147 // info and allow the caller to instantiate it. Only do 8148 // this if the provider is the same user as the caller's 8149 // process, or can run as root (so can be in any process). 8150 return cpr.newHolder(null); 8151 } 8152 8153 if (DEBUG_PROVIDER) { 8154 RuntimeException e = new RuntimeException("here"); 8155 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8156 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8157 } 8158 8159 // This is single process, and our app is now connecting to it. 8160 // See if we are already in the process of launching this 8161 // provider. 8162 final int N = mLaunchingProviders.size(); 8163 int i; 8164 for (i=0; i<N; i++) { 8165 if (mLaunchingProviders.get(i) == cpr) { 8166 break; 8167 } 8168 } 8169 8170 // If the provider is not already being launched, then get it 8171 // started. 8172 if (i >= N) { 8173 final long origId = Binder.clearCallingIdentity(); 8174 8175 try { 8176 // Content provider is now in use, its package can't be stopped. 8177 try { 8178 AppGlobals.getPackageManager().setPackageStoppedState( 8179 cpr.appInfo.packageName, false, userId); 8180 } catch (RemoteException e) { 8181 } catch (IllegalArgumentException e) { 8182 Slog.w(TAG, "Failed trying to unstop package " 8183 + cpr.appInfo.packageName + ": " + e); 8184 } 8185 8186 // Use existing process if already started 8187 ProcessRecord proc = getProcessRecordLocked( 8188 cpi.processName, cpr.appInfo.uid, false); 8189 if (proc != null && proc.thread != null) { 8190 if (DEBUG_PROVIDER) { 8191 Slog.d(TAG, "Installing in existing process " + proc); 8192 } 8193 proc.pubProviders.put(cpi.name, cpr); 8194 try { 8195 proc.thread.scheduleInstallProvider(cpi); 8196 } catch (RemoteException e) { 8197 } 8198 } else { 8199 proc = startProcessLocked(cpi.processName, 8200 cpr.appInfo, false, 0, "content provider", 8201 new ComponentName(cpi.applicationInfo.packageName, 8202 cpi.name), false, false, false); 8203 if (proc == null) { 8204 Slog.w(TAG, "Unable to launch app " 8205 + cpi.applicationInfo.packageName + "/" 8206 + cpi.applicationInfo.uid + " for provider " 8207 + name + ": process is bad"); 8208 return null; 8209 } 8210 } 8211 cpr.launchingApp = proc; 8212 mLaunchingProviders.add(cpr); 8213 } finally { 8214 Binder.restoreCallingIdentity(origId); 8215 } 8216 } 8217 8218 // Make sure the provider is published (the same provider class 8219 // may be published under multiple names). 8220 if (firstClass) { 8221 mProviderMap.putProviderByClass(comp, cpr); 8222 } 8223 8224 mProviderMap.putProviderByName(name, cpr); 8225 conn = incProviderCountLocked(r, cpr, token, stable); 8226 if (conn != null) { 8227 conn.waiting = true; 8228 } 8229 } 8230 } 8231 8232 // Wait for the provider to be published... 8233 synchronized (cpr) { 8234 while (cpr.provider == null) { 8235 if (cpr.launchingApp == null) { 8236 Slog.w(TAG, "Unable to launch app " 8237 + cpi.applicationInfo.packageName + "/" 8238 + cpi.applicationInfo.uid + " for provider " 8239 + name + ": launching app became null"); 8240 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8241 UserHandle.getUserId(cpi.applicationInfo.uid), 8242 cpi.applicationInfo.packageName, 8243 cpi.applicationInfo.uid, name); 8244 return null; 8245 } 8246 try { 8247 if (DEBUG_MU) { 8248 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8249 + cpr.launchingApp); 8250 } 8251 if (conn != null) { 8252 conn.waiting = true; 8253 } 8254 cpr.wait(); 8255 } catch (InterruptedException ex) { 8256 } finally { 8257 if (conn != null) { 8258 conn.waiting = false; 8259 } 8260 } 8261 } 8262 } 8263 return cpr != null ? cpr.newHolder(conn) : null; 8264 } 8265 8266 @Override 8267 public final ContentProviderHolder getContentProvider( 8268 IApplicationThread caller, String name, int userId, boolean stable) { 8269 enforceNotIsolatedCaller("getContentProvider"); 8270 if (caller == null) { 8271 String msg = "null IApplicationThread when getting content provider " 8272 + name; 8273 Slog.w(TAG, msg); 8274 throw new SecurityException(msg); 8275 } 8276 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8277 // with cross-user grant. 8278 return getContentProviderImpl(caller, name, null, stable, userId); 8279 } 8280 8281 public ContentProviderHolder getContentProviderExternal( 8282 String name, int userId, IBinder token) { 8283 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8284 "Do not have permission in call getContentProviderExternal()"); 8285 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8286 false, true, "getContentProvider", null); 8287 return getContentProviderExternalUnchecked(name, token, userId); 8288 } 8289 8290 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8291 IBinder token, int userId) { 8292 return getContentProviderImpl(null, name, token, true, userId); 8293 } 8294 8295 /** 8296 * Drop a content provider from a ProcessRecord's bookkeeping 8297 */ 8298 public void removeContentProvider(IBinder connection, boolean stable) { 8299 enforceNotIsolatedCaller("removeContentProvider"); 8300 long ident = Binder.clearCallingIdentity(); 8301 try { 8302 synchronized (this) { 8303 ContentProviderConnection conn; 8304 try { 8305 conn = (ContentProviderConnection)connection; 8306 } catch (ClassCastException e) { 8307 String msg ="removeContentProvider: " + connection 8308 + " not a ContentProviderConnection"; 8309 Slog.w(TAG, msg); 8310 throw new IllegalArgumentException(msg); 8311 } 8312 if (conn == null) { 8313 throw new NullPointerException("connection is null"); 8314 } 8315 if (decProviderCountLocked(conn, null, null, stable)) { 8316 updateOomAdjLocked(); 8317 } 8318 } 8319 } finally { 8320 Binder.restoreCallingIdentity(ident); 8321 } 8322 } 8323 8324 public void removeContentProviderExternal(String name, IBinder token) { 8325 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8326 "Do not have permission in call removeContentProviderExternal()"); 8327 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8328 } 8329 8330 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8331 synchronized (this) { 8332 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8333 if(cpr == null) { 8334 //remove from mProvidersByClass 8335 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8336 return; 8337 } 8338 8339 //update content provider record entry info 8340 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8341 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8342 if (localCpr.hasExternalProcessHandles()) { 8343 if (localCpr.removeExternalProcessHandleLocked(token)) { 8344 updateOomAdjLocked(); 8345 } else { 8346 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8347 + " with no external reference for token: " 8348 + token + "."); 8349 } 8350 } else { 8351 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8352 + " with no external references."); 8353 } 8354 } 8355 } 8356 8357 public final void publishContentProviders(IApplicationThread caller, 8358 List<ContentProviderHolder> providers) { 8359 if (providers == null) { 8360 return; 8361 } 8362 8363 enforceNotIsolatedCaller("publishContentProviders"); 8364 synchronized (this) { 8365 final ProcessRecord r = getRecordForAppLocked(caller); 8366 if (DEBUG_MU) 8367 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8368 if (r == null) { 8369 throw new SecurityException( 8370 "Unable to find app for caller " + caller 8371 + " (pid=" + Binder.getCallingPid() 8372 + ") when publishing content providers"); 8373 } 8374 8375 final long origId = Binder.clearCallingIdentity(); 8376 8377 final int N = providers.size(); 8378 for (int i=0; i<N; i++) { 8379 ContentProviderHolder src = providers.get(i); 8380 if (src == null || src.info == null || src.provider == null) { 8381 continue; 8382 } 8383 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8384 if (DEBUG_MU) 8385 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8386 if (dst != null) { 8387 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8388 mProviderMap.putProviderByClass(comp, dst); 8389 String names[] = dst.info.authority.split(";"); 8390 for (int j = 0; j < names.length; j++) { 8391 mProviderMap.putProviderByName(names[j], dst); 8392 } 8393 8394 int NL = mLaunchingProviders.size(); 8395 int j; 8396 for (j=0; j<NL; j++) { 8397 if (mLaunchingProviders.get(j) == dst) { 8398 mLaunchingProviders.remove(j); 8399 j--; 8400 NL--; 8401 } 8402 } 8403 synchronized (dst) { 8404 dst.provider = src.provider; 8405 dst.proc = r; 8406 dst.notifyAll(); 8407 } 8408 updateOomAdjLocked(r); 8409 } 8410 } 8411 8412 Binder.restoreCallingIdentity(origId); 8413 } 8414 } 8415 8416 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8417 ContentProviderConnection conn; 8418 try { 8419 conn = (ContentProviderConnection)connection; 8420 } catch (ClassCastException e) { 8421 String msg ="refContentProvider: " + connection 8422 + " not a ContentProviderConnection"; 8423 Slog.w(TAG, msg); 8424 throw new IllegalArgumentException(msg); 8425 } 8426 if (conn == null) { 8427 throw new NullPointerException("connection is null"); 8428 } 8429 8430 synchronized (this) { 8431 if (stable > 0) { 8432 conn.numStableIncs += stable; 8433 } 8434 stable = conn.stableCount + stable; 8435 if (stable < 0) { 8436 throw new IllegalStateException("stableCount < 0: " + stable); 8437 } 8438 8439 if (unstable > 0) { 8440 conn.numUnstableIncs += unstable; 8441 } 8442 unstable = conn.unstableCount + unstable; 8443 if (unstable < 0) { 8444 throw new IllegalStateException("unstableCount < 0: " + unstable); 8445 } 8446 8447 if ((stable+unstable) <= 0) { 8448 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8449 + stable + " unstable=" + unstable); 8450 } 8451 conn.stableCount = stable; 8452 conn.unstableCount = unstable; 8453 return !conn.dead; 8454 } 8455 } 8456 8457 public void unstableProviderDied(IBinder connection) { 8458 ContentProviderConnection conn; 8459 try { 8460 conn = (ContentProviderConnection)connection; 8461 } catch (ClassCastException e) { 8462 String msg ="refContentProvider: " + connection 8463 + " not a ContentProviderConnection"; 8464 Slog.w(TAG, msg); 8465 throw new IllegalArgumentException(msg); 8466 } 8467 if (conn == null) { 8468 throw new NullPointerException("connection is null"); 8469 } 8470 8471 // Safely retrieve the content provider associated with the connection. 8472 IContentProvider provider; 8473 synchronized (this) { 8474 provider = conn.provider.provider; 8475 } 8476 8477 if (provider == null) { 8478 // Um, yeah, we're way ahead of you. 8479 return; 8480 } 8481 8482 // Make sure the caller is being honest with us. 8483 if (provider.asBinder().pingBinder()) { 8484 // Er, no, still looks good to us. 8485 synchronized (this) { 8486 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8487 + " says " + conn + " died, but we don't agree"); 8488 return; 8489 } 8490 } 8491 8492 // Well look at that! It's dead! 8493 synchronized (this) { 8494 if (conn.provider.provider != provider) { 8495 // But something changed... good enough. 8496 return; 8497 } 8498 8499 ProcessRecord proc = conn.provider.proc; 8500 if (proc == null || proc.thread == null) { 8501 // Seems like the process is already cleaned up. 8502 return; 8503 } 8504 8505 // As far as we're concerned, this is just like receiving a 8506 // death notification... just a bit prematurely. 8507 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8508 + ") early provider death"); 8509 final long ident = Binder.clearCallingIdentity(); 8510 try { 8511 appDiedLocked(proc, proc.pid, proc.thread); 8512 } finally { 8513 Binder.restoreCallingIdentity(ident); 8514 } 8515 } 8516 } 8517 8518 @Override 8519 public void appNotRespondingViaProvider(IBinder connection) { 8520 enforceCallingPermission( 8521 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8522 8523 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8524 if (conn == null) { 8525 Slog.w(TAG, "ContentProviderConnection is null"); 8526 return; 8527 } 8528 8529 final ProcessRecord host = conn.provider.proc; 8530 if (host == null) { 8531 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8532 return; 8533 } 8534 8535 final long token = Binder.clearCallingIdentity(); 8536 try { 8537 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8538 } finally { 8539 Binder.restoreCallingIdentity(token); 8540 } 8541 } 8542 8543 public final void installSystemProviders() { 8544 List<ProviderInfo> providers; 8545 synchronized (this) { 8546 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8547 providers = generateApplicationProvidersLocked(app); 8548 if (providers != null) { 8549 for (int i=providers.size()-1; i>=0; i--) { 8550 ProviderInfo pi = (ProviderInfo)providers.get(i); 8551 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8552 Slog.w(TAG, "Not installing system proc provider " + pi.name 8553 + ": not system .apk"); 8554 providers.remove(i); 8555 } 8556 } 8557 } 8558 } 8559 if (providers != null) { 8560 mSystemThread.installSystemProviders(providers); 8561 } 8562 8563 mCoreSettingsObserver = new CoreSettingsObserver(this); 8564 8565 mUsageStatsService.monitorPackages(); 8566 } 8567 8568 /** 8569 * Allows app to retrieve the MIME type of a URI without having permission 8570 * to access its content provider. 8571 * 8572 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8573 * 8574 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8575 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8576 */ 8577 public String getProviderMimeType(Uri uri, int userId) { 8578 enforceNotIsolatedCaller("getProviderMimeType"); 8579 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8580 userId, false, true, "getProviderMimeType", null); 8581 final String name = uri.getAuthority(); 8582 final long ident = Binder.clearCallingIdentity(); 8583 ContentProviderHolder holder = null; 8584 8585 try { 8586 holder = getContentProviderExternalUnchecked(name, null, userId); 8587 if (holder != null) { 8588 return holder.provider.getType(uri); 8589 } 8590 } catch (RemoteException e) { 8591 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8592 return null; 8593 } finally { 8594 if (holder != null) { 8595 removeContentProviderExternalUnchecked(name, null, userId); 8596 } 8597 Binder.restoreCallingIdentity(ident); 8598 } 8599 8600 return null; 8601 } 8602 8603 // ========================================================= 8604 // GLOBAL MANAGEMENT 8605 // ========================================================= 8606 8607 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8608 boolean isolated) { 8609 String proc = customProcess != null ? customProcess : info.processName; 8610 BatteryStatsImpl.Uid.Proc ps = null; 8611 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8612 int uid = info.uid; 8613 if (isolated) { 8614 int userId = UserHandle.getUserId(uid); 8615 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8616 while (true) { 8617 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8618 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8619 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8620 } 8621 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8622 mNextIsolatedProcessUid++; 8623 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8624 // No process for this uid, use it. 8625 break; 8626 } 8627 stepsLeft--; 8628 if (stepsLeft <= 0) { 8629 return null; 8630 } 8631 } 8632 } 8633 return new ProcessRecord(stats, info, proc, uid); 8634 } 8635 8636 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8637 String abiOverride) { 8638 ProcessRecord app; 8639 if (!isolated) { 8640 app = getProcessRecordLocked(info.processName, info.uid, true); 8641 } else { 8642 app = null; 8643 } 8644 8645 if (app == null) { 8646 app = newProcessRecordLocked(info, null, isolated); 8647 mProcessNames.put(info.processName, app.uid, app); 8648 if (isolated) { 8649 mIsolatedProcesses.put(app.uid, app); 8650 } 8651 updateLruProcessLocked(app, false, null); 8652 updateOomAdjLocked(); 8653 } 8654 8655 // This package really, really can not be stopped. 8656 try { 8657 AppGlobals.getPackageManager().setPackageStoppedState( 8658 info.packageName, false, UserHandle.getUserId(app.uid)); 8659 } catch (RemoteException e) { 8660 } catch (IllegalArgumentException e) { 8661 Slog.w(TAG, "Failed trying to unstop package " 8662 + info.packageName + ": " + e); 8663 } 8664 8665 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8666 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8667 app.persistent = true; 8668 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8669 } 8670 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8671 mPersistentStartingProcesses.add(app); 8672 startProcessLocked(app, "added application", app.processName, 8673 abiOverride); 8674 } 8675 8676 return app; 8677 } 8678 8679 public void unhandledBack() { 8680 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8681 "unhandledBack()"); 8682 8683 synchronized(this) { 8684 final long origId = Binder.clearCallingIdentity(); 8685 try { 8686 getFocusedStack().unhandledBackLocked(); 8687 } finally { 8688 Binder.restoreCallingIdentity(origId); 8689 } 8690 } 8691 } 8692 8693 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8694 enforceNotIsolatedCaller("openContentUri"); 8695 final int userId = UserHandle.getCallingUserId(); 8696 String name = uri.getAuthority(); 8697 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8698 ParcelFileDescriptor pfd = null; 8699 if (cph != null) { 8700 // We record the binder invoker's uid in thread-local storage before 8701 // going to the content provider to open the file. Later, in the code 8702 // that handles all permissions checks, we look for this uid and use 8703 // that rather than the Activity Manager's own uid. The effect is that 8704 // we do the check against the caller's permissions even though it looks 8705 // to the content provider like the Activity Manager itself is making 8706 // the request. 8707 sCallerIdentity.set(new Identity( 8708 Binder.getCallingPid(), Binder.getCallingUid())); 8709 try { 8710 pfd = cph.provider.openFile(null, uri, "r", null); 8711 } catch (FileNotFoundException e) { 8712 // do nothing; pfd will be returned null 8713 } finally { 8714 // Ensure that whatever happens, we clean up the identity state 8715 sCallerIdentity.remove(); 8716 } 8717 8718 // We've got the fd now, so we're done with the provider. 8719 removeContentProviderExternalUnchecked(name, null, userId); 8720 } else { 8721 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8722 } 8723 return pfd; 8724 } 8725 8726 // Actually is sleeping or shutting down or whatever else in the future 8727 // is an inactive state. 8728 public boolean isSleepingOrShuttingDown() { 8729 return mSleeping || mShuttingDown; 8730 } 8731 8732 public boolean isSleeping() { 8733 return mSleeping; 8734 } 8735 8736 void goingToSleep() { 8737 synchronized(this) { 8738 mWentToSleep = true; 8739 updateEventDispatchingLocked(); 8740 goToSleepIfNeededLocked(); 8741 } 8742 } 8743 8744 void finishRunningVoiceLocked() { 8745 if (mRunningVoice) { 8746 mRunningVoice = false; 8747 goToSleepIfNeededLocked(); 8748 } 8749 } 8750 8751 void goToSleepIfNeededLocked() { 8752 if (mWentToSleep && !mRunningVoice) { 8753 if (!mSleeping) { 8754 mSleeping = true; 8755 mStackSupervisor.goingToSleepLocked(); 8756 8757 // Initialize the wake times of all processes. 8758 checkExcessivePowerUsageLocked(false); 8759 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8760 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8761 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8762 } 8763 } 8764 } 8765 8766 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8767 mTaskPersister.notify(task, flush); 8768 } 8769 8770 @Override 8771 public boolean shutdown(int timeout) { 8772 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8773 != PackageManager.PERMISSION_GRANTED) { 8774 throw new SecurityException("Requires permission " 8775 + android.Manifest.permission.SHUTDOWN); 8776 } 8777 8778 boolean timedout = false; 8779 8780 synchronized(this) { 8781 mShuttingDown = true; 8782 updateEventDispatchingLocked(); 8783 timedout = mStackSupervisor.shutdownLocked(timeout); 8784 } 8785 8786 mAppOpsService.shutdown(); 8787 mUsageStatsService.shutdown(); 8788 mBatteryStatsService.shutdown(); 8789 synchronized (this) { 8790 mProcessStats.shutdownLocked(); 8791 } 8792 notifyTaskPersisterLocked(null, true); 8793 8794 return timedout; 8795 } 8796 8797 public final void activitySlept(IBinder token) { 8798 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8799 8800 final long origId = Binder.clearCallingIdentity(); 8801 8802 synchronized (this) { 8803 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8804 if (r != null) { 8805 mStackSupervisor.activitySleptLocked(r); 8806 } 8807 } 8808 8809 Binder.restoreCallingIdentity(origId); 8810 } 8811 8812 void logLockScreen(String msg) { 8813 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8814 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8815 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8816 mStackSupervisor.mDismissKeyguardOnNextActivity); 8817 } 8818 8819 private void comeOutOfSleepIfNeededLocked() { 8820 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8821 if (mSleeping) { 8822 mSleeping = false; 8823 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8824 } 8825 } 8826 } 8827 8828 void wakingUp() { 8829 synchronized(this) { 8830 mWentToSleep = false; 8831 updateEventDispatchingLocked(); 8832 comeOutOfSleepIfNeededLocked(); 8833 } 8834 } 8835 8836 void startRunningVoiceLocked() { 8837 if (!mRunningVoice) { 8838 mRunningVoice = true; 8839 comeOutOfSleepIfNeededLocked(); 8840 } 8841 } 8842 8843 private void updateEventDispatchingLocked() { 8844 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8845 } 8846 8847 public void setLockScreenShown(boolean shown) { 8848 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8849 != PackageManager.PERMISSION_GRANTED) { 8850 throw new SecurityException("Requires permission " 8851 + android.Manifest.permission.DEVICE_POWER); 8852 } 8853 8854 synchronized(this) { 8855 long ident = Binder.clearCallingIdentity(); 8856 try { 8857 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8858 mLockScreenShown = shown; 8859 comeOutOfSleepIfNeededLocked(); 8860 } finally { 8861 Binder.restoreCallingIdentity(ident); 8862 } 8863 } 8864 } 8865 8866 public void stopAppSwitches() { 8867 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8868 != PackageManager.PERMISSION_GRANTED) { 8869 throw new SecurityException("Requires permission " 8870 + android.Manifest.permission.STOP_APP_SWITCHES); 8871 } 8872 8873 synchronized(this) { 8874 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8875 + APP_SWITCH_DELAY_TIME; 8876 mDidAppSwitch = false; 8877 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8878 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8879 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8880 } 8881 } 8882 8883 public void resumeAppSwitches() { 8884 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8885 != PackageManager.PERMISSION_GRANTED) { 8886 throw new SecurityException("Requires permission " 8887 + android.Manifest.permission.STOP_APP_SWITCHES); 8888 } 8889 8890 synchronized(this) { 8891 // Note that we don't execute any pending app switches... we will 8892 // let those wait until either the timeout, or the next start 8893 // activity request. 8894 mAppSwitchesAllowedTime = 0; 8895 } 8896 } 8897 8898 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8899 String name) { 8900 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8901 return true; 8902 } 8903 8904 final int perm = checkComponentPermission( 8905 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8906 callingUid, -1, true); 8907 if (perm == PackageManager.PERMISSION_GRANTED) { 8908 return true; 8909 } 8910 8911 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8912 return false; 8913 } 8914 8915 public void setDebugApp(String packageName, boolean waitForDebugger, 8916 boolean persistent) { 8917 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8918 "setDebugApp()"); 8919 8920 long ident = Binder.clearCallingIdentity(); 8921 try { 8922 // Note that this is not really thread safe if there are multiple 8923 // callers into it at the same time, but that's not a situation we 8924 // care about. 8925 if (persistent) { 8926 final ContentResolver resolver = mContext.getContentResolver(); 8927 Settings.Global.putString( 8928 resolver, Settings.Global.DEBUG_APP, 8929 packageName); 8930 Settings.Global.putInt( 8931 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8932 waitForDebugger ? 1 : 0); 8933 } 8934 8935 synchronized (this) { 8936 if (!persistent) { 8937 mOrigDebugApp = mDebugApp; 8938 mOrigWaitForDebugger = mWaitForDebugger; 8939 } 8940 mDebugApp = packageName; 8941 mWaitForDebugger = waitForDebugger; 8942 mDebugTransient = !persistent; 8943 if (packageName != null) { 8944 forceStopPackageLocked(packageName, -1, false, false, true, true, 8945 false, UserHandle.USER_ALL, "set debug app"); 8946 } 8947 } 8948 } finally { 8949 Binder.restoreCallingIdentity(ident); 8950 } 8951 } 8952 8953 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8954 synchronized (this) { 8955 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8956 if (!isDebuggable) { 8957 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8958 throw new SecurityException("Process not debuggable: " + app.packageName); 8959 } 8960 } 8961 8962 mOpenGlTraceApp = processName; 8963 } 8964 } 8965 8966 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8967 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8968 synchronized (this) { 8969 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8970 if (!isDebuggable) { 8971 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8972 throw new SecurityException("Process not debuggable: " + app.packageName); 8973 } 8974 } 8975 mProfileApp = processName; 8976 mProfileFile = profileFile; 8977 if (mProfileFd != null) { 8978 try { 8979 mProfileFd.close(); 8980 } catch (IOException e) { 8981 } 8982 mProfileFd = null; 8983 } 8984 mProfileFd = profileFd; 8985 mProfileType = 0; 8986 mAutoStopProfiler = autoStopProfiler; 8987 } 8988 } 8989 8990 @Override 8991 public void setAlwaysFinish(boolean enabled) { 8992 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8993 "setAlwaysFinish()"); 8994 8995 Settings.Global.putInt( 8996 mContext.getContentResolver(), 8997 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8998 8999 synchronized (this) { 9000 mAlwaysFinishActivities = enabled; 9001 } 9002 } 9003 9004 @Override 9005 public void setActivityController(IActivityController controller) { 9006 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9007 "setActivityController()"); 9008 synchronized (this) { 9009 mController = controller; 9010 Watchdog.getInstance().setActivityController(controller); 9011 } 9012 } 9013 9014 @Override 9015 public void setUserIsMonkey(boolean userIsMonkey) { 9016 synchronized (this) { 9017 synchronized (mPidsSelfLocked) { 9018 final int callingPid = Binder.getCallingPid(); 9019 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9020 if (precessRecord == null) { 9021 throw new SecurityException("Unknown process: " + callingPid); 9022 } 9023 if (precessRecord.instrumentationUiAutomationConnection == null) { 9024 throw new SecurityException("Only an instrumentation process " 9025 + "with a UiAutomation can call setUserIsMonkey"); 9026 } 9027 } 9028 mUserIsMonkey = userIsMonkey; 9029 } 9030 } 9031 9032 @Override 9033 public boolean isUserAMonkey() { 9034 synchronized (this) { 9035 // If there is a controller also implies the user is a monkey. 9036 return (mUserIsMonkey || mController != null); 9037 } 9038 } 9039 9040 public void requestBugReport() { 9041 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9042 SystemProperties.set("ctl.start", "bugreport"); 9043 } 9044 9045 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9046 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9047 } 9048 9049 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9050 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9051 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9052 } 9053 return KEY_DISPATCHING_TIMEOUT; 9054 } 9055 9056 @Override 9057 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9058 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9059 != PackageManager.PERMISSION_GRANTED) { 9060 throw new SecurityException("Requires permission " 9061 + android.Manifest.permission.FILTER_EVENTS); 9062 } 9063 ProcessRecord proc; 9064 long timeout; 9065 synchronized (this) { 9066 synchronized (mPidsSelfLocked) { 9067 proc = mPidsSelfLocked.get(pid); 9068 } 9069 timeout = getInputDispatchingTimeoutLocked(proc); 9070 } 9071 9072 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9073 return -1; 9074 } 9075 9076 return timeout; 9077 } 9078 9079 /** 9080 * Handle input dispatching timeouts. 9081 * Returns whether input dispatching should be aborted or not. 9082 */ 9083 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9084 final ActivityRecord activity, final ActivityRecord parent, 9085 final boolean aboveSystem, String reason) { 9086 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9087 != PackageManager.PERMISSION_GRANTED) { 9088 throw new SecurityException("Requires permission " 9089 + android.Manifest.permission.FILTER_EVENTS); 9090 } 9091 9092 final String annotation; 9093 if (reason == null) { 9094 annotation = "Input dispatching timed out"; 9095 } else { 9096 annotation = "Input dispatching timed out (" + reason + ")"; 9097 } 9098 9099 if (proc != null) { 9100 synchronized (this) { 9101 if (proc.debugging) { 9102 return false; 9103 } 9104 9105 if (mDidDexOpt) { 9106 // Give more time since we were dexopting. 9107 mDidDexOpt = false; 9108 return false; 9109 } 9110 9111 if (proc.instrumentationClass != null) { 9112 Bundle info = new Bundle(); 9113 info.putString("shortMsg", "keyDispatchingTimedOut"); 9114 info.putString("longMsg", annotation); 9115 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9116 return true; 9117 } 9118 } 9119 mHandler.post(new Runnable() { 9120 @Override 9121 public void run() { 9122 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9123 } 9124 }); 9125 } 9126 9127 return true; 9128 } 9129 9130 public Bundle getAssistContextExtras(int requestType) { 9131 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9132 "getAssistContextExtras()"); 9133 PendingAssistExtras pae; 9134 Bundle extras = new Bundle(); 9135 synchronized (this) { 9136 ActivityRecord activity = getFocusedStack().mResumedActivity; 9137 if (activity == null) { 9138 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9139 return null; 9140 } 9141 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9142 if (activity.app == null || activity.app.thread == null) { 9143 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9144 return extras; 9145 } 9146 if (activity.app.pid == Binder.getCallingPid()) { 9147 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9148 return extras; 9149 } 9150 pae = new PendingAssistExtras(activity); 9151 try { 9152 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9153 requestType); 9154 mPendingAssistExtras.add(pae); 9155 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9156 } catch (RemoteException e) { 9157 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9158 return extras; 9159 } 9160 } 9161 synchronized (pae) { 9162 while (!pae.haveResult) { 9163 try { 9164 pae.wait(); 9165 } catch (InterruptedException e) { 9166 } 9167 } 9168 if (pae.result != null) { 9169 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9170 } 9171 } 9172 synchronized (this) { 9173 mPendingAssistExtras.remove(pae); 9174 mHandler.removeCallbacks(pae); 9175 } 9176 return extras; 9177 } 9178 9179 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9180 PendingAssistExtras pae = (PendingAssistExtras)token; 9181 synchronized (pae) { 9182 pae.result = extras; 9183 pae.haveResult = true; 9184 pae.notifyAll(); 9185 } 9186 } 9187 9188 public void registerProcessObserver(IProcessObserver observer) { 9189 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9190 "registerProcessObserver()"); 9191 synchronized (this) { 9192 mProcessObservers.register(observer); 9193 } 9194 } 9195 9196 @Override 9197 public void unregisterProcessObserver(IProcessObserver observer) { 9198 synchronized (this) { 9199 mProcessObservers.unregister(observer); 9200 } 9201 } 9202 9203 @Override 9204 public boolean convertFromTranslucent(IBinder token) { 9205 final long origId = Binder.clearCallingIdentity(); 9206 try { 9207 synchronized (this) { 9208 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9209 if (r == null) { 9210 return false; 9211 } 9212 if (r.changeWindowTranslucency(true)) { 9213 mWindowManager.setAppFullscreen(token, true); 9214 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9215 return true; 9216 } 9217 return false; 9218 } 9219 } finally { 9220 Binder.restoreCallingIdentity(origId); 9221 } 9222 } 9223 9224 @Override 9225 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9226 final long origId = Binder.clearCallingIdentity(); 9227 try { 9228 synchronized (this) { 9229 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9230 if (r == null) { 9231 return false; 9232 } 9233 if (r.changeWindowTranslucency(false)) { 9234 r.task.stack.convertToTranslucent(r, options); 9235 mWindowManager.setAppFullscreen(token, false); 9236 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9237 return true; 9238 } 9239 return false; 9240 } 9241 } finally { 9242 Binder.restoreCallingIdentity(origId); 9243 } 9244 } 9245 9246 @Override 9247 public ActivityOptions getActivityOptions(IBinder token) { 9248 final long origId = Binder.clearCallingIdentity(); 9249 try { 9250 synchronized (this) { 9251 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9252 if (r != null) { 9253 final ActivityOptions activityOptions = r.pendingOptions; 9254 r.pendingOptions = null; 9255 return activityOptions; 9256 } 9257 return null; 9258 } 9259 } finally { 9260 Binder.restoreCallingIdentity(origId); 9261 } 9262 } 9263 9264 @Override 9265 public void setImmersive(IBinder token, boolean immersive) { 9266 synchronized(this) { 9267 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9268 if (r == null) { 9269 throw new IllegalArgumentException(); 9270 } 9271 r.immersive = immersive; 9272 9273 // update associated state if we're frontmost 9274 if (r == mFocusedActivity) { 9275 if (DEBUG_IMMERSIVE) { 9276 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9277 } 9278 applyUpdateLockStateLocked(r); 9279 } 9280 } 9281 } 9282 9283 @Override 9284 public boolean isImmersive(IBinder token) { 9285 synchronized (this) { 9286 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9287 if (r == null) { 9288 throw new IllegalArgumentException(); 9289 } 9290 return r.immersive; 9291 } 9292 } 9293 9294 public boolean isTopActivityImmersive() { 9295 enforceNotIsolatedCaller("startActivity"); 9296 synchronized (this) { 9297 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9298 return (r != null) ? r.immersive : false; 9299 } 9300 } 9301 9302 public final void enterSafeMode() { 9303 synchronized(this) { 9304 // It only makes sense to do this before the system is ready 9305 // and started launching other packages. 9306 if (!mSystemReady) { 9307 try { 9308 AppGlobals.getPackageManager().enterSafeMode(); 9309 } catch (RemoteException e) { 9310 } 9311 } 9312 9313 mSafeMode = true; 9314 } 9315 } 9316 9317 public final void showSafeModeOverlay() { 9318 View v = LayoutInflater.from(mContext).inflate( 9319 com.android.internal.R.layout.safe_mode, null); 9320 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9321 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9322 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9323 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9324 lp.gravity = Gravity.BOTTOM | Gravity.START; 9325 lp.format = v.getBackground().getOpacity(); 9326 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9327 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9328 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9329 ((WindowManager)mContext.getSystemService( 9330 Context.WINDOW_SERVICE)).addView(v, lp); 9331 } 9332 9333 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9334 if (!(sender instanceof PendingIntentRecord)) { 9335 return; 9336 } 9337 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9338 synchronized (stats) { 9339 if (mBatteryStatsService.isOnBattery()) { 9340 mBatteryStatsService.enforceCallingPermission(); 9341 PendingIntentRecord rec = (PendingIntentRecord)sender; 9342 int MY_UID = Binder.getCallingUid(); 9343 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9344 BatteryStatsImpl.Uid.Pkg pkg = 9345 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9346 sourcePkg != null ? sourcePkg : rec.key.packageName); 9347 pkg.incWakeupsLocked(); 9348 } 9349 } 9350 } 9351 9352 public boolean killPids(int[] pids, String pReason, boolean secure) { 9353 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9354 throw new SecurityException("killPids only available to the system"); 9355 } 9356 String reason = (pReason == null) ? "Unknown" : pReason; 9357 // XXX Note: don't acquire main activity lock here, because the window 9358 // manager calls in with its locks held. 9359 9360 boolean killed = false; 9361 synchronized (mPidsSelfLocked) { 9362 int[] types = new int[pids.length]; 9363 int worstType = 0; 9364 for (int i=0; i<pids.length; i++) { 9365 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9366 if (proc != null) { 9367 int type = proc.setAdj; 9368 types[i] = type; 9369 if (type > worstType) { 9370 worstType = type; 9371 } 9372 } 9373 } 9374 9375 // If the worst oom_adj is somewhere in the cached proc LRU range, 9376 // then constrain it so we will kill all cached procs. 9377 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9378 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9379 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9380 } 9381 9382 // If this is not a secure call, don't let it kill processes that 9383 // are important. 9384 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9385 worstType = ProcessList.SERVICE_ADJ; 9386 } 9387 9388 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9389 for (int i=0; i<pids.length; i++) { 9390 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9391 if (proc == null) { 9392 continue; 9393 } 9394 int adj = proc.setAdj; 9395 if (adj >= worstType && !proc.killedByAm) { 9396 killUnneededProcessLocked(proc, reason); 9397 killed = true; 9398 } 9399 } 9400 } 9401 return killed; 9402 } 9403 9404 @Override 9405 public void killUid(int uid, String reason) { 9406 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9407 throw new SecurityException("killUid only available to the system"); 9408 } 9409 synchronized (this) { 9410 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9411 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9412 reason != null ? reason : "kill uid"); 9413 } 9414 } 9415 9416 @Override 9417 public boolean killProcessesBelowForeground(String reason) { 9418 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9419 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9420 } 9421 9422 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9423 } 9424 9425 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9426 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9427 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9428 } 9429 9430 boolean killed = false; 9431 synchronized (mPidsSelfLocked) { 9432 final int size = mPidsSelfLocked.size(); 9433 for (int i = 0; i < size; i++) { 9434 final int pid = mPidsSelfLocked.keyAt(i); 9435 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9436 if (proc == null) continue; 9437 9438 final int adj = proc.setAdj; 9439 if (adj > belowAdj && !proc.killedByAm) { 9440 killUnneededProcessLocked(proc, reason); 9441 killed = true; 9442 } 9443 } 9444 } 9445 return killed; 9446 } 9447 9448 @Override 9449 public void hang(final IBinder who, boolean allowRestart) { 9450 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9451 != PackageManager.PERMISSION_GRANTED) { 9452 throw new SecurityException("Requires permission " 9453 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9454 } 9455 9456 final IBinder.DeathRecipient death = new DeathRecipient() { 9457 @Override 9458 public void binderDied() { 9459 synchronized (this) { 9460 notifyAll(); 9461 } 9462 } 9463 }; 9464 9465 try { 9466 who.linkToDeath(death, 0); 9467 } catch (RemoteException e) { 9468 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9469 return; 9470 } 9471 9472 synchronized (this) { 9473 Watchdog.getInstance().setAllowRestart(allowRestart); 9474 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9475 synchronized (death) { 9476 while (who.isBinderAlive()) { 9477 try { 9478 death.wait(); 9479 } catch (InterruptedException e) { 9480 } 9481 } 9482 } 9483 Watchdog.getInstance().setAllowRestart(true); 9484 } 9485 } 9486 9487 @Override 9488 public void restart() { 9489 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9490 != PackageManager.PERMISSION_GRANTED) { 9491 throw new SecurityException("Requires permission " 9492 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9493 } 9494 9495 Log.i(TAG, "Sending shutdown broadcast..."); 9496 9497 BroadcastReceiver br = new BroadcastReceiver() { 9498 @Override public void onReceive(Context context, Intent intent) { 9499 // Now the broadcast is done, finish up the low-level shutdown. 9500 Log.i(TAG, "Shutting down activity manager..."); 9501 shutdown(10000); 9502 Log.i(TAG, "Shutdown complete, restarting!"); 9503 Process.killProcess(Process.myPid()); 9504 System.exit(10); 9505 } 9506 }; 9507 9508 // First send the high-level shut down broadcast. 9509 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9510 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9511 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9512 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9513 mContext.sendOrderedBroadcastAsUser(intent, 9514 UserHandle.ALL, null, br, mHandler, 0, null, null); 9515 */ 9516 br.onReceive(mContext, intent); 9517 } 9518 9519 private long getLowRamTimeSinceIdle(long now) { 9520 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9521 } 9522 9523 @Override 9524 public void performIdleMaintenance() { 9525 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9526 != PackageManager.PERMISSION_GRANTED) { 9527 throw new SecurityException("Requires permission " 9528 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9529 } 9530 9531 synchronized (this) { 9532 final long now = SystemClock.uptimeMillis(); 9533 final long timeSinceLastIdle = now - mLastIdleTime; 9534 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9535 mLastIdleTime = now; 9536 mLowRamTimeSinceLastIdle = 0; 9537 if (mLowRamStartTime != 0) { 9538 mLowRamStartTime = now; 9539 } 9540 9541 StringBuilder sb = new StringBuilder(128); 9542 sb.append("Idle maintenance over "); 9543 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9544 sb.append(" low RAM for "); 9545 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9546 Slog.i(TAG, sb.toString()); 9547 9548 // If at least 1/3 of our time since the last idle period has been spent 9549 // with RAM low, then we want to kill processes. 9550 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9551 9552 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9553 ProcessRecord proc = mLruProcesses.get(i); 9554 if (proc.notCachedSinceIdle) { 9555 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9556 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9557 if (doKilling && proc.initialIdlePss != 0 9558 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9559 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9560 + " from " + proc.initialIdlePss + ")"); 9561 } 9562 } 9563 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9564 proc.notCachedSinceIdle = true; 9565 proc.initialIdlePss = 0; 9566 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9567 isSleeping(), now); 9568 } 9569 } 9570 9571 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9572 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9573 } 9574 } 9575 9576 private void retrieveSettings() { 9577 final ContentResolver resolver = mContext.getContentResolver(); 9578 String debugApp = Settings.Global.getString( 9579 resolver, Settings.Global.DEBUG_APP); 9580 boolean waitForDebugger = Settings.Global.getInt( 9581 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9582 boolean alwaysFinishActivities = Settings.Global.getInt( 9583 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9584 boolean forceRtl = Settings.Global.getInt( 9585 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9586 // Transfer any global setting for forcing RTL layout, into a System Property 9587 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9588 9589 Configuration configuration = new Configuration(); 9590 Settings.System.getConfiguration(resolver, configuration); 9591 if (forceRtl) { 9592 // This will take care of setting the correct layout direction flags 9593 configuration.setLayoutDirection(configuration.locale); 9594 } 9595 9596 synchronized (this) { 9597 mDebugApp = mOrigDebugApp = debugApp; 9598 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9599 mAlwaysFinishActivities = alwaysFinishActivities; 9600 // This happens before any activities are started, so we can 9601 // change mConfiguration in-place. 9602 updateConfigurationLocked(configuration, null, false, true); 9603 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9604 } 9605 } 9606 9607 public boolean testIsSystemReady() { 9608 // no need to synchronize(this) just to read & return the value 9609 return mSystemReady; 9610 } 9611 9612 private static File getCalledPreBootReceiversFile() { 9613 File dataDir = Environment.getDataDirectory(); 9614 File systemDir = new File(dataDir, "system"); 9615 File fname = new File(systemDir, "called_pre_boots.dat"); 9616 return fname; 9617 } 9618 9619 static final int LAST_DONE_VERSION = 10000; 9620 9621 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9622 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9623 File file = getCalledPreBootReceiversFile(); 9624 FileInputStream fis = null; 9625 try { 9626 fis = new FileInputStream(file); 9627 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9628 int fvers = dis.readInt(); 9629 if (fvers == LAST_DONE_VERSION) { 9630 String vers = dis.readUTF(); 9631 String codename = dis.readUTF(); 9632 String build = dis.readUTF(); 9633 if (android.os.Build.VERSION.RELEASE.equals(vers) 9634 && android.os.Build.VERSION.CODENAME.equals(codename) 9635 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9636 int num = dis.readInt(); 9637 while (num > 0) { 9638 num--; 9639 String pkg = dis.readUTF(); 9640 String cls = dis.readUTF(); 9641 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9642 } 9643 } 9644 } 9645 } catch (FileNotFoundException e) { 9646 } catch (IOException e) { 9647 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9648 } finally { 9649 if (fis != null) { 9650 try { 9651 fis.close(); 9652 } catch (IOException e) { 9653 } 9654 } 9655 } 9656 return lastDoneReceivers; 9657 } 9658 9659 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9660 File file = getCalledPreBootReceiversFile(); 9661 FileOutputStream fos = null; 9662 DataOutputStream dos = null; 9663 try { 9664 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9665 fos = new FileOutputStream(file); 9666 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9667 dos.writeInt(LAST_DONE_VERSION); 9668 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9669 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9670 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9671 dos.writeInt(list.size()); 9672 for (int i=0; i<list.size(); i++) { 9673 dos.writeUTF(list.get(i).getPackageName()); 9674 dos.writeUTF(list.get(i).getClassName()); 9675 } 9676 } catch (IOException e) { 9677 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9678 file.delete(); 9679 } finally { 9680 FileUtils.sync(fos); 9681 if (dos != null) { 9682 try { 9683 dos.close(); 9684 } catch (IOException e) { 9685 // TODO Auto-generated catch block 9686 e.printStackTrace(); 9687 } 9688 } 9689 } 9690 } 9691 9692 public void systemReady(final Runnable goingCallback) { 9693 synchronized(this) { 9694 if (mSystemReady) { 9695 if (goingCallback != null) goingCallback.run(); 9696 return; 9697 } 9698 9699 if (mRecentTasks == null) { 9700 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9701 if (!mRecentTasks.isEmpty()) { 9702 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9703 } 9704 mTaskPersister.startPersisting(); 9705 } 9706 9707 // Check to see if there are any update receivers to run. 9708 if (!mDidUpdate) { 9709 if (mWaitingUpdate) { 9710 return; 9711 } 9712 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9713 List<ResolveInfo> ris = null; 9714 try { 9715 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9716 intent, null, 0, 0); 9717 } catch (RemoteException e) { 9718 } 9719 if (ris != null) { 9720 for (int i=ris.size()-1; i>=0; i--) { 9721 if ((ris.get(i).activityInfo.applicationInfo.flags 9722 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9723 ris.remove(i); 9724 } 9725 } 9726 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9727 9728 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9729 9730 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9731 for (int i=0; i<ris.size(); i++) { 9732 ActivityInfo ai = ris.get(i).activityInfo; 9733 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9734 if (lastDoneReceivers.contains(comp)) { 9735 // We already did the pre boot receiver for this app with the current 9736 // platform version, so don't do it again... 9737 ris.remove(i); 9738 i--; 9739 // ...however, do keep it as one that has been done, so we don't 9740 // forget about it when rewriting the file of last done receivers. 9741 doneReceivers.add(comp); 9742 } 9743 } 9744 9745 final int[] users = getUsersLocked(); 9746 for (int i=0; i<ris.size(); i++) { 9747 ActivityInfo ai = ris.get(i).activityInfo; 9748 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9749 doneReceivers.add(comp); 9750 intent.setComponent(comp); 9751 for (int j=0; j<users.length; j++) { 9752 IIntentReceiver finisher = null; 9753 if (i == ris.size()-1 && j == users.length-1) { 9754 finisher = new IIntentReceiver.Stub() { 9755 public void performReceive(Intent intent, int resultCode, 9756 String data, Bundle extras, boolean ordered, 9757 boolean sticky, int sendingUser) { 9758 // The raw IIntentReceiver interface is called 9759 // with the AM lock held, so redispatch to 9760 // execute our code without the lock. 9761 mHandler.post(new Runnable() { 9762 public void run() { 9763 synchronized (ActivityManagerService.this) { 9764 mDidUpdate = true; 9765 } 9766 writeLastDonePreBootReceivers(doneReceivers); 9767 showBootMessage(mContext.getText( 9768 R.string.android_upgrading_complete), 9769 false); 9770 systemReady(goingCallback); 9771 } 9772 }); 9773 } 9774 }; 9775 } 9776 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9777 + " for user " + users[j]); 9778 broadcastIntentLocked(null, null, intent, null, finisher, 9779 0, null, null, null, AppOpsManager.OP_NONE, 9780 true, false, MY_PID, Process.SYSTEM_UID, 9781 users[j]); 9782 if (finisher != null) { 9783 mWaitingUpdate = true; 9784 } 9785 } 9786 } 9787 } 9788 if (mWaitingUpdate) { 9789 return; 9790 } 9791 mDidUpdate = true; 9792 } 9793 9794 mAppOpsService.systemReady(); 9795 mUsageStatsService.systemReady(); 9796 mSystemReady = true; 9797 } 9798 9799 ArrayList<ProcessRecord> procsToKill = null; 9800 synchronized(mPidsSelfLocked) { 9801 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9802 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9803 if (!isAllowedWhileBooting(proc.info)){ 9804 if (procsToKill == null) { 9805 procsToKill = new ArrayList<ProcessRecord>(); 9806 } 9807 procsToKill.add(proc); 9808 } 9809 } 9810 } 9811 9812 synchronized(this) { 9813 if (procsToKill != null) { 9814 for (int i=procsToKill.size()-1; i>=0; i--) { 9815 ProcessRecord proc = procsToKill.get(i); 9816 Slog.i(TAG, "Removing system update proc: " + proc); 9817 removeProcessLocked(proc, true, false, "system update done"); 9818 } 9819 } 9820 9821 // Now that we have cleaned up any update processes, we 9822 // are ready to start launching real processes and know that 9823 // we won't trample on them any more. 9824 mProcessesReady = true; 9825 } 9826 9827 Slog.i(TAG, "System now ready"); 9828 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9829 SystemClock.uptimeMillis()); 9830 9831 synchronized(this) { 9832 // Make sure we have no pre-ready processes sitting around. 9833 9834 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9835 ResolveInfo ri = mContext.getPackageManager() 9836 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9837 STOCK_PM_FLAGS); 9838 CharSequence errorMsg = null; 9839 if (ri != null) { 9840 ActivityInfo ai = ri.activityInfo; 9841 ApplicationInfo app = ai.applicationInfo; 9842 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9843 mTopAction = Intent.ACTION_FACTORY_TEST; 9844 mTopData = null; 9845 mTopComponent = new ComponentName(app.packageName, 9846 ai.name); 9847 } else { 9848 errorMsg = mContext.getResources().getText( 9849 com.android.internal.R.string.factorytest_not_system); 9850 } 9851 } else { 9852 errorMsg = mContext.getResources().getText( 9853 com.android.internal.R.string.factorytest_no_action); 9854 } 9855 if (errorMsg != null) { 9856 mTopAction = null; 9857 mTopData = null; 9858 mTopComponent = null; 9859 Message msg = Message.obtain(); 9860 msg.what = SHOW_FACTORY_ERROR_MSG; 9861 msg.getData().putCharSequence("msg", errorMsg); 9862 mHandler.sendMessage(msg); 9863 } 9864 } 9865 } 9866 9867 retrieveSettings(); 9868 9869 synchronized (this) { 9870 readGrantedUriPermissionsLocked(); 9871 } 9872 9873 if (goingCallback != null) goingCallback.run(); 9874 9875 mSystemServiceManager.startUser(mCurrentUserId); 9876 9877 synchronized (this) { 9878 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9879 try { 9880 List apps = AppGlobals.getPackageManager(). 9881 getPersistentApplications(STOCK_PM_FLAGS); 9882 if (apps != null) { 9883 int N = apps.size(); 9884 int i; 9885 for (i=0; i<N; i++) { 9886 ApplicationInfo info 9887 = (ApplicationInfo)apps.get(i); 9888 if (info != null && 9889 !info.packageName.equals("android")) { 9890 addAppLocked(info, false, null /* ABI override */); 9891 } 9892 } 9893 } 9894 } catch (RemoteException ex) { 9895 // pm is in same process, this will never happen. 9896 } 9897 } 9898 9899 // Start up initial activity. 9900 mBooting = true; 9901 9902 try { 9903 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9904 Message msg = Message.obtain(); 9905 msg.what = SHOW_UID_ERROR_MSG; 9906 mHandler.sendMessage(msg); 9907 } 9908 } catch (RemoteException e) { 9909 } 9910 9911 long ident = Binder.clearCallingIdentity(); 9912 try { 9913 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9914 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9915 | Intent.FLAG_RECEIVER_FOREGROUND); 9916 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9917 broadcastIntentLocked(null, null, intent, 9918 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9919 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9920 intent = new Intent(Intent.ACTION_USER_STARTING); 9921 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9922 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9923 broadcastIntentLocked(null, null, intent, 9924 null, new IIntentReceiver.Stub() { 9925 @Override 9926 public void performReceive(Intent intent, int resultCode, String data, 9927 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9928 throws RemoteException { 9929 } 9930 }, 0, null, null, 9931 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9932 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9933 } catch (Throwable t) { 9934 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9935 } finally { 9936 Binder.restoreCallingIdentity(ident); 9937 } 9938 mStackSupervisor.resumeTopActivitiesLocked(); 9939 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9940 } 9941 } 9942 9943 private boolean makeAppCrashingLocked(ProcessRecord app, 9944 String shortMsg, String longMsg, String stackTrace) { 9945 app.crashing = true; 9946 app.crashingReport = generateProcessError(app, 9947 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9948 startAppProblemLocked(app); 9949 app.stopFreezingAllLocked(); 9950 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9951 } 9952 9953 private void makeAppNotRespondingLocked(ProcessRecord app, 9954 String activity, String shortMsg, String longMsg) { 9955 app.notResponding = true; 9956 app.notRespondingReport = generateProcessError(app, 9957 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9958 activity, shortMsg, longMsg, null); 9959 startAppProblemLocked(app); 9960 app.stopFreezingAllLocked(); 9961 } 9962 9963 /** 9964 * Generate a process error record, suitable for attachment to a ProcessRecord. 9965 * 9966 * @param app The ProcessRecord in which the error occurred. 9967 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9968 * ActivityManager.AppErrorStateInfo 9969 * @param activity The activity associated with the crash, if known. 9970 * @param shortMsg Short message describing the crash. 9971 * @param longMsg Long message describing the crash. 9972 * @param stackTrace Full crash stack trace, may be null. 9973 * 9974 * @return Returns a fully-formed AppErrorStateInfo record. 9975 */ 9976 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9977 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9978 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9979 9980 report.condition = condition; 9981 report.processName = app.processName; 9982 report.pid = app.pid; 9983 report.uid = app.info.uid; 9984 report.tag = activity; 9985 report.shortMsg = shortMsg; 9986 report.longMsg = longMsg; 9987 report.stackTrace = stackTrace; 9988 9989 return report; 9990 } 9991 9992 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9993 synchronized (this) { 9994 app.crashing = false; 9995 app.crashingReport = null; 9996 app.notResponding = false; 9997 app.notRespondingReport = null; 9998 if (app.anrDialog == fromDialog) { 9999 app.anrDialog = null; 10000 } 10001 if (app.waitDialog == fromDialog) { 10002 app.waitDialog = null; 10003 } 10004 if (app.pid > 0 && app.pid != MY_PID) { 10005 handleAppCrashLocked(app, null, null, null); 10006 killUnneededProcessLocked(app, "user request after error"); 10007 } 10008 } 10009 } 10010 10011 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10012 String stackTrace) { 10013 long now = SystemClock.uptimeMillis(); 10014 10015 Long crashTime; 10016 if (!app.isolated) { 10017 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10018 } else { 10019 crashTime = null; 10020 } 10021 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10022 // This process loses! 10023 Slog.w(TAG, "Process " + app.info.processName 10024 + " has crashed too many times: killing!"); 10025 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10026 app.userId, app.info.processName, app.uid); 10027 mStackSupervisor.handleAppCrashLocked(app); 10028 if (!app.persistent) { 10029 // We don't want to start this process again until the user 10030 // explicitly does so... but for persistent process, we really 10031 // need to keep it running. If a persistent process is actually 10032 // repeatedly crashing, then badness for everyone. 10033 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10034 app.info.processName); 10035 if (!app.isolated) { 10036 // XXX We don't have a way to mark isolated processes 10037 // as bad, since they don't have a peristent identity. 10038 mBadProcesses.put(app.info.processName, app.uid, 10039 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10040 mProcessCrashTimes.remove(app.info.processName, app.uid); 10041 } 10042 app.bad = true; 10043 app.removed = true; 10044 // Don't let services in this process be restarted and potentially 10045 // annoy the user repeatedly. Unless it is persistent, since those 10046 // processes run critical code. 10047 removeProcessLocked(app, false, false, "crash"); 10048 mStackSupervisor.resumeTopActivitiesLocked(); 10049 return false; 10050 } 10051 mStackSupervisor.resumeTopActivitiesLocked(); 10052 } else { 10053 mStackSupervisor.finishTopRunningActivityLocked(app); 10054 } 10055 10056 // Bump up the crash count of any services currently running in the proc. 10057 for (int i=app.services.size()-1; i>=0; i--) { 10058 // Any services running in the application need to be placed 10059 // back in the pending list. 10060 ServiceRecord sr = app.services.valueAt(i); 10061 sr.crashCount++; 10062 } 10063 10064 // If the crashing process is what we consider to be the "home process" and it has been 10065 // replaced by a third-party app, clear the package preferred activities from packages 10066 // with a home activity running in the process to prevent a repeatedly crashing app 10067 // from blocking the user to manually clear the list. 10068 final ArrayList<ActivityRecord> activities = app.activities; 10069 if (app == mHomeProcess && activities.size() > 0 10070 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10071 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10072 final ActivityRecord r = activities.get(activityNdx); 10073 if (r.isHomeActivity()) { 10074 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10075 try { 10076 ActivityThread.getPackageManager() 10077 .clearPackagePreferredActivities(r.packageName); 10078 } catch (RemoteException c) { 10079 // pm is in same process, this will never happen. 10080 } 10081 } 10082 } 10083 } 10084 10085 if (!app.isolated) { 10086 // XXX Can't keep track of crash times for isolated processes, 10087 // because they don't have a perisistent identity. 10088 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10089 } 10090 10091 return true; 10092 } 10093 10094 void startAppProblemLocked(ProcessRecord app) { 10095 if (app.userId == mCurrentUserId) { 10096 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10097 mContext, app.info.packageName, app.info.flags); 10098 } else { 10099 // If this app is not running under the current user, then we 10100 // can't give it a report button because that would require 10101 // launching the report UI under a different user. 10102 app.errorReportReceiver = null; 10103 } 10104 skipCurrentReceiverLocked(app); 10105 } 10106 10107 void skipCurrentReceiverLocked(ProcessRecord app) { 10108 for (BroadcastQueue queue : mBroadcastQueues) { 10109 queue.skipCurrentReceiverLocked(app); 10110 } 10111 } 10112 10113 /** 10114 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10115 * The application process will exit immediately after this call returns. 10116 * @param app object of the crashing app, null for the system server 10117 * @param crashInfo describing the exception 10118 */ 10119 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10120 ProcessRecord r = findAppProcess(app, "Crash"); 10121 final String processName = app == null ? "system_server" 10122 : (r == null ? "unknown" : r.processName); 10123 10124 handleApplicationCrashInner("crash", r, processName, crashInfo); 10125 } 10126 10127 /* Native crash reporting uses this inner version because it needs to be somewhat 10128 * decoupled from the AM-managed cleanup lifecycle 10129 */ 10130 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10131 ApplicationErrorReport.CrashInfo crashInfo) { 10132 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10133 UserHandle.getUserId(Binder.getCallingUid()), processName, 10134 r == null ? -1 : r.info.flags, 10135 crashInfo.exceptionClassName, 10136 crashInfo.exceptionMessage, 10137 crashInfo.throwFileName, 10138 crashInfo.throwLineNumber); 10139 10140 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10141 10142 crashApplication(r, crashInfo); 10143 } 10144 10145 public void handleApplicationStrictModeViolation( 10146 IBinder app, 10147 int violationMask, 10148 StrictMode.ViolationInfo info) { 10149 ProcessRecord r = findAppProcess(app, "StrictMode"); 10150 if (r == null) { 10151 return; 10152 } 10153 10154 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10155 Integer stackFingerprint = info.hashCode(); 10156 boolean logIt = true; 10157 synchronized (mAlreadyLoggedViolatedStacks) { 10158 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10159 logIt = false; 10160 // TODO: sub-sample into EventLog for these, with 10161 // the info.durationMillis? Then we'd get 10162 // the relative pain numbers, without logging all 10163 // the stack traces repeatedly. We'd want to do 10164 // likewise in the client code, which also does 10165 // dup suppression, before the Binder call. 10166 } else { 10167 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10168 mAlreadyLoggedViolatedStacks.clear(); 10169 } 10170 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10171 } 10172 } 10173 if (logIt) { 10174 logStrictModeViolationToDropBox(r, info); 10175 } 10176 } 10177 10178 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10179 AppErrorResult result = new AppErrorResult(); 10180 synchronized (this) { 10181 final long origId = Binder.clearCallingIdentity(); 10182 10183 Message msg = Message.obtain(); 10184 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10185 HashMap<String, Object> data = new HashMap<String, Object>(); 10186 data.put("result", result); 10187 data.put("app", r); 10188 data.put("violationMask", violationMask); 10189 data.put("info", info); 10190 msg.obj = data; 10191 mHandler.sendMessage(msg); 10192 10193 Binder.restoreCallingIdentity(origId); 10194 } 10195 int res = result.get(); 10196 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10197 } 10198 } 10199 10200 // Depending on the policy in effect, there could be a bunch of 10201 // these in quick succession so we try to batch these together to 10202 // minimize disk writes, number of dropbox entries, and maximize 10203 // compression, by having more fewer, larger records. 10204 private void logStrictModeViolationToDropBox( 10205 ProcessRecord process, 10206 StrictMode.ViolationInfo info) { 10207 if (info == null) { 10208 return; 10209 } 10210 final boolean isSystemApp = process == null || 10211 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10212 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10213 final String processName = process == null ? "unknown" : process.processName; 10214 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10215 final DropBoxManager dbox = (DropBoxManager) 10216 mContext.getSystemService(Context.DROPBOX_SERVICE); 10217 10218 // Exit early if the dropbox isn't configured to accept this report type. 10219 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10220 10221 boolean bufferWasEmpty; 10222 boolean needsFlush; 10223 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10224 synchronized (sb) { 10225 bufferWasEmpty = sb.length() == 0; 10226 appendDropBoxProcessHeaders(process, processName, sb); 10227 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10228 sb.append("System-App: ").append(isSystemApp).append("\n"); 10229 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10230 if (info.violationNumThisLoop != 0) { 10231 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10232 } 10233 if (info.numAnimationsRunning != 0) { 10234 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10235 } 10236 if (info.broadcastIntentAction != null) { 10237 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10238 } 10239 if (info.durationMillis != -1) { 10240 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10241 } 10242 if (info.numInstances != -1) { 10243 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10244 } 10245 if (info.tags != null) { 10246 for (String tag : info.tags) { 10247 sb.append("Span-Tag: ").append(tag).append("\n"); 10248 } 10249 } 10250 sb.append("\n"); 10251 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10252 sb.append(info.crashInfo.stackTrace); 10253 } 10254 sb.append("\n"); 10255 10256 // Only buffer up to ~64k. Various logging bits truncate 10257 // things at 128k. 10258 needsFlush = (sb.length() > 64 * 1024); 10259 } 10260 10261 // Flush immediately if the buffer's grown too large, or this 10262 // is a non-system app. Non-system apps are isolated with a 10263 // different tag & policy and not batched. 10264 // 10265 // Batching is useful during internal testing with 10266 // StrictMode settings turned up high. Without batching, 10267 // thousands of separate files could be created on boot. 10268 if (!isSystemApp || needsFlush) { 10269 new Thread("Error dump: " + dropboxTag) { 10270 @Override 10271 public void run() { 10272 String report; 10273 synchronized (sb) { 10274 report = sb.toString(); 10275 sb.delete(0, sb.length()); 10276 sb.trimToSize(); 10277 } 10278 if (report.length() != 0) { 10279 dbox.addText(dropboxTag, report); 10280 } 10281 } 10282 }.start(); 10283 return; 10284 } 10285 10286 // System app batching: 10287 if (!bufferWasEmpty) { 10288 // An existing dropbox-writing thread is outstanding, so 10289 // we don't need to start it up. The existing thread will 10290 // catch the buffer appends we just did. 10291 return; 10292 } 10293 10294 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10295 // (After this point, we shouldn't access AMS internal data structures.) 10296 new Thread("Error dump: " + dropboxTag) { 10297 @Override 10298 public void run() { 10299 // 5 second sleep to let stacks arrive and be batched together 10300 try { 10301 Thread.sleep(5000); // 5 seconds 10302 } catch (InterruptedException e) {} 10303 10304 String errorReport; 10305 synchronized (mStrictModeBuffer) { 10306 errorReport = mStrictModeBuffer.toString(); 10307 if (errorReport.length() == 0) { 10308 return; 10309 } 10310 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10311 mStrictModeBuffer.trimToSize(); 10312 } 10313 dbox.addText(dropboxTag, errorReport); 10314 } 10315 }.start(); 10316 } 10317 10318 /** 10319 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10320 * @param app object of the crashing app, null for the system server 10321 * @param tag reported by the caller 10322 * @param crashInfo describing the context of the error 10323 * @return true if the process should exit immediately (WTF is fatal) 10324 */ 10325 public boolean handleApplicationWtf(IBinder app, String tag, 10326 ApplicationErrorReport.CrashInfo crashInfo) { 10327 ProcessRecord r = findAppProcess(app, "WTF"); 10328 final String processName = app == null ? "system_server" 10329 : (r == null ? "unknown" : r.processName); 10330 10331 EventLog.writeEvent(EventLogTags.AM_WTF, 10332 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10333 processName, 10334 r == null ? -1 : r.info.flags, 10335 tag, crashInfo.exceptionMessage); 10336 10337 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10338 10339 if (r != null && r.pid != Process.myPid() && 10340 Settings.Global.getInt(mContext.getContentResolver(), 10341 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10342 crashApplication(r, crashInfo); 10343 return true; 10344 } else { 10345 return false; 10346 } 10347 } 10348 10349 /** 10350 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10351 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10352 */ 10353 private ProcessRecord findAppProcess(IBinder app, String reason) { 10354 if (app == null) { 10355 return null; 10356 } 10357 10358 synchronized (this) { 10359 final int NP = mProcessNames.getMap().size(); 10360 for (int ip=0; ip<NP; ip++) { 10361 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10362 final int NA = apps.size(); 10363 for (int ia=0; ia<NA; ia++) { 10364 ProcessRecord p = apps.valueAt(ia); 10365 if (p.thread != null && p.thread.asBinder() == app) { 10366 return p; 10367 } 10368 } 10369 } 10370 10371 Slog.w(TAG, "Can't find mystery application for " + reason 10372 + " from pid=" + Binder.getCallingPid() 10373 + " uid=" + Binder.getCallingUid() + ": " + app); 10374 return null; 10375 } 10376 } 10377 10378 /** 10379 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10380 * to append various headers to the dropbox log text. 10381 */ 10382 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10383 StringBuilder sb) { 10384 // Watchdog thread ends up invoking this function (with 10385 // a null ProcessRecord) to add the stack file to dropbox. 10386 // Do not acquire a lock on this (am) in such cases, as it 10387 // could cause a potential deadlock, if and when watchdog 10388 // is invoked due to unavailability of lock on am and it 10389 // would prevent watchdog from killing system_server. 10390 if (process == null) { 10391 sb.append("Process: ").append(processName).append("\n"); 10392 return; 10393 } 10394 // Note: ProcessRecord 'process' is guarded by the service 10395 // instance. (notably process.pkgList, which could otherwise change 10396 // concurrently during execution of this method) 10397 synchronized (this) { 10398 sb.append("Process: ").append(processName).append("\n"); 10399 int flags = process.info.flags; 10400 IPackageManager pm = AppGlobals.getPackageManager(); 10401 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10402 for (int ip=0; ip<process.pkgList.size(); ip++) { 10403 String pkg = process.pkgList.keyAt(ip); 10404 sb.append("Package: ").append(pkg); 10405 try { 10406 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10407 if (pi != null) { 10408 sb.append(" v").append(pi.versionCode); 10409 if (pi.versionName != null) { 10410 sb.append(" (").append(pi.versionName).append(")"); 10411 } 10412 } 10413 } catch (RemoteException e) { 10414 Slog.e(TAG, "Error getting package info: " + pkg, e); 10415 } 10416 sb.append("\n"); 10417 } 10418 } 10419 } 10420 10421 private static String processClass(ProcessRecord process) { 10422 if (process == null || process.pid == MY_PID) { 10423 return "system_server"; 10424 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10425 return "system_app"; 10426 } else { 10427 return "data_app"; 10428 } 10429 } 10430 10431 /** 10432 * Write a description of an error (crash, WTF, ANR) to the drop box. 10433 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10434 * @param process which caused the error, null means the system server 10435 * @param activity which triggered the error, null if unknown 10436 * @param parent activity related to the error, null if unknown 10437 * @param subject line related to the error, null if absent 10438 * @param report in long form describing the error, null if absent 10439 * @param logFile to include in the report, null if none 10440 * @param crashInfo giving an application stack trace, null if absent 10441 */ 10442 public void addErrorToDropBox(String eventType, 10443 ProcessRecord process, String processName, ActivityRecord activity, 10444 ActivityRecord parent, String subject, 10445 final String report, final File logFile, 10446 final ApplicationErrorReport.CrashInfo crashInfo) { 10447 // NOTE -- this must never acquire the ActivityManagerService lock, 10448 // otherwise the watchdog may be prevented from resetting the system. 10449 10450 final String dropboxTag = processClass(process) + "_" + eventType; 10451 final DropBoxManager dbox = (DropBoxManager) 10452 mContext.getSystemService(Context.DROPBOX_SERVICE); 10453 10454 // Exit early if the dropbox isn't configured to accept this report type. 10455 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10456 10457 final StringBuilder sb = new StringBuilder(1024); 10458 appendDropBoxProcessHeaders(process, processName, sb); 10459 if (activity != null) { 10460 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10461 } 10462 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10463 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10464 } 10465 if (parent != null && parent != activity) { 10466 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10467 } 10468 if (subject != null) { 10469 sb.append("Subject: ").append(subject).append("\n"); 10470 } 10471 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10472 if (Debug.isDebuggerConnected()) { 10473 sb.append("Debugger: Connected\n"); 10474 } 10475 sb.append("\n"); 10476 10477 // Do the rest in a worker thread to avoid blocking the caller on I/O 10478 // (After this point, we shouldn't access AMS internal data structures.) 10479 Thread worker = new Thread("Error dump: " + dropboxTag) { 10480 @Override 10481 public void run() { 10482 if (report != null) { 10483 sb.append(report); 10484 } 10485 if (logFile != null) { 10486 try { 10487 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10488 "\n\n[[TRUNCATED]]")); 10489 } catch (IOException e) { 10490 Slog.e(TAG, "Error reading " + logFile, e); 10491 } 10492 } 10493 if (crashInfo != null && crashInfo.stackTrace != null) { 10494 sb.append(crashInfo.stackTrace); 10495 } 10496 10497 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10498 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10499 if (lines > 0) { 10500 sb.append("\n"); 10501 10502 // Merge several logcat streams, and take the last N lines 10503 InputStreamReader input = null; 10504 try { 10505 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10506 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10507 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10508 10509 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10510 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10511 input = new InputStreamReader(logcat.getInputStream()); 10512 10513 int num; 10514 char[] buf = new char[8192]; 10515 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10516 } catch (IOException e) { 10517 Slog.e(TAG, "Error running logcat", e); 10518 } finally { 10519 if (input != null) try { input.close(); } catch (IOException e) {} 10520 } 10521 } 10522 10523 dbox.addText(dropboxTag, sb.toString()); 10524 } 10525 }; 10526 10527 if (process == null) { 10528 // If process is null, we are being called from some internal code 10529 // and may be about to die -- run this synchronously. 10530 worker.run(); 10531 } else { 10532 worker.start(); 10533 } 10534 } 10535 10536 /** 10537 * Bring up the "unexpected error" dialog box for a crashing app. 10538 * Deal with edge cases (intercepts from instrumented applications, 10539 * ActivityController, error intent receivers, that sort of thing). 10540 * @param r the application crashing 10541 * @param crashInfo describing the failure 10542 */ 10543 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10544 long timeMillis = System.currentTimeMillis(); 10545 String shortMsg = crashInfo.exceptionClassName; 10546 String longMsg = crashInfo.exceptionMessage; 10547 String stackTrace = crashInfo.stackTrace; 10548 if (shortMsg != null && longMsg != null) { 10549 longMsg = shortMsg + ": " + longMsg; 10550 } else if (shortMsg != null) { 10551 longMsg = shortMsg; 10552 } 10553 10554 AppErrorResult result = new AppErrorResult(); 10555 synchronized (this) { 10556 if (mController != null) { 10557 try { 10558 String name = r != null ? r.processName : null; 10559 int pid = r != null ? r.pid : Binder.getCallingPid(); 10560 if (!mController.appCrashed(name, pid, 10561 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10562 Slog.w(TAG, "Force-killing crashed app " + name 10563 + " at watcher's request"); 10564 Process.killProcess(pid); 10565 return; 10566 } 10567 } catch (RemoteException e) { 10568 mController = null; 10569 Watchdog.getInstance().setActivityController(null); 10570 } 10571 } 10572 10573 final long origId = Binder.clearCallingIdentity(); 10574 10575 // If this process is running instrumentation, finish it. 10576 if (r != null && r.instrumentationClass != null) { 10577 Slog.w(TAG, "Error in app " + r.processName 10578 + " running instrumentation " + r.instrumentationClass + ":"); 10579 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10580 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10581 Bundle info = new Bundle(); 10582 info.putString("shortMsg", shortMsg); 10583 info.putString("longMsg", longMsg); 10584 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10585 Binder.restoreCallingIdentity(origId); 10586 return; 10587 } 10588 10589 // If we can't identify the process or it's already exceeded its crash quota, 10590 // quit right away without showing a crash dialog. 10591 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10592 Binder.restoreCallingIdentity(origId); 10593 return; 10594 } 10595 10596 Message msg = Message.obtain(); 10597 msg.what = SHOW_ERROR_MSG; 10598 HashMap data = new HashMap(); 10599 data.put("result", result); 10600 data.put("app", r); 10601 msg.obj = data; 10602 mHandler.sendMessage(msg); 10603 10604 Binder.restoreCallingIdentity(origId); 10605 } 10606 10607 int res = result.get(); 10608 10609 Intent appErrorIntent = null; 10610 synchronized (this) { 10611 if (r != null && !r.isolated) { 10612 // XXX Can't keep track of crash time for isolated processes, 10613 // since they don't have a persistent identity. 10614 mProcessCrashTimes.put(r.info.processName, r.uid, 10615 SystemClock.uptimeMillis()); 10616 } 10617 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10618 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10619 } 10620 } 10621 10622 if (appErrorIntent != null) { 10623 try { 10624 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10625 } catch (ActivityNotFoundException e) { 10626 Slog.w(TAG, "bug report receiver dissappeared", e); 10627 } 10628 } 10629 } 10630 10631 Intent createAppErrorIntentLocked(ProcessRecord r, 10632 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10633 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10634 if (report == null) { 10635 return null; 10636 } 10637 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10638 result.setComponent(r.errorReportReceiver); 10639 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10640 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10641 return result; 10642 } 10643 10644 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10645 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10646 if (r.errorReportReceiver == null) { 10647 return null; 10648 } 10649 10650 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10651 return null; 10652 } 10653 10654 ApplicationErrorReport report = new ApplicationErrorReport(); 10655 report.packageName = r.info.packageName; 10656 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10657 report.processName = r.processName; 10658 report.time = timeMillis; 10659 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10660 10661 if (r.crashing || r.forceCrashReport) { 10662 report.type = ApplicationErrorReport.TYPE_CRASH; 10663 report.crashInfo = crashInfo; 10664 } else if (r.notResponding) { 10665 report.type = ApplicationErrorReport.TYPE_ANR; 10666 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10667 10668 report.anrInfo.activity = r.notRespondingReport.tag; 10669 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10670 report.anrInfo.info = r.notRespondingReport.longMsg; 10671 } 10672 10673 return report; 10674 } 10675 10676 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10677 enforceNotIsolatedCaller("getProcessesInErrorState"); 10678 // assume our apps are happy - lazy create the list 10679 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10680 10681 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10682 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10683 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10684 10685 synchronized (this) { 10686 10687 // iterate across all processes 10688 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10689 ProcessRecord app = mLruProcesses.get(i); 10690 if (!allUsers && app.userId != userId) { 10691 continue; 10692 } 10693 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10694 // This one's in trouble, so we'll generate a report for it 10695 // crashes are higher priority (in case there's a crash *and* an anr) 10696 ActivityManager.ProcessErrorStateInfo report = null; 10697 if (app.crashing) { 10698 report = app.crashingReport; 10699 } else if (app.notResponding) { 10700 report = app.notRespondingReport; 10701 } 10702 10703 if (report != null) { 10704 if (errList == null) { 10705 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10706 } 10707 errList.add(report); 10708 } else { 10709 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10710 " crashing = " + app.crashing + 10711 " notResponding = " + app.notResponding); 10712 } 10713 } 10714 } 10715 } 10716 10717 return errList; 10718 } 10719 10720 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10721 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10722 if (currApp != null) { 10723 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10724 } 10725 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10726 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10727 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10728 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10729 if (currApp != null) { 10730 currApp.lru = 0; 10731 } 10732 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10733 } else if (adj >= ProcessList.SERVICE_ADJ) { 10734 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10735 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10736 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10737 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10738 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10739 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10740 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10741 } else { 10742 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10743 } 10744 } 10745 10746 private void fillInProcMemInfo(ProcessRecord app, 10747 ActivityManager.RunningAppProcessInfo outInfo) { 10748 outInfo.pid = app.pid; 10749 outInfo.uid = app.info.uid; 10750 if (mHeavyWeightProcess == app) { 10751 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10752 } 10753 if (app.persistent) { 10754 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10755 } 10756 if (app.activities.size() > 0) { 10757 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10758 } 10759 outInfo.lastTrimLevel = app.trimMemoryLevel; 10760 int adj = app.curAdj; 10761 outInfo.importance = oomAdjToImportance(adj, outInfo); 10762 outInfo.importanceReasonCode = app.adjTypeCode; 10763 outInfo.processState = app.curProcState; 10764 } 10765 10766 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10767 enforceNotIsolatedCaller("getRunningAppProcesses"); 10768 // Lazy instantiation of list 10769 List<ActivityManager.RunningAppProcessInfo> runList = null; 10770 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10771 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10772 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10773 synchronized (this) { 10774 // Iterate across all processes 10775 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10776 ProcessRecord app = mLruProcesses.get(i); 10777 if (!allUsers && app.userId != userId) { 10778 continue; 10779 } 10780 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10781 // Generate process state info for running application 10782 ActivityManager.RunningAppProcessInfo currApp = 10783 new ActivityManager.RunningAppProcessInfo(app.processName, 10784 app.pid, app.getPackageList()); 10785 fillInProcMemInfo(app, currApp); 10786 if (app.adjSource instanceof ProcessRecord) { 10787 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10788 currApp.importanceReasonImportance = oomAdjToImportance( 10789 app.adjSourceOom, null); 10790 } else if (app.adjSource instanceof ActivityRecord) { 10791 ActivityRecord r = (ActivityRecord)app.adjSource; 10792 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10793 } 10794 if (app.adjTarget instanceof ComponentName) { 10795 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10796 } 10797 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10798 // + " lru=" + currApp.lru); 10799 if (runList == null) { 10800 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10801 } 10802 runList.add(currApp); 10803 } 10804 } 10805 } 10806 return runList; 10807 } 10808 10809 public List<ApplicationInfo> getRunningExternalApplications() { 10810 enforceNotIsolatedCaller("getRunningExternalApplications"); 10811 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10812 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10813 if (runningApps != null && runningApps.size() > 0) { 10814 Set<String> extList = new HashSet<String>(); 10815 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10816 if (app.pkgList != null) { 10817 for (String pkg : app.pkgList) { 10818 extList.add(pkg); 10819 } 10820 } 10821 } 10822 IPackageManager pm = AppGlobals.getPackageManager(); 10823 for (String pkg : extList) { 10824 try { 10825 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10826 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10827 retList.add(info); 10828 } 10829 } catch (RemoteException e) { 10830 } 10831 } 10832 } 10833 return retList; 10834 } 10835 10836 @Override 10837 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10838 enforceNotIsolatedCaller("getMyMemoryState"); 10839 synchronized (this) { 10840 ProcessRecord proc; 10841 synchronized (mPidsSelfLocked) { 10842 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10843 } 10844 fillInProcMemInfo(proc, outInfo); 10845 } 10846 } 10847 10848 @Override 10849 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10850 if (checkCallingPermission(android.Manifest.permission.DUMP) 10851 != PackageManager.PERMISSION_GRANTED) { 10852 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10853 + Binder.getCallingPid() 10854 + ", uid=" + Binder.getCallingUid() 10855 + " without permission " 10856 + android.Manifest.permission.DUMP); 10857 return; 10858 } 10859 10860 boolean dumpAll = false; 10861 boolean dumpClient = false; 10862 String dumpPackage = null; 10863 10864 int opti = 0; 10865 while (opti < args.length) { 10866 String opt = args[opti]; 10867 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10868 break; 10869 } 10870 opti++; 10871 if ("-a".equals(opt)) { 10872 dumpAll = true; 10873 } else if ("-c".equals(opt)) { 10874 dumpClient = true; 10875 } else if ("-h".equals(opt)) { 10876 pw.println("Activity manager dump options:"); 10877 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10878 pw.println(" cmd may be one of:"); 10879 pw.println(" a[ctivities]: activity stack state"); 10880 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10881 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10882 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10883 pw.println(" o[om]: out of memory management"); 10884 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10885 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10886 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10887 pw.println(" service [COMP_SPEC]: service client-side state"); 10888 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10889 pw.println(" all: dump all activities"); 10890 pw.println(" top: dump the top activity"); 10891 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10892 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10893 pw.println(" a partial substring in a component name, a"); 10894 pw.println(" hex object identifier."); 10895 pw.println(" -a: include all available server state."); 10896 pw.println(" -c: include client state."); 10897 return; 10898 } else { 10899 pw.println("Unknown argument: " + opt + "; use -h for help"); 10900 } 10901 } 10902 10903 long origId = Binder.clearCallingIdentity(); 10904 boolean more = false; 10905 // Is the caller requesting to dump a particular piece of data? 10906 if (opti < args.length) { 10907 String cmd = args[opti]; 10908 opti++; 10909 if ("activities".equals(cmd) || "a".equals(cmd)) { 10910 synchronized (this) { 10911 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10912 } 10913 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10914 String[] newArgs; 10915 String name; 10916 if (opti >= args.length) { 10917 name = null; 10918 newArgs = EMPTY_STRING_ARRAY; 10919 } else { 10920 name = args[opti]; 10921 opti++; 10922 newArgs = new String[args.length - opti]; 10923 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10924 args.length - opti); 10925 } 10926 synchronized (this) { 10927 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10928 } 10929 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10930 String[] newArgs; 10931 String name; 10932 if (opti >= args.length) { 10933 name = null; 10934 newArgs = EMPTY_STRING_ARRAY; 10935 } else { 10936 name = args[opti]; 10937 opti++; 10938 newArgs = new String[args.length - opti]; 10939 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10940 args.length - opti); 10941 } 10942 synchronized (this) { 10943 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10944 } 10945 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10946 String[] newArgs; 10947 String name; 10948 if (opti >= args.length) { 10949 name = null; 10950 newArgs = EMPTY_STRING_ARRAY; 10951 } else { 10952 name = args[opti]; 10953 opti++; 10954 newArgs = new String[args.length - opti]; 10955 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10956 args.length - opti); 10957 } 10958 synchronized (this) { 10959 dumpProcessesLocked(fd, pw, args, opti, true, name); 10960 } 10961 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10962 synchronized (this) { 10963 dumpOomLocked(fd, pw, args, opti, true); 10964 } 10965 } else if ("provider".equals(cmd)) { 10966 String[] newArgs; 10967 String name; 10968 if (opti >= args.length) { 10969 name = null; 10970 newArgs = EMPTY_STRING_ARRAY; 10971 } else { 10972 name = args[opti]; 10973 opti++; 10974 newArgs = new String[args.length - opti]; 10975 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10976 } 10977 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10978 pw.println("No providers match: " + name); 10979 pw.println("Use -h for help."); 10980 } 10981 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10982 synchronized (this) { 10983 dumpProvidersLocked(fd, pw, args, opti, true, null); 10984 } 10985 } else if ("service".equals(cmd)) { 10986 String[] newArgs; 10987 String name; 10988 if (opti >= args.length) { 10989 name = null; 10990 newArgs = EMPTY_STRING_ARRAY; 10991 } else { 10992 name = args[opti]; 10993 opti++; 10994 newArgs = new String[args.length - opti]; 10995 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10996 args.length - opti); 10997 } 10998 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10999 pw.println("No services match: " + name); 11000 pw.println("Use -h for help."); 11001 } 11002 } else if ("package".equals(cmd)) { 11003 String[] newArgs; 11004 if (opti >= args.length) { 11005 pw.println("package: no package name specified"); 11006 pw.println("Use -h for help."); 11007 } else { 11008 dumpPackage = args[opti]; 11009 opti++; 11010 newArgs = new String[args.length - opti]; 11011 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11012 args.length - opti); 11013 args = newArgs; 11014 opti = 0; 11015 more = true; 11016 } 11017 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11018 synchronized (this) { 11019 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11020 } 11021 } else { 11022 // Dumping a single activity? 11023 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11024 pw.println("Bad activity command, or no activities match: " + cmd); 11025 pw.println("Use -h for help."); 11026 } 11027 } 11028 if (!more) { 11029 Binder.restoreCallingIdentity(origId); 11030 return; 11031 } 11032 } 11033 11034 // No piece of data specified, dump everything. 11035 synchronized (this) { 11036 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11037 pw.println(); 11038 if (dumpAll) { 11039 pw.println("-------------------------------------------------------------------------------"); 11040 } 11041 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11042 pw.println(); 11043 if (dumpAll) { 11044 pw.println("-------------------------------------------------------------------------------"); 11045 } 11046 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11047 pw.println(); 11048 if (dumpAll) { 11049 pw.println("-------------------------------------------------------------------------------"); 11050 } 11051 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11052 pw.println(); 11053 if (dumpAll) { 11054 pw.println("-------------------------------------------------------------------------------"); 11055 } 11056 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11057 pw.println(); 11058 if (dumpAll) { 11059 pw.println("-------------------------------------------------------------------------------"); 11060 } 11061 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11062 } 11063 Binder.restoreCallingIdentity(origId); 11064 } 11065 11066 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11067 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11068 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11069 11070 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11071 dumpPackage); 11072 boolean needSep = printedAnything; 11073 11074 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11075 dumpPackage, needSep, " mFocusedActivity: "); 11076 if (printed) { 11077 printedAnything = true; 11078 needSep = false; 11079 } 11080 11081 if (dumpPackage == null) { 11082 if (needSep) { 11083 pw.println(); 11084 } 11085 needSep = true; 11086 printedAnything = true; 11087 mStackSupervisor.dump(pw, " "); 11088 } 11089 11090 if (mRecentTasks.size() > 0) { 11091 boolean printedHeader = false; 11092 11093 final int N = mRecentTasks.size(); 11094 for (int i=0; i<N; i++) { 11095 TaskRecord tr = mRecentTasks.get(i); 11096 if (dumpPackage != null) { 11097 if (tr.realActivity == null || 11098 !dumpPackage.equals(tr.realActivity)) { 11099 continue; 11100 } 11101 } 11102 if (!printedHeader) { 11103 if (needSep) { 11104 pw.println(); 11105 } 11106 pw.println(" Recent tasks:"); 11107 printedHeader = true; 11108 printedAnything = true; 11109 } 11110 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11111 pw.println(tr); 11112 if (dumpAll) { 11113 mRecentTasks.get(i).dump(pw, " "); 11114 } 11115 } 11116 } 11117 11118 if (!printedAnything) { 11119 pw.println(" (nothing)"); 11120 } 11121 } 11122 11123 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11124 int opti, boolean dumpAll, String dumpPackage) { 11125 boolean needSep = false; 11126 boolean printedAnything = false; 11127 int numPers = 0; 11128 11129 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11130 11131 if (dumpAll) { 11132 final int NP = mProcessNames.getMap().size(); 11133 for (int ip=0; ip<NP; ip++) { 11134 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11135 final int NA = procs.size(); 11136 for (int ia=0; ia<NA; ia++) { 11137 ProcessRecord r = procs.valueAt(ia); 11138 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11139 continue; 11140 } 11141 if (!needSep) { 11142 pw.println(" All known processes:"); 11143 needSep = true; 11144 printedAnything = true; 11145 } 11146 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11147 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11148 pw.print(" "); pw.println(r); 11149 r.dump(pw, " "); 11150 if (r.persistent) { 11151 numPers++; 11152 } 11153 } 11154 } 11155 } 11156 11157 if (mIsolatedProcesses.size() > 0) { 11158 boolean printed = false; 11159 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11160 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11161 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11162 continue; 11163 } 11164 if (!printed) { 11165 if (needSep) { 11166 pw.println(); 11167 } 11168 pw.println(" Isolated process list (sorted by uid):"); 11169 printedAnything = true; 11170 printed = true; 11171 needSep = true; 11172 } 11173 pw.println(String.format("%sIsolated #%2d: %s", 11174 " ", i, r.toString())); 11175 } 11176 } 11177 11178 if (mLruProcesses.size() > 0) { 11179 if (needSep) { 11180 pw.println(); 11181 } 11182 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11183 pw.print(" total, non-act at "); 11184 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11185 pw.print(", non-svc at "); 11186 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11187 pw.println("):"); 11188 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11189 needSep = true; 11190 printedAnything = true; 11191 } 11192 11193 if (dumpAll || dumpPackage != null) { 11194 synchronized (mPidsSelfLocked) { 11195 boolean printed = false; 11196 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11197 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11198 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11199 continue; 11200 } 11201 if (!printed) { 11202 if (needSep) pw.println(); 11203 needSep = true; 11204 pw.println(" PID mappings:"); 11205 printed = true; 11206 printedAnything = true; 11207 } 11208 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11209 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11210 } 11211 } 11212 } 11213 11214 if (mForegroundProcesses.size() > 0) { 11215 synchronized (mPidsSelfLocked) { 11216 boolean printed = false; 11217 for (int i=0; i<mForegroundProcesses.size(); i++) { 11218 ProcessRecord r = mPidsSelfLocked.get( 11219 mForegroundProcesses.valueAt(i).pid); 11220 if (dumpPackage != null && (r == null 11221 || !r.pkgList.containsKey(dumpPackage))) { 11222 continue; 11223 } 11224 if (!printed) { 11225 if (needSep) pw.println(); 11226 needSep = true; 11227 pw.println(" Foreground Processes:"); 11228 printed = true; 11229 printedAnything = true; 11230 } 11231 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11232 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11233 } 11234 } 11235 } 11236 11237 if (mPersistentStartingProcesses.size() > 0) { 11238 if (needSep) pw.println(); 11239 needSep = true; 11240 printedAnything = true; 11241 pw.println(" Persisent processes that are starting:"); 11242 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11243 "Starting Norm", "Restarting PERS", dumpPackage); 11244 } 11245 11246 if (mRemovedProcesses.size() > 0) { 11247 if (needSep) pw.println(); 11248 needSep = true; 11249 printedAnything = true; 11250 pw.println(" Processes that are being removed:"); 11251 dumpProcessList(pw, this, mRemovedProcesses, " ", 11252 "Removed Norm", "Removed PERS", dumpPackage); 11253 } 11254 11255 if (mProcessesOnHold.size() > 0) { 11256 if (needSep) pw.println(); 11257 needSep = true; 11258 printedAnything = true; 11259 pw.println(" Processes that are on old until the system is ready:"); 11260 dumpProcessList(pw, this, mProcessesOnHold, " ", 11261 "OnHold Norm", "OnHold PERS", dumpPackage); 11262 } 11263 11264 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11265 11266 if (mProcessCrashTimes.getMap().size() > 0) { 11267 boolean printed = false; 11268 long now = SystemClock.uptimeMillis(); 11269 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11270 final int NP = pmap.size(); 11271 for (int ip=0; ip<NP; ip++) { 11272 String pname = pmap.keyAt(ip); 11273 SparseArray<Long> uids = pmap.valueAt(ip); 11274 final int N = uids.size(); 11275 for (int i=0; i<N; i++) { 11276 int puid = uids.keyAt(i); 11277 ProcessRecord r = mProcessNames.get(pname, puid); 11278 if (dumpPackage != null && (r == null 11279 || !r.pkgList.containsKey(dumpPackage))) { 11280 continue; 11281 } 11282 if (!printed) { 11283 if (needSep) pw.println(); 11284 needSep = true; 11285 pw.println(" Time since processes crashed:"); 11286 printed = true; 11287 printedAnything = true; 11288 } 11289 pw.print(" Process "); pw.print(pname); 11290 pw.print(" uid "); pw.print(puid); 11291 pw.print(": last crashed "); 11292 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11293 pw.println(" ago"); 11294 } 11295 } 11296 } 11297 11298 if (mBadProcesses.getMap().size() > 0) { 11299 boolean printed = false; 11300 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11301 final int NP = pmap.size(); 11302 for (int ip=0; ip<NP; ip++) { 11303 String pname = pmap.keyAt(ip); 11304 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11305 final int N = uids.size(); 11306 for (int i=0; i<N; i++) { 11307 int puid = uids.keyAt(i); 11308 ProcessRecord r = mProcessNames.get(pname, puid); 11309 if (dumpPackage != null && (r == null 11310 || !r.pkgList.containsKey(dumpPackage))) { 11311 continue; 11312 } 11313 if (!printed) { 11314 if (needSep) pw.println(); 11315 needSep = true; 11316 pw.println(" Bad processes:"); 11317 printedAnything = true; 11318 } 11319 BadProcessInfo info = uids.valueAt(i); 11320 pw.print(" Bad process "); pw.print(pname); 11321 pw.print(" uid "); pw.print(puid); 11322 pw.print(": crashed at time "); pw.println(info.time); 11323 if (info.shortMsg != null) { 11324 pw.print(" Short msg: "); pw.println(info.shortMsg); 11325 } 11326 if (info.longMsg != null) { 11327 pw.print(" Long msg: "); pw.println(info.longMsg); 11328 } 11329 if (info.stack != null) { 11330 pw.println(" Stack:"); 11331 int lastPos = 0; 11332 for (int pos=0; pos<info.stack.length(); pos++) { 11333 if (info.stack.charAt(pos) == '\n') { 11334 pw.print(" "); 11335 pw.write(info.stack, lastPos, pos-lastPos); 11336 pw.println(); 11337 lastPos = pos+1; 11338 } 11339 } 11340 if (lastPos < info.stack.length()) { 11341 pw.print(" "); 11342 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11343 pw.println(); 11344 } 11345 } 11346 } 11347 } 11348 } 11349 11350 if (dumpPackage == null) { 11351 pw.println(); 11352 needSep = false; 11353 pw.println(" mStartedUsers:"); 11354 for (int i=0; i<mStartedUsers.size(); i++) { 11355 UserStartedState uss = mStartedUsers.valueAt(i); 11356 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11357 pw.print(": "); uss.dump("", pw); 11358 } 11359 pw.print(" mStartedUserArray: ["); 11360 for (int i=0; i<mStartedUserArray.length; i++) { 11361 if (i > 0) pw.print(", "); 11362 pw.print(mStartedUserArray[i]); 11363 } 11364 pw.println("]"); 11365 pw.print(" mUserLru: ["); 11366 for (int i=0; i<mUserLru.size(); i++) { 11367 if (i > 0) pw.print(", "); 11368 pw.print(mUserLru.get(i)); 11369 } 11370 pw.println("]"); 11371 if (dumpAll) { 11372 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11373 } 11374 } 11375 if (mHomeProcess != null && (dumpPackage == null 11376 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11377 if (needSep) { 11378 pw.println(); 11379 needSep = false; 11380 } 11381 pw.println(" mHomeProcess: " + mHomeProcess); 11382 } 11383 if (mPreviousProcess != null && (dumpPackage == null 11384 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11385 if (needSep) { 11386 pw.println(); 11387 needSep = false; 11388 } 11389 pw.println(" mPreviousProcess: " + mPreviousProcess); 11390 } 11391 if (dumpAll) { 11392 StringBuilder sb = new StringBuilder(128); 11393 sb.append(" mPreviousProcessVisibleTime: "); 11394 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11395 pw.println(sb); 11396 } 11397 if (mHeavyWeightProcess != null && (dumpPackage == null 11398 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11399 if (needSep) { 11400 pw.println(); 11401 needSep = false; 11402 } 11403 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11404 } 11405 if (dumpPackage == null) { 11406 pw.println(" mConfiguration: " + mConfiguration); 11407 } 11408 if (dumpAll) { 11409 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11410 if (mCompatModePackages.getPackages().size() > 0) { 11411 boolean printed = false; 11412 for (Map.Entry<String, Integer> entry 11413 : mCompatModePackages.getPackages().entrySet()) { 11414 String pkg = entry.getKey(); 11415 int mode = entry.getValue(); 11416 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11417 continue; 11418 } 11419 if (!printed) { 11420 pw.println(" mScreenCompatPackages:"); 11421 printed = true; 11422 } 11423 pw.print(" "); pw.print(pkg); pw.print(": "); 11424 pw.print(mode); pw.println(); 11425 } 11426 } 11427 } 11428 if (dumpPackage == null) { 11429 if (mSleeping || mWentToSleep || mLockScreenShown) { 11430 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11431 + " mLockScreenShown " + mLockScreenShown); 11432 } 11433 if (mShuttingDown || mRunningVoice) { 11434 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11435 } 11436 } 11437 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11438 || mOrigWaitForDebugger) { 11439 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11440 || dumpPackage.equals(mOrigDebugApp)) { 11441 if (needSep) { 11442 pw.println(); 11443 needSep = false; 11444 } 11445 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11446 + " mDebugTransient=" + mDebugTransient 11447 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11448 } 11449 } 11450 if (mOpenGlTraceApp != null) { 11451 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11452 if (needSep) { 11453 pw.println(); 11454 needSep = false; 11455 } 11456 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11457 } 11458 } 11459 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11460 || mProfileFd != null) { 11461 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11462 if (needSep) { 11463 pw.println(); 11464 needSep = false; 11465 } 11466 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11467 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11468 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11469 + mAutoStopProfiler); 11470 } 11471 } 11472 if (dumpPackage == null) { 11473 if (mAlwaysFinishActivities || mController != null) { 11474 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11475 + " mController=" + mController); 11476 } 11477 if (dumpAll) { 11478 pw.println(" Total persistent processes: " + numPers); 11479 pw.println(" mProcessesReady=" + mProcessesReady 11480 + " mSystemReady=" + mSystemReady); 11481 pw.println(" mBooting=" + mBooting 11482 + " mBooted=" + mBooted 11483 + " mFactoryTest=" + mFactoryTest); 11484 pw.print(" mLastPowerCheckRealtime="); 11485 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11486 pw.println(""); 11487 pw.print(" mLastPowerCheckUptime="); 11488 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11489 pw.println(""); 11490 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11491 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11492 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11493 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11494 + " (" + mLruProcesses.size() + " total)" 11495 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11496 + " mNumServiceProcs=" + mNumServiceProcs 11497 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11498 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11499 + " mLastMemoryLevel" + mLastMemoryLevel 11500 + " mLastNumProcesses" + mLastNumProcesses); 11501 long now = SystemClock.uptimeMillis(); 11502 pw.print(" mLastIdleTime="); 11503 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11504 pw.print(" mLowRamSinceLastIdle="); 11505 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11506 pw.println(); 11507 } 11508 } 11509 11510 if (!printedAnything) { 11511 pw.println(" (nothing)"); 11512 } 11513 } 11514 11515 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11516 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11517 if (mProcessesToGc.size() > 0) { 11518 boolean printed = false; 11519 long now = SystemClock.uptimeMillis(); 11520 for (int i=0; i<mProcessesToGc.size(); i++) { 11521 ProcessRecord proc = mProcessesToGc.get(i); 11522 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11523 continue; 11524 } 11525 if (!printed) { 11526 if (needSep) pw.println(); 11527 needSep = true; 11528 pw.println(" Processes that are waiting to GC:"); 11529 printed = true; 11530 } 11531 pw.print(" Process "); pw.println(proc); 11532 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11533 pw.print(", last gced="); 11534 pw.print(now-proc.lastRequestedGc); 11535 pw.print(" ms ago, last lowMem="); 11536 pw.print(now-proc.lastLowMemory); 11537 pw.println(" ms ago"); 11538 11539 } 11540 } 11541 return needSep; 11542 } 11543 11544 void printOomLevel(PrintWriter pw, String name, int adj) { 11545 pw.print(" "); 11546 if (adj >= 0) { 11547 pw.print(' '); 11548 if (adj < 10) pw.print(' '); 11549 } else { 11550 if (adj > -10) pw.print(' '); 11551 } 11552 pw.print(adj); 11553 pw.print(": "); 11554 pw.print(name); 11555 pw.print(" ("); 11556 pw.print(mProcessList.getMemLevel(adj)/1024); 11557 pw.println(" kB)"); 11558 } 11559 11560 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11561 int opti, boolean dumpAll) { 11562 boolean needSep = false; 11563 11564 if (mLruProcesses.size() > 0) { 11565 if (needSep) pw.println(); 11566 needSep = true; 11567 pw.println(" OOM levels:"); 11568 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11569 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11570 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11571 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11572 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11573 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11574 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11575 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11576 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11577 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11578 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11579 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11580 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11581 11582 if (needSep) pw.println(); 11583 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11584 pw.print(" total, non-act at "); 11585 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11586 pw.print(", non-svc at "); 11587 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11588 pw.println("):"); 11589 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11590 needSep = true; 11591 } 11592 11593 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11594 11595 pw.println(); 11596 pw.println(" mHomeProcess: " + mHomeProcess); 11597 pw.println(" mPreviousProcess: " + mPreviousProcess); 11598 if (mHeavyWeightProcess != null) { 11599 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11600 } 11601 11602 return true; 11603 } 11604 11605 /** 11606 * There are three ways to call this: 11607 * - no provider specified: dump all the providers 11608 * - a flattened component name that matched an existing provider was specified as the 11609 * first arg: dump that one provider 11610 * - the first arg isn't the flattened component name of an existing provider: 11611 * dump all providers whose component contains the first arg as a substring 11612 */ 11613 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11614 int opti, boolean dumpAll) { 11615 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11616 } 11617 11618 static class ItemMatcher { 11619 ArrayList<ComponentName> components; 11620 ArrayList<String> strings; 11621 ArrayList<Integer> objects; 11622 boolean all; 11623 11624 ItemMatcher() { 11625 all = true; 11626 } 11627 11628 void build(String name) { 11629 ComponentName componentName = ComponentName.unflattenFromString(name); 11630 if (componentName != null) { 11631 if (components == null) { 11632 components = new ArrayList<ComponentName>(); 11633 } 11634 components.add(componentName); 11635 all = false; 11636 } else { 11637 int objectId = 0; 11638 // Not a '/' separated full component name; maybe an object ID? 11639 try { 11640 objectId = Integer.parseInt(name, 16); 11641 if (objects == null) { 11642 objects = new ArrayList<Integer>(); 11643 } 11644 objects.add(objectId); 11645 all = false; 11646 } catch (RuntimeException e) { 11647 // Not an integer; just do string match. 11648 if (strings == null) { 11649 strings = new ArrayList<String>(); 11650 } 11651 strings.add(name); 11652 all = false; 11653 } 11654 } 11655 } 11656 11657 int build(String[] args, int opti) { 11658 for (; opti<args.length; opti++) { 11659 String name = args[opti]; 11660 if ("--".equals(name)) { 11661 return opti+1; 11662 } 11663 build(name); 11664 } 11665 return opti; 11666 } 11667 11668 boolean match(Object object, ComponentName comp) { 11669 if (all) { 11670 return true; 11671 } 11672 if (components != null) { 11673 for (int i=0; i<components.size(); i++) { 11674 if (components.get(i).equals(comp)) { 11675 return true; 11676 } 11677 } 11678 } 11679 if (objects != null) { 11680 for (int i=0; i<objects.size(); i++) { 11681 if (System.identityHashCode(object) == objects.get(i)) { 11682 return true; 11683 } 11684 } 11685 } 11686 if (strings != null) { 11687 String flat = comp.flattenToString(); 11688 for (int i=0; i<strings.size(); i++) { 11689 if (flat.contains(strings.get(i))) { 11690 return true; 11691 } 11692 } 11693 } 11694 return false; 11695 } 11696 } 11697 11698 /** 11699 * There are three things that cmd can be: 11700 * - a flattened component name that matches an existing activity 11701 * - the cmd arg isn't the flattened component name of an existing activity: 11702 * dump all activity whose component contains the cmd as a substring 11703 * - A hex number of the ActivityRecord object instance. 11704 */ 11705 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11706 int opti, boolean dumpAll) { 11707 ArrayList<ActivityRecord> activities; 11708 11709 synchronized (this) { 11710 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11711 } 11712 11713 if (activities.size() <= 0) { 11714 return false; 11715 } 11716 11717 String[] newArgs = new String[args.length - opti]; 11718 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11719 11720 TaskRecord lastTask = null; 11721 boolean needSep = false; 11722 for (int i=activities.size()-1; i>=0; i--) { 11723 ActivityRecord r = activities.get(i); 11724 if (needSep) { 11725 pw.println(); 11726 } 11727 needSep = true; 11728 synchronized (this) { 11729 if (lastTask != r.task) { 11730 lastTask = r.task; 11731 pw.print("TASK "); pw.print(lastTask.affinity); 11732 pw.print(" id="); pw.println(lastTask.taskId); 11733 if (dumpAll) { 11734 lastTask.dump(pw, " "); 11735 } 11736 } 11737 } 11738 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11739 } 11740 return true; 11741 } 11742 11743 /** 11744 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11745 * there is a thread associated with the activity. 11746 */ 11747 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11748 final ActivityRecord r, String[] args, boolean dumpAll) { 11749 String innerPrefix = prefix + " "; 11750 synchronized (this) { 11751 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11752 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11753 pw.print(" pid="); 11754 if (r.app != null) pw.println(r.app.pid); 11755 else pw.println("(not running)"); 11756 if (dumpAll) { 11757 r.dump(pw, innerPrefix); 11758 } 11759 } 11760 if (r.app != null && r.app.thread != null) { 11761 // flush anything that is already in the PrintWriter since the thread is going 11762 // to write to the file descriptor directly 11763 pw.flush(); 11764 try { 11765 TransferPipe tp = new TransferPipe(); 11766 try { 11767 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11768 r.appToken, innerPrefix, args); 11769 tp.go(fd); 11770 } finally { 11771 tp.kill(); 11772 } 11773 } catch (IOException e) { 11774 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11775 } catch (RemoteException e) { 11776 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11777 } 11778 } 11779 } 11780 11781 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11782 int opti, boolean dumpAll, String dumpPackage) { 11783 boolean needSep = false; 11784 boolean onlyHistory = false; 11785 boolean printedAnything = false; 11786 11787 if ("history".equals(dumpPackage)) { 11788 if (opti < args.length && "-s".equals(args[opti])) { 11789 dumpAll = false; 11790 } 11791 onlyHistory = true; 11792 dumpPackage = null; 11793 } 11794 11795 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11796 if (!onlyHistory && dumpAll) { 11797 if (mRegisteredReceivers.size() > 0) { 11798 boolean printed = false; 11799 Iterator it = mRegisteredReceivers.values().iterator(); 11800 while (it.hasNext()) { 11801 ReceiverList r = (ReceiverList)it.next(); 11802 if (dumpPackage != null && (r.app == null || 11803 !dumpPackage.equals(r.app.info.packageName))) { 11804 continue; 11805 } 11806 if (!printed) { 11807 pw.println(" Registered Receivers:"); 11808 needSep = true; 11809 printed = true; 11810 printedAnything = true; 11811 } 11812 pw.print(" * "); pw.println(r); 11813 r.dump(pw, " "); 11814 } 11815 } 11816 11817 if (mReceiverResolver.dump(pw, needSep ? 11818 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11819 " ", dumpPackage, false)) { 11820 needSep = true; 11821 printedAnything = true; 11822 } 11823 } 11824 11825 for (BroadcastQueue q : mBroadcastQueues) { 11826 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11827 printedAnything |= needSep; 11828 } 11829 11830 needSep = true; 11831 11832 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11833 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11834 if (needSep) { 11835 pw.println(); 11836 } 11837 needSep = true; 11838 printedAnything = true; 11839 pw.print(" Sticky broadcasts for user "); 11840 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11841 StringBuilder sb = new StringBuilder(128); 11842 for (Map.Entry<String, ArrayList<Intent>> ent 11843 : mStickyBroadcasts.valueAt(user).entrySet()) { 11844 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11845 if (dumpAll) { 11846 pw.println(":"); 11847 ArrayList<Intent> intents = ent.getValue(); 11848 final int N = intents.size(); 11849 for (int i=0; i<N; i++) { 11850 sb.setLength(0); 11851 sb.append(" Intent: "); 11852 intents.get(i).toShortString(sb, false, true, false, false); 11853 pw.println(sb.toString()); 11854 Bundle bundle = intents.get(i).getExtras(); 11855 if (bundle != null) { 11856 pw.print(" "); 11857 pw.println(bundle.toString()); 11858 } 11859 } 11860 } else { 11861 pw.println(""); 11862 } 11863 } 11864 } 11865 } 11866 11867 if (!onlyHistory && dumpAll) { 11868 pw.println(); 11869 for (BroadcastQueue queue : mBroadcastQueues) { 11870 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11871 + queue.mBroadcastsScheduled); 11872 } 11873 pw.println(" mHandler:"); 11874 mHandler.dump(new PrintWriterPrinter(pw), " "); 11875 needSep = true; 11876 printedAnything = true; 11877 } 11878 11879 if (!printedAnything) { 11880 pw.println(" (nothing)"); 11881 } 11882 } 11883 11884 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11885 int opti, boolean dumpAll, String dumpPackage) { 11886 boolean needSep; 11887 boolean printedAnything = false; 11888 11889 ItemMatcher matcher = new ItemMatcher(); 11890 matcher.build(args, opti); 11891 11892 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11893 11894 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11895 printedAnything |= needSep; 11896 11897 if (mLaunchingProviders.size() > 0) { 11898 boolean printed = false; 11899 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11900 ContentProviderRecord r = mLaunchingProviders.get(i); 11901 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11902 continue; 11903 } 11904 if (!printed) { 11905 if (needSep) pw.println(); 11906 needSep = true; 11907 pw.println(" Launching content providers:"); 11908 printed = true; 11909 printedAnything = true; 11910 } 11911 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11912 pw.println(r); 11913 } 11914 } 11915 11916 if (mGrantedUriPermissions.size() > 0) { 11917 boolean printed = false; 11918 int dumpUid = -2; 11919 if (dumpPackage != null) { 11920 try { 11921 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11922 } catch (NameNotFoundException e) { 11923 dumpUid = -1; 11924 } 11925 } 11926 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11927 int uid = mGrantedUriPermissions.keyAt(i); 11928 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11929 continue; 11930 } 11931 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11932 if (!printed) { 11933 if (needSep) pw.println(); 11934 needSep = true; 11935 pw.println(" Granted Uri Permissions:"); 11936 printed = true; 11937 printedAnything = true; 11938 } 11939 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11940 for (UriPermission perm : perms.values()) { 11941 pw.print(" "); pw.println(perm); 11942 if (dumpAll) { 11943 perm.dump(pw, " "); 11944 } 11945 } 11946 } 11947 } 11948 11949 if (!printedAnything) { 11950 pw.println(" (nothing)"); 11951 } 11952 } 11953 11954 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11955 int opti, boolean dumpAll, String dumpPackage) { 11956 boolean printed = false; 11957 11958 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11959 11960 if (mIntentSenderRecords.size() > 0) { 11961 Iterator<WeakReference<PendingIntentRecord>> it 11962 = mIntentSenderRecords.values().iterator(); 11963 while (it.hasNext()) { 11964 WeakReference<PendingIntentRecord> ref = it.next(); 11965 PendingIntentRecord rec = ref != null ? ref.get(): null; 11966 if (dumpPackage != null && (rec == null 11967 || !dumpPackage.equals(rec.key.packageName))) { 11968 continue; 11969 } 11970 printed = true; 11971 if (rec != null) { 11972 pw.print(" * "); pw.println(rec); 11973 if (dumpAll) { 11974 rec.dump(pw, " "); 11975 } 11976 } else { 11977 pw.print(" * "); pw.println(ref); 11978 } 11979 } 11980 } 11981 11982 if (!printed) { 11983 pw.println(" (nothing)"); 11984 } 11985 } 11986 11987 private static final int dumpProcessList(PrintWriter pw, 11988 ActivityManagerService service, List list, 11989 String prefix, String normalLabel, String persistentLabel, 11990 String dumpPackage) { 11991 int numPers = 0; 11992 final int N = list.size()-1; 11993 for (int i=N; i>=0; i--) { 11994 ProcessRecord r = (ProcessRecord)list.get(i); 11995 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11996 continue; 11997 } 11998 pw.println(String.format("%s%s #%2d: %s", 11999 prefix, (r.persistent ? persistentLabel : normalLabel), 12000 i, r.toString())); 12001 if (r.persistent) { 12002 numPers++; 12003 } 12004 } 12005 return numPers; 12006 } 12007 12008 private static final boolean dumpProcessOomList(PrintWriter pw, 12009 ActivityManagerService service, List<ProcessRecord> origList, 12010 String prefix, String normalLabel, String persistentLabel, 12011 boolean inclDetails, String dumpPackage) { 12012 12013 ArrayList<Pair<ProcessRecord, Integer>> list 12014 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12015 for (int i=0; i<origList.size(); i++) { 12016 ProcessRecord r = origList.get(i); 12017 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12018 continue; 12019 } 12020 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12021 } 12022 12023 if (list.size() <= 0) { 12024 return false; 12025 } 12026 12027 Comparator<Pair<ProcessRecord, Integer>> comparator 12028 = new Comparator<Pair<ProcessRecord, Integer>>() { 12029 @Override 12030 public int compare(Pair<ProcessRecord, Integer> object1, 12031 Pair<ProcessRecord, Integer> object2) { 12032 if (object1.first.setAdj != object2.first.setAdj) { 12033 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12034 } 12035 if (object1.second.intValue() != object2.second.intValue()) { 12036 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12037 } 12038 return 0; 12039 } 12040 }; 12041 12042 Collections.sort(list, comparator); 12043 12044 final long curRealtime = SystemClock.elapsedRealtime(); 12045 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12046 final long curUptime = SystemClock.uptimeMillis(); 12047 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12048 12049 for (int i=list.size()-1; i>=0; i--) { 12050 ProcessRecord r = list.get(i).first; 12051 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12052 char schedGroup; 12053 switch (r.setSchedGroup) { 12054 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12055 schedGroup = 'B'; 12056 break; 12057 case Process.THREAD_GROUP_DEFAULT: 12058 schedGroup = 'F'; 12059 break; 12060 default: 12061 schedGroup = '?'; 12062 break; 12063 } 12064 char foreground; 12065 if (r.foregroundActivities) { 12066 foreground = 'A'; 12067 } else if (r.foregroundServices) { 12068 foreground = 'S'; 12069 } else { 12070 foreground = ' '; 12071 } 12072 String procState = ProcessList.makeProcStateString(r.curProcState); 12073 pw.print(prefix); 12074 pw.print(r.persistent ? persistentLabel : normalLabel); 12075 pw.print(" #"); 12076 int num = (origList.size()-1)-list.get(i).second; 12077 if (num < 10) pw.print(' '); 12078 pw.print(num); 12079 pw.print(": "); 12080 pw.print(oomAdj); 12081 pw.print(' '); 12082 pw.print(schedGroup); 12083 pw.print('/'); 12084 pw.print(foreground); 12085 pw.print('/'); 12086 pw.print(procState); 12087 pw.print(" trm:"); 12088 if (r.trimMemoryLevel < 10) pw.print(' '); 12089 pw.print(r.trimMemoryLevel); 12090 pw.print(' '); 12091 pw.print(r.toShortString()); 12092 pw.print(" ("); 12093 pw.print(r.adjType); 12094 pw.println(')'); 12095 if (r.adjSource != null || r.adjTarget != null) { 12096 pw.print(prefix); 12097 pw.print(" "); 12098 if (r.adjTarget instanceof ComponentName) { 12099 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12100 } else if (r.adjTarget != null) { 12101 pw.print(r.adjTarget.toString()); 12102 } else { 12103 pw.print("{null}"); 12104 } 12105 pw.print("<="); 12106 if (r.adjSource instanceof ProcessRecord) { 12107 pw.print("Proc{"); 12108 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12109 pw.println("}"); 12110 } else if (r.adjSource != null) { 12111 pw.println(r.adjSource.toString()); 12112 } else { 12113 pw.println("{null}"); 12114 } 12115 } 12116 if (inclDetails) { 12117 pw.print(prefix); 12118 pw.print(" "); 12119 pw.print("oom: max="); pw.print(r.maxAdj); 12120 pw.print(" curRaw="); pw.print(r.curRawAdj); 12121 pw.print(" setRaw="); pw.print(r.setRawAdj); 12122 pw.print(" cur="); pw.print(r.curAdj); 12123 pw.print(" set="); pw.println(r.setAdj); 12124 pw.print(prefix); 12125 pw.print(" "); 12126 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12127 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12128 pw.print(" lastPss="); pw.print(r.lastPss); 12129 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12130 pw.print(prefix); 12131 pw.print(" "); 12132 pw.print("keeping="); pw.print(r.keeping); 12133 pw.print(" cached="); pw.print(r.cached); 12134 pw.print(" empty="); pw.print(r.empty); 12135 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12136 12137 if (!r.keeping) { 12138 if (r.lastWakeTime != 0) { 12139 long wtime; 12140 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12141 synchronized (stats) { 12142 wtime = stats.getProcessWakeTime(r.info.uid, 12143 r.pid, curRealtime); 12144 } 12145 long timeUsed = wtime - r.lastWakeTime; 12146 pw.print(prefix); 12147 pw.print(" "); 12148 pw.print("keep awake over "); 12149 TimeUtils.formatDuration(realtimeSince, pw); 12150 pw.print(" used "); 12151 TimeUtils.formatDuration(timeUsed, pw); 12152 pw.print(" ("); 12153 pw.print((timeUsed*100)/realtimeSince); 12154 pw.println("%)"); 12155 } 12156 if (r.lastCpuTime != 0) { 12157 long timeUsed = r.curCpuTime - r.lastCpuTime; 12158 pw.print(prefix); 12159 pw.print(" "); 12160 pw.print("run cpu over "); 12161 TimeUtils.formatDuration(uptimeSince, pw); 12162 pw.print(" used "); 12163 TimeUtils.formatDuration(timeUsed, pw); 12164 pw.print(" ("); 12165 pw.print((timeUsed*100)/uptimeSince); 12166 pw.println("%)"); 12167 } 12168 } 12169 } 12170 } 12171 return true; 12172 } 12173 12174 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12175 ArrayList<ProcessRecord> procs; 12176 synchronized (this) { 12177 if (args != null && args.length > start 12178 && args[start].charAt(0) != '-') { 12179 procs = new ArrayList<ProcessRecord>(); 12180 int pid = -1; 12181 try { 12182 pid = Integer.parseInt(args[start]); 12183 } catch (NumberFormatException e) { 12184 } 12185 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12186 ProcessRecord proc = mLruProcesses.get(i); 12187 if (proc.pid == pid) { 12188 procs.add(proc); 12189 } else if (proc.processName.equals(args[start])) { 12190 procs.add(proc); 12191 } 12192 } 12193 if (procs.size() <= 0) { 12194 return null; 12195 } 12196 } else { 12197 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12198 } 12199 } 12200 return procs; 12201 } 12202 12203 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12204 PrintWriter pw, String[] args) { 12205 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12206 if (procs == null) { 12207 pw.println("No process found for: " + args[0]); 12208 return; 12209 } 12210 12211 long uptime = SystemClock.uptimeMillis(); 12212 long realtime = SystemClock.elapsedRealtime(); 12213 pw.println("Applications Graphics Acceleration Info:"); 12214 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12215 12216 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12217 ProcessRecord r = procs.get(i); 12218 if (r.thread != null) { 12219 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12220 pw.flush(); 12221 try { 12222 TransferPipe tp = new TransferPipe(); 12223 try { 12224 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12225 tp.go(fd); 12226 } finally { 12227 tp.kill(); 12228 } 12229 } catch (IOException e) { 12230 pw.println("Failure while dumping the app: " + r); 12231 pw.flush(); 12232 } catch (RemoteException e) { 12233 pw.println("Got a RemoteException while dumping the app " + r); 12234 pw.flush(); 12235 } 12236 } 12237 } 12238 } 12239 12240 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12241 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12242 if (procs == null) { 12243 pw.println("No process found for: " + args[0]); 12244 return; 12245 } 12246 12247 pw.println("Applications Database Info:"); 12248 12249 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12250 ProcessRecord r = procs.get(i); 12251 if (r.thread != null) { 12252 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12253 pw.flush(); 12254 try { 12255 TransferPipe tp = new TransferPipe(); 12256 try { 12257 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12258 tp.go(fd); 12259 } finally { 12260 tp.kill(); 12261 } 12262 } catch (IOException e) { 12263 pw.println("Failure while dumping the app: " + r); 12264 pw.flush(); 12265 } catch (RemoteException e) { 12266 pw.println("Got a RemoteException while dumping the app " + r); 12267 pw.flush(); 12268 } 12269 } 12270 } 12271 } 12272 12273 final static class MemItem { 12274 final boolean isProc; 12275 final String label; 12276 final String shortLabel; 12277 final long pss; 12278 final int id; 12279 final boolean hasActivities; 12280 ArrayList<MemItem> subitems; 12281 12282 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12283 boolean _hasActivities) { 12284 isProc = true; 12285 label = _label; 12286 shortLabel = _shortLabel; 12287 pss = _pss; 12288 id = _id; 12289 hasActivities = _hasActivities; 12290 } 12291 12292 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12293 isProc = false; 12294 label = _label; 12295 shortLabel = _shortLabel; 12296 pss = _pss; 12297 id = _id; 12298 hasActivities = false; 12299 } 12300 } 12301 12302 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12303 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12304 if (sort && !isCompact) { 12305 Collections.sort(items, new Comparator<MemItem>() { 12306 @Override 12307 public int compare(MemItem lhs, MemItem rhs) { 12308 if (lhs.pss < rhs.pss) { 12309 return 1; 12310 } else if (lhs.pss > rhs.pss) { 12311 return -1; 12312 } 12313 return 0; 12314 } 12315 }); 12316 } 12317 12318 for (int i=0; i<items.size(); i++) { 12319 MemItem mi = items.get(i); 12320 if (!isCompact) { 12321 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12322 } else if (mi.isProc) { 12323 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12324 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12325 pw.println(mi.hasActivities ? ",a" : ",e"); 12326 } else { 12327 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12328 pw.println(mi.pss); 12329 } 12330 if (mi.subitems != null) { 12331 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12332 true, isCompact); 12333 } 12334 } 12335 } 12336 12337 // These are in KB. 12338 static final long[] DUMP_MEM_BUCKETS = new long[] { 12339 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12340 120*1024, 160*1024, 200*1024, 12341 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12342 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12343 }; 12344 12345 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12346 boolean stackLike) { 12347 int start = label.lastIndexOf('.'); 12348 if (start >= 0) start++; 12349 else start = 0; 12350 int end = label.length(); 12351 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12352 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12353 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12354 out.append(bucket); 12355 out.append(stackLike ? "MB." : "MB "); 12356 out.append(label, start, end); 12357 return; 12358 } 12359 } 12360 out.append(memKB/1024); 12361 out.append(stackLike ? "MB." : "MB "); 12362 out.append(label, start, end); 12363 } 12364 12365 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12366 ProcessList.NATIVE_ADJ, 12367 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12368 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12369 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12370 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12371 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12372 }; 12373 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12374 "Native", 12375 "System", "Persistent", "Foreground", 12376 "Visible", "Perceptible", 12377 "Heavy Weight", "Backup", 12378 "A Services", "Home", 12379 "Previous", "B Services", "Cached" 12380 }; 12381 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12382 "native", 12383 "sys", "pers", "fore", 12384 "vis", "percept", 12385 "heavy", "backup", 12386 "servicea", "home", 12387 "prev", "serviceb", "cached" 12388 }; 12389 12390 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12391 long realtime, boolean isCheckinRequest, boolean isCompact) { 12392 if (isCheckinRequest || isCompact) { 12393 // short checkin version 12394 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12395 } else { 12396 pw.println("Applications Memory Usage (kB):"); 12397 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12398 } 12399 } 12400 12401 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12402 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12403 boolean dumpDetails = false; 12404 boolean dumpFullDetails = false; 12405 boolean dumpDalvik = false; 12406 boolean oomOnly = false; 12407 boolean isCompact = false; 12408 boolean localOnly = false; 12409 12410 int opti = 0; 12411 while (opti < args.length) { 12412 String opt = args[opti]; 12413 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12414 break; 12415 } 12416 opti++; 12417 if ("-a".equals(opt)) { 12418 dumpDetails = true; 12419 dumpFullDetails = true; 12420 dumpDalvik = true; 12421 } else if ("-d".equals(opt)) { 12422 dumpDalvik = true; 12423 } else if ("-c".equals(opt)) { 12424 isCompact = true; 12425 } else if ("--oom".equals(opt)) { 12426 oomOnly = true; 12427 } else if ("--local".equals(opt)) { 12428 localOnly = true; 12429 } else if ("-h".equals(opt)) { 12430 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12431 pw.println(" -a: include all available information for each process."); 12432 pw.println(" -d: include dalvik details when dumping process details."); 12433 pw.println(" -c: dump in a compact machine-parseable representation."); 12434 pw.println(" --oom: only show processes organized by oom adj."); 12435 pw.println(" --local: only collect details locally, don't call process."); 12436 pw.println("If [process] is specified it can be the name or "); 12437 pw.println("pid of a specific process to dump."); 12438 return; 12439 } else { 12440 pw.println("Unknown argument: " + opt + "; use -h for help"); 12441 } 12442 } 12443 12444 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12445 long uptime = SystemClock.uptimeMillis(); 12446 long realtime = SystemClock.elapsedRealtime(); 12447 final long[] tmpLong = new long[1]; 12448 12449 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12450 if (procs == null) { 12451 // No Java processes. Maybe they want to print a native process. 12452 if (args != null && args.length > opti 12453 && args[opti].charAt(0) != '-') { 12454 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12455 = new ArrayList<ProcessCpuTracker.Stats>(); 12456 updateCpuStatsNow(); 12457 int findPid = -1; 12458 try { 12459 findPid = Integer.parseInt(args[opti]); 12460 } catch (NumberFormatException e) { 12461 } 12462 synchronized (mProcessCpuThread) { 12463 final int N = mProcessCpuTracker.countStats(); 12464 for (int i=0; i<N; i++) { 12465 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12466 if (st.pid == findPid || (st.baseName != null 12467 && st.baseName.equals(args[opti]))) { 12468 nativeProcs.add(st); 12469 } 12470 } 12471 } 12472 if (nativeProcs.size() > 0) { 12473 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12474 isCompact); 12475 Debug.MemoryInfo mi = null; 12476 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12477 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12478 final int pid = r.pid; 12479 if (!isCheckinRequest && dumpDetails) { 12480 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12481 } 12482 if (mi == null) { 12483 mi = new Debug.MemoryInfo(); 12484 } 12485 if (dumpDetails || (!brief && !oomOnly)) { 12486 Debug.getMemoryInfo(pid, mi); 12487 } else { 12488 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12489 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12490 } 12491 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12492 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12493 if (isCheckinRequest) { 12494 pw.println(); 12495 } 12496 } 12497 return; 12498 } 12499 } 12500 pw.println("No process found for: " + args[opti]); 12501 return; 12502 } 12503 12504 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12505 dumpDetails = true; 12506 } 12507 12508 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12509 12510 String[] innerArgs = new String[args.length-opti]; 12511 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12512 12513 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12514 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12515 long nativePss=0, dalvikPss=0, otherPss=0; 12516 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12517 12518 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12519 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12520 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12521 12522 long totalPss = 0; 12523 long cachedPss = 0; 12524 12525 Debug.MemoryInfo mi = null; 12526 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12527 final ProcessRecord r = procs.get(i); 12528 final IApplicationThread thread; 12529 final int pid; 12530 final int oomAdj; 12531 final boolean hasActivities; 12532 synchronized (this) { 12533 thread = r.thread; 12534 pid = r.pid; 12535 oomAdj = r.getSetAdjWithServices(); 12536 hasActivities = r.activities.size() > 0; 12537 } 12538 if (thread != null) { 12539 if (!isCheckinRequest && dumpDetails) { 12540 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12541 } 12542 if (mi == null) { 12543 mi = new Debug.MemoryInfo(); 12544 } 12545 if (dumpDetails || (!brief && !oomOnly)) { 12546 Debug.getMemoryInfo(pid, mi); 12547 } else { 12548 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12549 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12550 } 12551 if (dumpDetails) { 12552 if (localOnly) { 12553 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12554 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12555 if (isCheckinRequest) { 12556 pw.println(); 12557 } 12558 } else { 12559 try { 12560 pw.flush(); 12561 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12562 dumpDalvik, innerArgs); 12563 } catch (RemoteException e) { 12564 if (!isCheckinRequest) { 12565 pw.println("Got RemoteException!"); 12566 pw.flush(); 12567 } 12568 } 12569 } 12570 } 12571 12572 final long myTotalPss = mi.getTotalPss(); 12573 final long myTotalUss = mi.getTotalUss(); 12574 12575 synchronized (this) { 12576 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12577 // Record this for posterity if the process has been stable. 12578 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12579 } 12580 } 12581 12582 if (!isCheckinRequest && mi != null) { 12583 totalPss += myTotalPss; 12584 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12585 (hasActivities ? " / activities)" : ")"), 12586 r.processName, myTotalPss, pid, hasActivities); 12587 procMems.add(pssItem); 12588 procMemsMap.put(pid, pssItem); 12589 12590 nativePss += mi.nativePss; 12591 dalvikPss += mi.dalvikPss; 12592 otherPss += mi.otherPss; 12593 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12594 long mem = mi.getOtherPss(j); 12595 miscPss[j] += mem; 12596 otherPss -= mem; 12597 } 12598 12599 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12600 cachedPss += myTotalPss; 12601 } 12602 12603 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12604 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12605 || oomIndex == (oomPss.length-1)) { 12606 oomPss[oomIndex] += myTotalPss; 12607 if (oomProcs[oomIndex] == null) { 12608 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12609 } 12610 oomProcs[oomIndex].add(pssItem); 12611 break; 12612 } 12613 } 12614 } 12615 } 12616 } 12617 12618 long nativeProcTotalPss = 0; 12619 12620 if (!isCheckinRequest && procs.size() > 1) { 12621 // If we are showing aggregations, also look for native processes to 12622 // include so that our aggregations are more accurate. 12623 updateCpuStatsNow(); 12624 synchronized (mProcessCpuThread) { 12625 final int N = mProcessCpuTracker.countStats(); 12626 for (int i=0; i<N; i++) { 12627 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12628 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12629 if (mi == null) { 12630 mi = new Debug.MemoryInfo(); 12631 } 12632 if (!brief && !oomOnly) { 12633 Debug.getMemoryInfo(st.pid, mi); 12634 } else { 12635 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12636 mi.nativePrivateDirty = (int)tmpLong[0]; 12637 } 12638 12639 final long myTotalPss = mi.getTotalPss(); 12640 totalPss += myTotalPss; 12641 nativeProcTotalPss += myTotalPss; 12642 12643 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12644 st.name, myTotalPss, st.pid, false); 12645 procMems.add(pssItem); 12646 12647 nativePss += mi.nativePss; 12648 dalvikPss += mi.dalvikPss; 12649 otherPss += mi.otherPss; 12650 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12651 long mem = mi.getOtherPss(j); 12652 miscPss[j] += mem; 12653 otherPss -= mem; 12654 } 12655 oomPss[0] += myTotalPss; 12656 if (oomProcs[0] == null) { 12657 oomProcs[0] = new ArrayList<MemItem>(); 12658 } 12659 oomProcs[0].add(pssItem); 12660 } 12661 } 12662 } 12663 12664 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12665 12666 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12667 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12668 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12669 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12670 String label = Debug.MemoryInfo.getOtherLabel(j); 12671 catMems.add(new MemItem(label, label, miscPss[j], j)); 12672 } 12673 12674 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12675 for (int j=0; j<oomPss.length; j++) { 12676 if (oomPss[j] != 0) { 12677 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12678 : DUMP_MEM_OOM_LABEL[j]; 12679 MemItem item = new MemItem(label, label, oomPss[j], 12680 DUMP_MEM_OOM_ADJ[j]); 12681 item.subitems = oomProcs[j]; 12682 oomMems.add(item); 12683 } 12684 } 12685 12686 if (!brief && !oomOnly && !isCompact) { 12687 pw.println(); 12688 pw.println("Total PSS by process:"); 12689 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12690 pw.println(); 12691 } 12692 if (!isCompact) { 12693 pw.println("Total PSS by OOM adjustment:"); 12694 } 12695 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12696 if (!brief && !oomOnly) { 12697 PrintWriter out = categoryPw != null ? categoryPw : pw; 12698 if (!isCompact) { 12699 out.println(); 12700 out.println("Total PSS by category:"); 12701 } 12702 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12703 } 12704 if (!isCompact) { 12705 pw.println(); 12706 } 12707 MemInfoReader memInfo = new MemInfoReader(); 12708 memInfo.readMemInfo(); 12709 if (nativeProcTotalPss > 0) { 12710 synchronized (this) { 12711 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12712 memInfo.getFreeSizeKb(), 12713 memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(), 12714 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12715 nativeProcTotalPss); 12716 } 12717 } 12718 if (!brief) { 12719 if (!isCompact) { 12720 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12721 pw.print(" kB (status "); 12722 switch (mLastMemoryLevel) { 12723 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12724 pw.println("normal)"); 12725 break; 12726 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12727 pw.println("moderate)"); 12728 break; 12729 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12730 pw.println("low)"); 12731 break; 12732 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12733 pw.println("critical)"); 12734 break; 12735 default: 12736 pw.print(mLastMemoryLevel); 12737 pw.println(")"); 12738 break; 12739 } 12740 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12741 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12742 pw.print(cachedPss); pw.print(" cached pss + "); 12743 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12744 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12745 } else { 12746 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12747 pw.print(cachedPss + memInfo.getCachedSizeKb() 12748 + memInfo.getFreeSizeKb()); pw.print(","); 12749 pw.println(totalPss - cachedPss); 12750 } 12751 } 12752 if (!isCompact) { 12753 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12754 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12755 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12756 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12757 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12758 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12759 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12760 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12761 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12762 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12763 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12764 } 12765 if (!brief) { 12766 if (memInfo.getZramTotalSizeKb() != 0) { 12767 if (!isCompact) { 12768 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12769 pw.print(" kB physical used for "); 12770 pw.print(memInfo.getSwapTotalSizeKb() 12771 - memInfo.getSwapFreeSizeKb()); 12772 pw.print(" kB in swap ("); 12773 pw.print(memInfo.getSwapTotalSizeKb()); 12774 pw.println(" kB total swap)"); 12775 } else { 12776 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12777 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12778 pw.println(memInfo.getSwapFreeSizeKb()); 12779 } 12780 } 12781 final int[] SINGLE_LONG_FORMAT = new int[] { 12782 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12783 }; 12784 long[] longOut = new long[1]; 12785 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12786 SINGLE_LONG_FORMAT, null, longOut, null); 12787 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12788 longOut[0] = 0; 12789 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12790 SINGLE_LONG_FORMAT, null, longOut, null); 12791 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12792 longOut[0] = 0; 12793 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12794 SINGLE_LONG_FORMAT, null, longOut, null); 12795 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12796 longOut[0] = 0; 12797 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12798 SINGLE_LONG_FORMAT, null, longOut, null); 12799 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12800 if (!isCompact) { 12801 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12802 pw.print(" KSM: "); pw.print(sharing); 12803 pw.print(" kB saved from shared "); 12804 pw.print(shared); pw.println(" kB"); 12805 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12806 pw.print(voltile); pw.println(" kB volatile"); 12807 } 12808 pw.print(" Tuning: "); 12809 pw.print(ActivityManager.staticGetMemoryClass()); 12810 pw.print(" (large "); 12811 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12812 pw.print("), oom "); 12813 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12814 pw.print(" kB"); 12815 pw.print(", restore limit "); 12816 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12817 pw.print(" kB"); 12818 if (ActivityManager.isLowRamDeviceStatic()) { 12819 pw.print(" (low-ram)"); 12820 } 12821 if (ActivityManager.isHighEndGfx()) { 12822 pw.print(" (high-end-gfx)"); 12823 } 12824 pw.println(); 12825 } else { 12826 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12827 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12828 pw.println(voltile); 12829 pw.print("tuning,"); 12830 pw.print(ActivityManager.staticGetMemoryClass()); 12831 pw.print(','); 12832 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12833 pw.print(','); 12834 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12835 if (ActivityManager.isLowRamDeviceStatic()) { 12836 pw.print(",low-ram"); 12837 } 12838 if (ActivityManager.isHighEndGfx()) { 12839 pw.print(",high-end-gfx"); 12840 } 12841 pw.println(); 12842 } 12843 } 12844 } 12845 } 12846 12847 /** 12848 * Searches array of arguments for the specified string 12849 * @param args array of argument strings 12850 * @param value value to search for 12851 * @return true if the value is contained in the array 12852 */ 12853 private static boolean scanArgs(String[] args, String value) { 12854 if (args != null) { 12855 for (String arg : args) { 12856 if (value.equals(arg)) { 12857 return true; 12858 } 12859 } 12860 } 12861 return false; 12862 } 12863 12864 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12865 ContentProviderRecord cpr, boolean always) { 12866 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12867 12868 if (!inLaunching || always) { 12869 synchronized (cpr) { 12870 cpr.launchingApp = null; 12871 cpr.notifyAll(); 12872 } 12873 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12874 String names[] = cpr.info.authority.split(";"); 12875 for (int j = 0; j < names.length; j++) { 12876 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12877 } 12878 } 12879 12880 for (int i=0; i<cpr.connections.size(); i++) { 12881 ContentProviderConnection conn = cpr.connections.get(i); 12882 if (conn.waiting) { 12883 // If this connection is waiting for the provider, then we don't 12884 // need to mess with its process unless we are always removing 12885 // or for some reason the provider is not currently launching. 12886 if (inLaunching && !always) { 12887 continue; 12888 } 12889 } 12890 ProcessRecord capp = conn.client; 12891 conn.dead = true; 12892 if (conn.stableCount > 0) { 12893 if (!capp.persistent && capp.thread != null 12894 && capp.pid != 0 12895 && capp.pid != MY_PID) { 12896 killUnneededProcessLocked(capp, "depends on provider " 12897 + cpr.name.flattenToShortString() 12898 + " in dying proc " + (proc != null ? proc.processName : "??")); 12899 } 12900 } else if (capp.thread != null && conn.provider.provider != null) { 12901 try { 12902 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12903 } catch (RemoteException e) { 12904 } 12905 // In the protocol here, we don't expect the client to correctly 12906 // clean up this connection, we'll just remove it. 12907 cpr.connections.remove(i); 12908 conn.client.conProviders.remove(conn); 12909 } 12910 } 12911 12912 if (inLaunching && always) { 12913 mLaunchingProviders.remove(cpr); 12914 } 12915 return inLaunching; 12916 } 12917 12918 /** 12919 * Main code for cleaning up a process when it has gone away. This is 12920 * called both as a result of the process dying, or directly when stopping 12921 * a process when running in single process mode. 12922 */ 12923 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12924 boolean restarting, boolean allowRestart, int index) { 12925 if (index >= 0) { 12926 removeLruProcessLocked(app); 12927 ProcessList.remove(app.pid); 12928 } 12929 12930 mProcessesToGc.remove(app); 12931 mPendingPssProcesses.remove(app); 12932 12933 // Dismiss any open dialogs. 12934 if (app.crashDialog != null && !app.forceCrashReport) { 12935 app.crashDialog.dismiss(); 12936 app.crashDialog = null; 12937 } 12938 if (app.anrDialog != null) { 12939 app.anrDialog.dismiss(); 12940 app.anrDialog = null; 12941 } 12942 if (app.waitDialog != null) { 12943 app.waitDialog.dismiss(); 12944 app.waitDialog = null; 12945 } 12946 12947 app.crashing = false; 12948 app.notResponding = false; 12949 12950 app.resetPackageList(mProcessStats); 12951 app.unlinkDeathRecipient(); 12952 app.makeInactive(mProcessStats); 12953 app.forcingToForeground = null; 12954 updateProcessForegroundLocked(app, false, false); 12955 app.foregroundActivities = false; 12956 app.hasShownUi = false; 12957 app.treatLikeActivity = false; 12958 app.hasAboveClient = false; 12959 app.hasClientActivities = false; 12960 12961 mServices.killServicesLocked(app, allowRestart); 12962 12963 boolean restart = false; 12964 12965 // Remove published content providers. 12966 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12967 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12968 final boolean always = app.bad || !allowRestart; 12969 if (removeDyingProviderLocked(app, cpr, always) || always) { 12970 // We left the provider in the launching list, need to 12971 // restart it. 12972 restart = true; 12973 } 12974 12975 cpr.provider = null; 12976 cpr.proc = null; 12977 } 12978 app.pubProviders.clear(); 12979 12980 // Take care of any launching providers waiting for this process. 12981 if (checkAppInLaunchingProvidersLocked(app, false)) { 12982 restart = true; 12983 } 12984 12985 // Unregister from connected content providers. 12986 if (!app.conProviders.isEmpty()) { 12987 for (int i=0; i<app.conProviders.size(); i++) { 12988 ContentProviderConnection conn = app.conProviders.get(i); 12989 conn.provider.connections.remove(conn); 12990 } 12991 app.conProviders.clear(); 12992 } 12993 12994 // At this point there may be remaining entries in mLaunchingProviders 12995 // where we were the only one waiting, so they are no longer of use. 12996 // Look for these and clean up if found. 12997 // XXX Commented out for now. Trying to figure out a way to reproduce 12998 // the actual situation to identify what is actually going on. 12999 if (false) { 13000 for (int i=0; i<mLaunchingProviders.size(); i++) { 13001 ContentProviderRecord cpr = (ContentProviderRecord) 13002 mLaunchingProviders.get(i); 13003 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13004 synchronized (cpr) { 13005 cpr.launchingApp = null; 13006 cpr.notifyAll(); 13007 } 13008 } 13009 } 13010 } 13011 13012 skipCurrentReceiverLocked(app); 13013 13014 // Unregister any receivers. 13015 for (int i=app.receivers.size()-1; i>=0; i--) { 13016 removeReceiverLocked(app.receivers.valueAt(i)); 13017 } 13018 app.receivers.clear(); 13019 13020 // If the app is undergoing backup, tell the backup manager about it 13021 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13022 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13023 + mBackupTarget.appInfo + " died during backup"); 13024 try { 13025 IBackupManager bm = IBackupManager.Stub.asInterface( 13026 ServiceManager.getService(Context.BACKUP_SERVICE)); 13027 bm.agentDisconnected(app.info.packageName); 13028 } catch (RemoteException e) { 13029 // can't happen; backup manager is local 13030 } 13031 } 13032 13033 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13034 ProcessChangeItem item = mPendingProcessChanges.get(i); 13035 if (item.pid == app.pid) { 13036 mPendingProcessChanges.remove(i); 13037 mAvailProcessChanges.add(item); 13038 } 13039 } 13040 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13041 13042 // If the caller is restarting this app, then leave it in its 13043 // current lists and let the caller take care of it. 13044 if (restarting) { 13045 return; 13046 } 13047 13048 if (!app.persistent || app.isolated) { 13049 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13050 "Removing non-persistent process during cleanup: " + app); 13051 mProcessNames.remove(app.processName, app.uid); 13052 mIsolatedProcesses.remove(app.uid); 13053 if (mHeavyWeightProcess == app) { 13054 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13055 mHeavyWeightProcess.userId, 0)); 13056 mHeavyWeightProcess = null; 13057 } 13058 } else if (!app.removed) { 13059 // This app is persistent, so we need to keep its record around. 13060 // If it is not already on the pending app list, add it there 13061 // and start a new process for it. 13062 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13063 mPersistentStartingProcesses.add(app); 13064 restart = true; 13065 } 13066 } 13067 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13068 "Clean-up removing on hold: " + app); 13069 mProcessesOnHold.remove(app); 13070 13071 if (app == mHomeProcess) { 13072 mHomeProcess = null; 13073 } 13074 if (app == mPreviousProcess) { 13075 mPreviousProcess = null; 13076 } 13077 13078 if (restart && !app.isolated) { 13079 // We have components that still need to be running in the 13080 // process, so re-launch it. 13081 mProcessNames.put(app.processName, app.uid, app); 13082 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13083 } else if (app.pid > 0 && app.pid != MY_PID) { 13084 // Goodbye! 13085 boolean removed; 13086 synchronized (mPidsSelfLocked) { 13087 mPidsSelfLocked.remove(app.pid); 13088 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13089 } 13090 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13091 app.processName, app.info.uid); 13092 if (app.isolated) { 13093 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13094 } 13095 app.setPid(0); 13096 } 13097 } 13098 13099 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13100 // Look through the content providers we are waiting to have launched, 13101 // and if any run in this process then either schedule a restart of 13102 // the process or kill the client waiting for it if this process has 13103 // gone bad. 13104 int NL = mLaunchingProviders.size(); 13105 boolean restart = false; 13106 for (int i=0; i<NL; i++) { 13107 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13108 if (cpr.launchingApp == app) { 13109 if (!alwaysBad && !app.bad) { 13110 restart = true; 13111 } else { 13112 removeDyingProviderLocked(app, cpr, true); 13113 // cpr should have been removed from mLaunchingProviders 13114 NL = mLaunchingProviders.size(); 13115 i--; 13116 } 13117 } 13118 } 13119 return restart; 13120 } 13121 13122 // ========================================================= 13123 // SERVICES 13124 // ========================================================= 13125 13126 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13127 int flags) { 13128 enforceNotIsolatedCaller("getServices"); 13129 synchronized (this) { 13130 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13131 } 13132 } 13133 13134 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13135 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13136 synchronized (this) { 13137 return mServices.getRunningServiceControlPanelLocked(name); 13138 } 13139 } 13140 13141 public ComponentName startService(IApplicationThread caller, Intent service, 13142 String resolvedType, int userId) { 13143 enforceNotIsolatedCaller("startService"); 13144 // Refuse possible leaked file descriptors 13145 if (service != null && service.hasFileDescriptors() == true) { 13146 throw new IllegalArgumentException("File descriptors passed in Intent"); 13147 } 13148 13149 if (DEBUG_SERVICE) 13150 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13151 synchronized(this) { 13152 final int callingPid = Binder.getCallingPid(); 13153 final int callingUid = Binder.getCallingUid(); 13154 final long origId = Binder.clearCallingIdentity(); 13155 ComponentName res = mServices.startServiceLocked(caller, service, 13156 resolvedType, callingPid, callingUid, userId); 13157 Binder.restoreCallingIdentity(origId); 13158 return res; 13159 } 13160 } 13161 13162 ComponentName startServiceInPackage(int uid, 13163 Intent service, String resolvedType, int userId) { 13164 synchronized(this) { 13165 if (DEBUG_SERVICE) 13166 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13167 final long origId = Binder.clearCallingIdentity(); 13168 ComponentName res = mServices.startServiceLocked(null, service, 13169 resolvedType, -1, uid, userId); 13170 Binder.restoreCallingIdentity(origId); 13171 return res; 13172 } 13173 } 13174 13175 public int stopService(IApplicationThread caller, Intent service, 13176 String resolvedType, int userId) { 13177 enforceNotIsolatedCaller("stopService"); 13178 // Refuse possible leaked file descriptors 13179 if (service != null && service.hasFileDescriptors() == true) { 13180 throw new IllegalArgumentException("File descriptors passed in Intent"); 13181 } 13182 13183 synchronized(this) { 13184 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13185 } 13186 } 13187 13188 public IBinder peekService(Intent service, String resolvedType) { 13189 enforceNotIsolatedCaller("peekService"); 13190 // Refuse possible leaked file descriptors 13191 if (service != null && service.hasFileDescriptors() == true) { 13192 throw new IllegalArgumentException("File descriptors passed in Intent"); 13193 } 13194 synchronized(this) { 13195 return mServices.peekServiceLocked(service, resolvedType); 13196 } 13197 } 13198 13199 public boolean stopServiceToken(ComponentName className, IBinder token, 13200 int startId) { 13201 synchronized(this) { 13202 return mServices.stopServiceTokenLocked(className, token, startId); 13203 } 13204 } 13205 13206 public void setServiceForeground(ComponentName className, IBinder token, 13207 int id, Notification notification, boolean removeNotification) { 13208 synchronized(this) { 13209 mServices.setServiceForegroundLocked(className, token, id, notification, 13210 removeNotification); 13211 } 13212 } 13213 13214 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13215 boolean requireFull, String name, String callerPackage) { 13216 final int callingUserId = UserHandle.getUserId(callingUid); 13217 if (callingUserId != userId) { 13218 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13219 if ((requireFull || checkComponentPermission( 13220 android.Manifest.permission.INTERACT_ACROSS_USERS, 13221 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13222 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13223 callingPid, callingUid, -1, true) 13224 != PackageManager.PERMISSION_GRANTED) { 13225 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13226 // In this case, they would like to just execute as their 13227 // owner user instead of failing. 13228 userId = callingUserId; 13229 } else { 13230 StringBuilder builder = new StringBuilder(128); 13231 builder.append("Permission Denial: "); 13232 builder.append(name); 13233 if (callerPackage != null) { 13234 builder.append(" from "); 13235 builder.append(callerPackage); 13236 } 13237 builder.append(" asks to run as user "); 13238 builder.append(userId); 13239 builder.append(" but is calling from user "); 13240 builder.append(UserHandle.getUserId(callingUid)); 13241 builder.append("; this requires "); 13242 builder.append(INTERACT_ACROSS_USERS_FULL); 13243 if (!requireFull) { 13244 builder.append(" or "); 13245 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13246 } 13247 String msg = builder.toString(); 13248 Slog.w(TAG, msg); 13249 throw new SecurityException(msg); 13250 } 13251 } 13252 } 13253 if (userId == UserHandle.USER_CURRENT 13254 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13255 // Note that we may be accessing this outside of a lock... 13256 // shouldn't be a big deal, if this is being called outside 13257 // of a locked context there is intrinsically a race with 13258 // the value the caller will receive and someone else changing it. 13259 userId = mCurrentUserId; 13260 } 13261 if (!allowAll && userId < 0) { 13262 throw new IllegalArgumentException( 13263 "Call does not support special user #" + userId); 13264 } 13265 } 13266 return userId; 13267 } 13268 13269 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13270 String className, int flags) { 13271 boolean result = false; 13272 // For apps that don't have pre-defined UIDs, check for permission 13273 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13274 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13275 if (ActivityManager.checkUidPermission( 13276 android.Manifest.permission.INTERACT_ACROSS_USERS, 13277 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13278 ComponentName comp = new ComponentName(aInfo.packageName, className); 13279 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13280 + " requests FLAG_SINGLE_USER, but app does not hold " 13281 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13282 Slog.w(TAG, msg); 13283 throw new SecurityException(msg); 13284 } 13285 // Permission passed 13286 result = true; 13287 } 13288 } else if ("system".equals(componentProcessName)) { 13289 result = true; 13290 } else { 13291 // App with pre-defined UID, check if it's a persistent app 13292 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13293 } 13294 if (DEBUG_MU) { 13295 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13296 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13297 } 13298 return result; 13299 } 13300 13301 /** 13302 * Checks to see if the caller is in the same app as the singleton 13303 * component, or the component is in a special app. It allows special apps 13304 * to export singleton components but prevents exporting singleton 13305 * components for regular apps. 13306 */ 13307 boolean isValidSingletonCall(int callingUid, int componentUid) { 13308 int componentAppId = UserHandle.getAppId(componentUid); 13309 return UserHandle.isSameApp(callingUid, componentUid) 13310 || componentAppId == Process.SYSTEM_UID 13311 || componentAppId == Process.PHONE_UID 13312 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13313 == PackageManager.PERMISSION_GRANTED; 13314 } 13315 13316 public int bindService(IApplicationThread caller, IBinder token, 13317 Intent service, String resolvedType, 13318 IServiceConnection connection, int flags, int userId) { 13319 enforceNotIsolatedCaller("bindService"); 13320 // Refuse possible leaked file descriptors 13321 if (service != null && service.hasFileDescriptors() == true) { 13322 throw new IllegalArgumentException("File descriptors passed in Intent"); 13323 } 13324 13325 synchronized(this) { 13326 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13327 connection, flags, userId); 13328 } 13329 } 13330 13331 public boolean unbindService(IServiceConnection connection) { 13332 synchronized (this) { 13333 return mServices.unbindServiceLocked(connection); 13334 } 13335 } 13336 13337 public void publishService(IBinder token, Intent intent, IBinder service) { 13338 // Refuse possible leaked file descriptors 13339 if (intent != null && intent.hasFileDescriptors() == true) { 13340 throw new IllegalArgumentException("File descriptors passed in Intent"); 13341 } 13342 13343 synchronized(this) { 13344 if (!(token instanceof ServiceRecord)) { 13345 throw new IllegalArgumentException("Invalid service token"); 13346 } 13347 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13348 } 13349 } 13350 13351 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13352 // Refuse possible leaked file descriptors 13353 if (intent != null && intent.hasFileDescriptors() == true) { 13354 throw new IllegalArgumentException("File descriptors passed in Intent"); 13355 } 13356 13357 synchronized(this) { 13358 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13359 } 13360 } 13361 13362 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13363 synchronized(this) { 13364 if (!(token instanceof ServiceRecord)) { 13365 throw new IllegalArgumentException("Invalid service token"); 13366 } 13367 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13368 } 13369 } 13370 13371 // ========================================================= 13372 // BACKUP AND RESTORE 13373 // ========================================================= 13374 13375 // Cause the target app to be launched if necessary and its backup agent 13376 // instantiated. The backup agent will invoke backupAgentCreated() on the 13377 // activity manager to announce its creation. 13378 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13379 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13380 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13381 13382 synchronized(this) { 13383 // !!! TODO: currently no check here that we're already bound 13384 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13385 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13386 synchronized (stats) { 13387 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13388 } 13389 13390 // Backup agent is now in use, its package can't be stopped. 13391 try { 13392 AppGlobals.getPackageManager().setPackageStoppedState( 13393 app.packageName, false, UserHandle.getUserId(app.uid)); 13394 } catch (RemoteException e) { 13395 } catch (IllegalArgumentException e) { 13396 Slog.w(TAG, "Failed trying to unstop package " 13397 + app.packageName + ": " + e); 13398 } 13399 13400 BackupRecord r = new BackupRecord(ss, app, backupMode); 13401 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13402 ? new ComponentName(app.packageName, app.backupAgentName) 13403 : new ComponentName("android", "FullBackupAgent"); 13404 // startProcessLocked() returns existing proc's record if it's already running 13405 ProcessRecord proc = startProcessLocked(app.processName, app, 13406 false, 0, "backup", hostingName, false, false, false); 13407 if (proc == null) { 13408 Slog.e(TAG, "Unable to start backup agent process " + r); 13409 return false; 13410 } 13411 13412 r.app = proc; 13413 mBackupTarget = r; 13414 mBackupAppName = app.packageName; 13415 13416 // Try not to kill the process during backup 13417 updateOomAdjLocked(proc); 13418 13419 // If the process is already attached, schedule the creation of the backup agent now. 13420 // If it is not yet live, this will be done when it attaches to the framework. 13421 if (proc.thread != null) { 13422 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13423 try { 13424 proc.thread.scheduleCreateBackupAgent(app, 13425 compatibilityInfoForPackageLocked(app), backupMode); 13426 } catch (RemoteException e) { 13427 // Will time out on the backup manager side 13428 } 13429 } else { 13430 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13431 } 13432 // Invariants: at this point, the target app process exists and the application 13433 // is either already running or in the process of coming up. mBackupTarget and 13434 // mBackupAppName describe the app, so that when it binds back to the AM we 13435 // know that it's scheduled for a backup-agent operation. 13436 } 13437 13438 return true; 13439 } 13440 13441 @Override 13442 public void clearPendingBackup() { 13443 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13444 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13445 13446 synchronized (this) { 13447 mBackupTarget = null; 13448 mBackupAppName = null; 13449 } 13450 } 13451 13452 // A backup agent has just come up 13453 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13454 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13455 + " = " + agent); 13456 13457 synchronized(this) { 13458 if (!agentPackageName.equals(mBackupAppName)) { 13459 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13460 return; 13461 } 13462 } 13463 13464 long oldIdent = Binder.clearCallingIdentity(); 13465 try { 13466 IBackupManager bm = IBackupManager.Stub.asInterface( 13467 ServiceManager.getService(Context.BACKUP_SERVICE)); 13468 bm.agentConnected(agentPackageName, agent); 13469 } catch (RemoteException e) { 13470 // can't happen; the backup manager service is local 13471 } catch (Exception e) { 13472 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13473 e.printStackTrace(); 13474 } finally { 13475 Binder.restoreCallingIdentity(oldIdent); 13476 } 13477 } 13478 13479 // done with this agent 13480 public void unbindBackupAgent(ApplicationInfo appInfo) { 13481 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13482 if (appInfo == null) { 13483 Slog.w(TAG, "unbind backup agent for null app"); 13484 return; 13485 } 13486 13487 synchronized(this) { 13488 try { 13489 if (mBackupAppName == null) { 13490 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13491 return; 13492 } 13493 13494 if (!mBackupAppName.equals(appInfo.packageName)) { 13495 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13496 return; 13497 } 13498 13499 // Not backing this app up any more; reset its OOM adjustment 13500 final ProcessRecord proc = mBackupTarget.app; 13501 updateOomAdjLocked(proc); 13502 13503 // If the app crashed during backup, 'thread' will be null here 13504 if (proc.thread != null) { 13505 try { 13506 proc.thread.scheduleDestroyBackupAgent(appInfo, 13507 compatibilityInfoForPackageLocked(appInfo)); 13508 } catch (Exception e) { 13509 Slog.e(TAG, "Exception when unbinding backup agent:"); 13510 e.printStackTrace(); 13511 } 13512 } 13513 } finally { 13514 mBackupTarget = null; 13515 mBackupAppName = null; 13516 } 13517 } 13518 } 13519 // ========================================================= 13520 // BROADCASTS 13521 // ========================================================= 13522 13523 private final List getStickiesLocked(String action, IntentFilter filter, 13524 List cur, int userId) { 13525 final ContentResolver resolver = mContext.getContentResolver(); 13526 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13527 if (stickies == null) { 13528 return cur; 13529 } 13530 final ArrayList<Intent> list = stickies.get(action); 13531 if (list == null) { 13532 return cur; 13533 } 13534 int N = list.size(); 13535 for (int i=0; i<N; i++) { 13536 Intent intent = list.get(i); 13537 if (filter.match(resolver, intent, true, TAG) >= 0) { 13538 if (cur == null) { 13539 cur = new ArrayList<Intent>(); 13540 } 13541 cur.add(intent); 13542 } 13543 } 13544 return cur; 13545 } 13546 13547 boolean isPendingBroadcastProcessLocked(int pid) { 13548 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13549 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13550 } 13551 13552 void skipPendingBroadcastLocked(int pid) { 13553 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13554 for (BroadcastQueue queue : mBroadcastQueues) { 13555 queue.skipPendingBroadcastLocked(pid); 13556 } 13557 } 13558 13559 // The app just attached; send any pending broadcasts that it should receive 13560 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13561 boolean didSomething = false; 13562 for (BroadcastQueue queue : mBroadcastQueues) { 13563 didSomething |= queue.sendPendingBroadcastsLocked(app); 13564 } 13565 return didSomething; 13566 } 13567 13568 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13569 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13570 enforceNotIsolatedCaller("registerReceiver"); 13571 int callingUid; 13572 int callingPid; 13573 synchronized(this) { 13574 ProcessRecord callerApp = null; 13575 if (caller != null) { 13576 callerApp = getRecordForAppLocked(caller); 13577 if (callerApp == null) { 13578 throw new SecurityException( 13579 "Unable to find app for caller " + caller 13580 + " (pid=" + Binder.getCallingPid() 13581 + ") when registering receiver " + receiver); 13582 } 13583 if (callerApp.info.uid != Process.SYSTEM_UID && 13584 !callerApp.pkgList.containsKey(callerPackage) && 13585 !"android".equals(callerPackage)) { 13586 throw new SecurityException("Given caller package " + callerPackage 13587 + " is not running in process " + callerApp); 13588 } 13589 callingUid = callerApp.info.uid; 13590 callingPid = callerApp.pid; 13591 } else { 13592 callerPackage = null; 13593 callingUid = Binder.getCallingUid(); 13594 callingPid = Binder.getCallingPid(); 13595 } 13596 13597 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13598 true, true, "registerReceiver", callerPackage); 13599 13600 List allSticky = null; 13601 13602 // Look for any matching sticky broadcasts... 13603 Iterator actions = filter.actionsIterator(); 13604 if (actions != null) { 13605 while (actions.hasNext()) { 13606 String action = (String)actions.next(); 13607 allSticky = getStickiesLocked(action, filter, allSticky, 13608 UserHandle.USER_ALL); 13609 allSticky = getStickiesLocked(action, filter, allSticky, 13610 UserHandle.getUserId(callingUid)); 13611 } 13612 } else { 13613 allSticky = getStickiesLocked(null, filter, allSticky, 13614 UserHandle.USER_ALL); 13615 allSticky = getStickiesLocked(null, filter, allSticky, 13616 UserHandle.getUserId(callingUid)); 13617 } 13618 13619 // The first sticky in the list is returned directly back to 13620 // the client. 13621 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13622 13623 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13624 + ": " + sticky); 13625 13626 if (receiver == null) { 13627 return sticky; 13628 } 13629 13630 ReceiverList rl 13631 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13632 if (rl == null) { 13633 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13634 userId, receiver); 13635 if (rl.app != null) { 13636 rl.app.receivers.add(rl); 13637 } else { 13638 try { 13639 receiver.asBinder().linkToDeath(rl, 0); 13640 } catch (RemoteException e) { 13641 return sticky; 13642 } 13643 rl.linkedToDeath = true; 13644 } 13645 mRegisteredReceivers.put(receiver.asBinder(), rl); 13646 } else if (rl.uid != callingUid) { 13647 throw new IllegalArgumentException( 13648 "Receiver requested to register for uid " + callingUid 13649 + " was previously registered for uid " + rl.uid); 13650 } else if (rl.pid != callingPid) { 13651 throw new IllegalArgumentException( 13652 "Receiver requested to register for pid " + callingPid 13653 + " was previously registered for pid " + rl.pid); 13654 } else if (rl.userId != userId) { 13655 throw new IllegalArgumentException( 13656 "Receiver requested to register for user " + userId 13657 + " was previously registered for user " + rl.userId); 13658 } 13659 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13660 permission, callingUid, userId); 13661 rl.add(bf); 13662 if (!bf.debugCheck()) { 13663 Slog.w(TAG, "==> For Dynamic broadast"); 13664 } 13665 mReceiverResolver.addFilter(bf); 13666 13667 // Enqueue broadcasts for all existing stickies that match 13668 // this filter. 13669 if (allSticky != null) { 13670 ArrayList receivers = new ArrayList(); 13671 receivers.add(bf); 13672 13673 int N = allSticky.size(); 13674 for (int i=0; i<N; i++) { 13675 Intent intent = (Intent)allSticky.get(i); 13676 BroadcastQueue queue = broadcastQueueForIntent(intent); 13677 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13678 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13679 null, null, false, true, true, -1); 13680 queue.enqueueParallelBroadcastLocked(r); 13681 queue.scheduleBroadcastsLocked(); 13682 } 13683 } 13684 13685 return sticky; 13686 } 13687 } 13688 13689 public void unregisterReceiver(IIntentReceiver receiver) { 13690 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13691 13692 final long origId = Binder.clearCallingIdentity(); 13693 try { 13694 boolean doTrim = false; 13695 13696 synchronized(this) { 13697 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13698 if (rl != null) { 13699 if (rl.curBroadcast != null) { 13700 BroadcastRecord r = rl.curBroadcast; 13701 final boolean doNext = finishReceiverLocked( 13702 receiver.asBinder(), r.resultCode, r.resultData, 13703 r.resultExtras, r.resultAbort); 13704 if (doNext) { 13705 doTrim = true; 13706 r.queue.processNextBroadcast(false); 13707 } 13708 } 13709 13710 if (rl.app != null) { 13711 rl.app.receivers.remove(rl); 13712 } 13713 removeReceiverLocked(rl); 13714 if (rl.linkedToDeath) { 13715 rl.linkedToDeath = false; 13716 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13717 } 13718 } 13719 } 13720 13721 // If we actually concluded any broadcasts, we might now be able 13722 // to trim the recipients' apps from our working set 13723 if (doTrim) { 13724 trimApplications(); 13725 return; 13726 } 13727 13728 } finally { 13729 Binder.restoreCallingIdentity(origId); 13730 } 13731 } 13732 13733 void removeReceiverLocked(ReceiverList rl) { 13734 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13735 int N = rl.size(); 13736 for (int i=0; i<N; i++) { 13737 mReceiverResolver.removeFilter(rl.get(i)); 13738 } 13739 } 13740 13741 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13742 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13743 ProcessRecord r = mLruProcesses.get(i); 13744 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13745 try { 13746 r.thread.dispatchPackageBroadcast(cmd, packages); 13747 } catch (RemoteException ex) { 13748 } 13749 } 13750 } 13751 } 13752 13753 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13754 int[] users) { 13755 List<ResolveInfo> receivers = null; 13756 try { 13757 HashSet<ComponentName> singleUserReceivers = null; 13758 boolean scannedFirstReceivers = false; 13759 for (int user : users) { 13760 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13761 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13762 if (user != 0 && newReceivers != null) { 13763 // If this is not the primary user, we need to check for 13764 // any receivers that should be filtered out. 13765 for (int i=0; i<newReceivers.size(); i++) { 13766 ResolveInfo ri = newReceivers.get(i); 13767 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13768 newReceivers.remove(i); 13769 i--; 13770 } 13771 } 13772 } 13773 if (newReceivers != null && newReceivers.size() == 0) { 13774 newReceivers = null; 13775 } 13776 if (receivers == null) { 13777 receivers = newReceivers; 13778 } else if (newReceivers != null) { 13779 // We need to concatenate the additional receivers 13780 // found with what we have do far. This would be easy, 13781 // but we also need to de-dup any receivers that are 13782 // singleUser. 13783 if (!scannedFirstReceivers) { 13784 // Collect any single user receivers we had already retrieved. 13785 scannedFirstReceivers = true; 13786 for (int i=0; i<receivers.size(); i++) { 13787 ResolveInfo ri = receivers.get(i); 13788 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13789 ComponentName cn = new ComponentName( 13790 ri.activityInfo.packageName, ri.activityInfo.name); 13791 if (singleUserReceivers == null) { 13792 singleUserReceivers = new HashSet<ComponentName>(); 13793 } 13794 singleUserReceivers.add(cn); 13795 } 13796 } 13797 } 13798 // Add the new results to the existing results, tracking 13799 // and de-dupping single user receivers. 13800 for (int i=0; i<newReceivers.size(); i++) { 13801 ResolveInfo ri = newReceivers.get(i); 13802 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13803 ComponentName cn = new ComponentName( 13804 ri.activityInfo.packageName, ri.activityInfo.name); 13805 if (singleUserReceivers == null) { 13806 singleUserReceivers = new HashSet<ComponentName>(); 13807 } 13808 if (!singleUserReceivers.contains(cn)) { 13809 singleUserReceivers.add(cn); 13810 receivers.add(ri); 13811 } 13812 } else { 13813 receivers.add(ri); 13814 } 13815 } 13816 } 13817 } 13818 } catch (RemoteException ex) { 13819 // pm is in same process, this will never happen. 13820 } 13821 return receivers; 13822 } 13823 13824 private final int broadcastIntentLocked(ProcessRecord callerApp, 13825 String callerPackage, Intent intent, String resolvedType, 13826 IIntentReceiver resultTo, int resultCode, String resultData, 13827 Bundle map, String requiredPermission, int appOp, 13828 boolean ordered, boolean sticky, int callingPid, int callingUid, 13829 int userId) { 13830 intent = new Intent(intent); 13831 13832 // By default broadcasts do not go to stopped apps. 13833 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13834 13835 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13836 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13837 + " ordered=" + ordered + " userid=" + userId); 13838 if ((resultTo != null) && !ordered) { 13839 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13840 } 13841 13842 userId = handleIncomingUser(callingPid, callingUid, userId, 13843 true, false, "broadcast", callerPackage); 13844 13845 // Make sure that the user who is receiving this broadcast is started. 13846 // If not, we will just skip it. 13847 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13848 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13849 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13850 Slog.w(TAG, "Skipping broadcast of " + intent 13851 + ": user " + userId + " is stopped"); 13852 return ActivityManager.BROADCAST_SUCCESS; 13853 } 13854 } 13855 13856 /* 13857 * Prevent non-system code (defined here to be non-persistent 13858 * processes) from sending protected broadcasts. 13859 */ 13860 int callingAppId = UserHandle.getAppId(callingUid); 13861 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13862 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 13863 || callingUid == 0) { 13864 // Always okay. 13865 } else if (callerApp == null || !callerApp.persistent) { 13866 try { 13867 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13868 intent.getAction())) { 13869 String msg = "Permission Denial: not allowed to send broadcast " 13870 + intent.getAction() + " from pid=" 13871 + callingPid + ", uid=" + callingUid; 13872 Slog.w(TAG, msg); 13873 throw new SecurityException(msg); 13874 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13875 // Special case for compatibility: we don't want apps to send this, 13876 // but historically it has not been protected and apps may be using it 13877 // to poke their own app widget. So, instead of making it protected, 13878 // just limit it to the caller. 13879 if (callerApp == null) { 13880 String msg = "Permission Denial: not allowed to send broadcast " 13881 + intent.getAction() + " from unknown caller."; 13882 Slog.w(TAG, msg); 13883 throw new SecurityException(msg); 13884 } else if (intent.getComponent() != null) { 13885 // They are good enough to send to an explicit component... verify 13886 // it is being sent to the calling app. 13887 if (!intent.getComponent().getPackageName().equals( 13888 callerApp.info.packageName)) { 13889 String msg = "Permission Denial: not allowed to send broadcast " 13890 + intent.getAction() + " to " 13891 + intent.getComponent().getPackageName() + " from " 13892 + callerApp.info.packageName; 13893 Slog.w(TAG, msg); 13894 throw new SecurityException(msg); 13895 } 13896 } else { 13897 // Limit broadcast to their own package. 13898 intent.setPackage(callerApp.info.packageName); 13899 } 13900 } 13901 } catch (RemoteException e) { 13902 Slog.w(TAG, "Remote exception", e); 13903 return ActivityManager.BROADCAST_SUCCESS; 13904 } 13905 } 13906 13907 // Handle special intents: if this broadcast is from the package 13908 // manager about a package being removed, we need to remove all of 13909 // its activities from the history stack. 13910 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13911 intent.getAction()); 13912 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13913 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13914 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13915 || uidRemoved) { 13916 if (checkComponentPermission( 13917 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13918 callingPid, callingUid, -1, true) 13919 == PackageManager.PERMISSION_GRANTED) { 13920 if (uidRemoved) { 13921 final Bundle intentExtras = intent.getExtras(); 13922 final int uid = intentExtras != null 13923 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13924 if (uid >= 0) { 13925 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13926 synchronized (bs) { 13927 bs.removeUidStatsLocked(uid); 13928 } 13929 mAppOpsService.uidRemoved(uid); 13930 } 13931 } else { 13932 // If resources are unavailable just force stop all 13933 // those packages and flush the attribute cache as well. 13934 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13935 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13936 if (list != null && (list.length > 0)) { 13937 for (String pkg : list) { 13938 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13939 "storage unmount"); 13940 } 13941 sendPackageBroadcastLocked( 13942 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13943 } 13944 } else { 13945 Uri data = intent.getData(); 13946 String ssp; 13947 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13948 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13949 intent.getAction()); 13950 boolean fullUninstall = removed && 13951 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13952 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13953 forceStopPackageLocked(ssp, UserHandle.getAppId( 13954 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13955 false, fullUninstall, userId, 13956 removed ? "pkg removed" : "pkg changed"); 13957 } 13958 if (removed) { 13959 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13960 new String[] {ssp}, userId); 13961 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13962 mAppOpsService.packageRemoved( 13963 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13964 13965 // Remove all permissions granted from/to this package 13966 removeUriPermissionsForPackageLocked(ssp, userId, true); 13967 } 13968 } 13969 } 13970 } 13971 } 13972 } else { 13973 String msg = "Permission Denial: " + intent.getAction() 13974 + " broadcast from " + callerPackage + " (pid=" + callingPid 13975 + ", uid=" + callingUid + ")" 13976 + " requires " 13977 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13978 Slog.w(TAG, msg); 13979 throw new SecurityException(msg); 13980 } 13981 13982 // Special case for adding a package: by default turn on compatibility 13983 // mode. 13984 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13985 Uri data = intent.getData(); 13986 String ssp; 13987 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13988 mCompatModePackages.handlePackageAddedLocked(ssp, 13989 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13990 } 13991 } 13992 13993 /* 13994 * If this is the time zone changed action, queue up a message that will reset the timezone 13995 * of all currently running processes. This message will get queued up before the broadcast 13996 * happens. 13997 */ 13998 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13999 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14000 } 14001 14002 /* 14003 * If the user set the time, let all running processes know. 14004 */ 14005 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14006 final int is24Hour = intent.getBooleanExtra( 14007 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14008 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14009 } 14010 14011 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14012 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14013 } 14014 14015 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14016 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14017 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14018 } 14019 14020 // Add to the sticky list if requested. 14021 if (sticky) { 14022 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14023 callingPid, callingUid) 14024 != PackageManager.PERMISSION_GRANTED) { 14025 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14026 + callingPid + ", uid=" + callingUid 14027 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14028 Slog.w(TAG, msg); 14029 throw new SecurityException(msg); 14030 } 14031 if (requiredPermission != null) { 14032 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14033 + " and enforce permission " + requiredPermission); 14034 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14035 } 14036 if (intent.getComponent() != null) { 14037 throw new SecurityException( 14038 "Sticky broadcasts can't target a specific component"); 14039 } 14040 // We use userId directly here, since the "all" target is maintained 14041 // as a separate set of sticky broadcasts. 14042 if (userId != UserHandle.USER_ALL) { 14043 // But first, if this is not a broadcast to all users, then 14044 // make sure it doesn't conflict with an existing broadcast to 14045 // all users. 14046 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14047 UserHandle.USER_ALL); 14048 if (stickies != null) { 14049 ArrayList<Intent> list = stickies.get(intent.getAction()); 14050 if (list != null) { 14051 int N = list.size(); 14052 int i; 14053 for (i=0; i<N; i++) { 14054 if (intent.filterEquals(list.get(i))) { 14055 throw new IllegalArgumentException( 14056 "Sticky broadcast " + intent + " for user " 14057 + userId + " conflicts with existing global broadcast"); 14058 } 14059 } 14060 } 14061 } 14062 } 14063 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14064 if (stickies == null) { 14065 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14066 mStickyBroadcasts.put(userId, stickies); 14067 } 14068 ArrayList<Intent> list = stickies.get(intent.getAction()); 14069 if (list == null) { 14070 list = new ArrayList<Intent>(); 14071 stickies.put(intent.getAction(), list); 14072 } 14073 int N = list.size(); 14074 int i; 14075 for (i=0; i<N; i++) { 14076 if (intent.filterEquals(list.get(i))) { 14077 // This sticky already exists, replace it. 14078 list.set(i, new Intent(intent)); 14079 break; 14080 } 14081 } 14082 if (i >= N) { 14083 list.add(new Intent(intent)); 14084 } 14085 } 14086 14087 int[] users; 14088 if (userId == UserHandle.USER_ALL) { 14089 // Caller wants broadcast to go to all started users. 14090 users = mStartedUserArray; 14091 } else { 14092 // Caller wants broadcast to go to one specific user. 14093 users = new int[] {userId}; 14094 } 14095 14096 // Figure out who all will receive this broadcast. 14097 List receivers = null; 14098 List<BroadcastFilter> registeredReceivers = null; 14099 // Need to resolve the intent to interested receivers... 14100 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14101 == 0) { 14102 receivers = collectReceiverComponents(intent, resolvedType, users); 14103 } 14104 if (intent.getComponent() == null) { 14105 registeredReceivers = mReceiverResolver.queryIntent(intent, 14106 resolvedType, false, userId); 14107 } 14108 14109 final boolean replacePending = 14110 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14111 14112 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14113 + " replacePending=" + replacePending); 14114 14115 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14116 if (!ordered && NR > 0) { 14117 // If we are not serializing this broadcast, then send the 14118 // registered receivers separately so they don't wait for the 14119 // components to be launched. 14120 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14121 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14122 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14123 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14124 ordered, sticky, false, userId); 14125 if (DEBUG_BROADCAST) Slog.v( 14126 TAG, "Enqueueing parallel broadcast " + r); 14127 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14128 if (!replaced) { 14129 queue.enqueueParallelBroadcastLocked(r); 14130 queue.scheduleBroadcastsLocked(); 14131 } 14132 registeredReceivers = null; 14133 NR = 0; 14134 } 14135 14136 // Merge into one list. 14137 int ir = 0; 14138 if (receivers != null) { 14139 // A special case for PACKAGE_ADDED: do not allow the package 14140 // being added to see this broadcast. This prevents them from 14141 // using this as a back door to get run as soon as they are 14142 // installed. Maybe in the future we want to have a special install 14143 // broadcast or such for apps, but we'd like to deliberately make 14144 // this decision. 14145 String skipPackages[] = null; 14146 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14147 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14148 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14149 Uri data = intent.getData(); 14150 if (data != null) { 14151 String pkgName = data.getSchemeSpecificPart(); 14152 if (pkgName != null) { 14153 skipPackages = new String[] { pkgName }; 14154 } 14155 } 14156 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14157 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14158 } 14159 if (skipPackages != null && (skipPackages.length > 0)) { 14160 for (String skipPackage : skipPackages) { 14161 if (skipPackage != null) { 14162 int NT = receivers.size(); 14163 for (int it=0; it<NT; it++) { 14164 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14165 if (curt.activityInfo.packageName.equals(skipPackage)) { 14166 receivers.remove(it); 14167 it--; 14168 NT--; 14169 } 14170 } 14171 } 14172 } 14173 } 14174 14175 int NT = receivers != null ? receivers.size() : 0; 14176 int it = 0; 14177 ResolveInfo curt = null; 14178 BroadcastFilter curr = null; 14179 while (it < NT && ir < NR) { 14180 if (curt == null) { 14181 curt = (ResolveInfo)receivers.get(it); 14182 } 14183 if (curr == null) { 14184 curr = registeredReceivers.get(ir); 14185 } 14186 if (curr.getPriority() >= curt.priority) { 14187 // Insert this broadcast record into the final list. 14188 receivers.add(it, curr); 14189 ir++; 14190 curr = null; 14191 it++; 14192 NT++; 14193 } else { 14194 // Skip to the next ResolveInfo in the final list. 14195 it++; 14196 curt = null; 14197 } 14198 } 14199 } 14200 while (ir < NR) { 14201 if (receivers == null) { 14202 receivers = new ArrayList(); 14203 } 14204 receivers.add(registeredReceivers.get(ir)); 14205 ir++; 14206 } 14207 14208 if ((receivers != null && receivers.size() > 0) 14209 || resultTo != null) { 14210 BroadcastQueue queue = broadcastQueueForIntent(intent); 14211 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14212 callerPackage, callingPid, callingUid, resolvedType, 14213 requiredPermission, appOp, receivers, resultTo, resultCode, 14214 resultData, map, ordered, sticky, false, userId); 14215 if (DEBUG_BROADCAST) Slog.v( 14216 TAG, "Enqueueing ordered broadcast " + r 14217 + ": prev had " + queue.mOrderedBroadcasts.size()); 14218 if (DEBUG_BROADCAST) { 14219 int seq = r.intent.getIntExtra("seq", -1); 14220 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14221 } 14222 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14223 if (!replaced) { 14224 queue.enqueueOrderedBroadcastLocked(r); 14225 queue.scheduleBroadcastsLocked(); 14226 } 14227 } 14228 14229 return ActivityManager.BROADCAST_SUCCESS; 14230 } 14231 14232 final Intent verifyBroadcastLocked(Intent intent) { 14233 // Refuse possible leaked file descriptors 14234 if (intent != null && intent.hasFileDescriptors() == true) { 14235 throw new IllegalArgumentException("File descriptors passed in Intent"); 14236 } 14237 14238 int flags = intent.getFlags(); 14239 14240 if (!mProcessesReady) { 14241 // if the caller really truly claims to know what they're doing, go 14242 // ahead and allow the broadcast without launching any receivers 14243 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14244 intent = new Intent(intent); 14245 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14246 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14247 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14248 + " before boot completion"); 14249 throw new IllegalStateException("Cannot broadcast before boot completed"); 14250 } 14251 } 14252 14253 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14254 throw new IllegalArgumentException( 14255 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14256 } 14257 14258 return intent; 14259 } 14260 14261 public final int broadcastIntent(IApplicationThread caller, 14262 Intent intent, String resolvedType, IIntentReceiver resultTo, 14263 int resultCode, String resultData, Bundle map, 14264 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14265 enforceNotIsolatedCaller("broadcastIntent"); 14266 synchronized(this) { 14267 intent = verifyBroadcastLocked(intent); 14268 14269 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14270 final int callingPid = Binder.getCallingPid(); 14271 final int callingUid = Binder.getCallingUid(); 14272 final long origId = Binder.clearCallingIdentity(); 14273 int res = broadcastIntentLocked(callerApp, 14274 callerApp != null ? callerApp.info.packageName : null, 14275 intent, resolvedType, resultTo, 14276 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14277 callingPid, callingUid, userId); 14278 Binder.restoreCallingIdentity(origId); 14279 return res; 14280 } 14281 } 14282 14283 int broadcastIntentInPackage(String packageName, int uid, 14284 Intent intent, String resolvedType, IIntentReceiver resultTo, 14285 int resultCode, String resultData, Bundle map, 14286 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14287 synchronized(this) { 14288 intent = verifyBroadcastLocked(intent); 14289 14290 final long origId = Binder.clearCallingIdentity(); 14291 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14292 resultTo, resultCode, resultData, map, requiredPermission, 14293 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14294 Binder.restoreCallingIdentity(origId); 14295 return res; 14296 } 14297 } 14298 14299 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14300 // Refuse possible leaked file descriptors 14301 if (intent != null && intent.hasFileDescriptors() == true) { 14302 throw new IllegalArgumentException("File descriptors passed in Intent"); 14303 } 14304 14305 userId = handleIncomingUser(Binder.getCallingPid(), 14306 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14307 14308 synchronized(this) { 14309 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14310 != PackageManager.PERMISSION_GRANTED) { 14311 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14312 + Binder.getCallingPid() 14313 + ", uid=" + Binder.getCallingUid() 14314 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14315 Slog.w(TAG, msg); 14316 throw new SecurityException(msg); 14317 } 14318 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14319 if (stickies != null) { 14320 ArrayList<Intent> list = stickies.get(intent.getAction()); 14321 if (list != null) { 14322 int N = list.size(); 14323 int i; 14324 for (i=0; i<N; i++) { 14325 if (intent.filterEquals(list.get(i))) { 14326 list.remove(i); 14327 break; 14328 } 14329 } 14330 if (list.size() <= 0) { 14331 stickies.remove(intent.getAction()); 14332 } 14333 } 14334 if (stickies.size() <= 0) { 14335 mStickyBroadcasts.remove(userId); 14336 } 14337 } 14338 } 14339 } 14340 14341 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14342 String resultData, Bundle resultExtras, boolean resultAbort) { 14343 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14344 if (r == null) { 14345 Slog.w(TAG, "finishReceiver called but not found on queue"); 14346 return false; 14347 } 14348 14349 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14350 } 14351 14352 void backgroundServicesFinishedLocked(int userId) { 14353 for (BroadcastQueue queue : mBroadcastQueues) { 14354 queue.backgroundServicesFinishedLocked(userId); 14355 } 14356 } 14357 14358 public void finishReceiver(IBinder who, int resultCode, String resultData, 14359 Bundle resultExtras, boolean resultAbort) { 14360 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14361 14362 // Refuse possible leaked file descriptors 14363 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14364 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14365 } 14366 14367 final long origId = Binder.clearCallingIdentity(); 14368 try { 14369 boolean doNext = false; 14370 BroadcastRecord r; 14371 14372 synchronized(this) { 14373 r = broadcastRecordForReceiverLocked(who); 14374 if (r != null) { 14375 doNext = r.queue.finishReceiverLocked(r, resultCode, 14376 resultData, resultExtras, resultAbort, true); 14377 } 14378 } 14379 14380 if (doNext) { 14381 r.queue.processNextBroadcast(false); 14382 } 14383 trimApplications(); 14384 } finally { 14385 Binder.restoreCallingIdentity(origId); 14386 } 14387 } 14388 14389 // ========================================================= 14390 // INSTRUMENTATION 14391 // ========================================================= 14392 14393 public boolean startInstrumentation(ComponentName className, 14394 String profileFile, int flags, Bundle arguments, 14395 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14396 int userId, String abiOverride) { 14397 enforceNotIsolatedCaller("startInstrumentation"); 14398 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14399 userId, false, true, "startInstrumentation", null); 14400 // Refuse possible leaked file descriptors 14401 if (arguments != null && arguments.hasFileDescriptors()) { 14402 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14403 } 14404 14405 synchronized(this) { 14406 InstrumentationInfo ii = null; 14407 ApplicationInfo ai = null; 14408 try { 14409 ii = mContext.getPackageManager().getInstrumentationInfo( 14410 className, STOCK_PM_FLAGS); 14411 ai = AppGlobals.getPackageManager().getApplicationInfo( 14412 ii.targetPackage, STOCK_PM_FLAGS, userId); 14413 } catch (PackageManager.NameNotFoundException e) { 14414 } catch (RemoteException e) { 14415 } 14416 if (ii == null) { 14417 reportStartInstrumentationFailure(watcher, className, 14418 "Unable to find instrumentation info for: " + className); 14419 return false; 14420 } 14421 if (ai == null) { 14422 reportStartInstrumentationFailure(watcher, className, 14423 "Unable to find instrumentation target package: " + ii.targetPackage); 14424 return false; 14425 } 14426 14427 int match = mContext.getPackageManager().checkSignatures( 14428 ii.targetPackage, ii.packageName); 14429 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14430 String msg = "Permission Denial: starting instrumentation " 14431 + className + " from pid=" 14432 + Binder.getCallingPid() 14433 + ", uid=" + Binder.getCallingPid() 14434 + " not allowed because package " + ii.packageName 14435 + " does not have a signature matching the target " 14436 + ii.targetPackage; 14437 reportStartInstrumentationFailure(watcher, className, msg); 14438 throw new SecurityException(msg); 14439 } 14440 14441 final long origId = Binder.clearCallingIdentity(); 14442 // Instrumentation can kill and relaunch even persistent processes 14443 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14444 "start instr"); 14445 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14446 app.instrumentationClass = className; 14447 app.instrumentationInfo = ai; 14448 app.instrumentationProfileFile = profileFile; 14449 app.instrumentationArguments = arguments; 14450 app.instrumentationWatcher = watcher; 14451 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14452 app.instrumentationResultClass = className; 14453 Binder.restoreCallingIdentity(origId); 14454 } 14455 14456 return true; 14457 } 14458 14459 /** 14460 * Report errors that occur while attempting to start Instrumentation. Always writes the 14461 * error to the logs, but if somebody is watching, send the report there too. This enables 14462 * the "am" command to report errors with more information. 14463 * 14464 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14465 * @param cn The component name of the instrumentation. 14466 * @param report The error report. 14467 */ 14468 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14469 ComponentName cn, String report) { 14470 Slog.w(TAG, report); 14471 try { 14472 if (watcher != null) { 14473 Bundle results = new Bundle(); 14474 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14475 results.putString("Error", report); 14476 watcher.instrumentationStatus(cn, -1, results); 14477 } 14478 } catch (RemoteException e) { 14479 Slog.w(TAG, e); 14480 } 14481 } 14482 14483 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14484 if (app.instrumentationWatcher != null) { 14485 try { 14486 // NOTE: IInstrumentationWatcher *must* be oneway here 14487 app.instrumentationWatcher.instrumentationFinished( 14488 app.instrumentationClass, 14489 resultCode, 14490 results); 14491 } catch (RemoteException e) { 14492 } 14493 } 14494 if (app.instrumentationUiAutomationConnection != null) { 14495 try { 14496 app.instrumentationUiAutomationConnection.shutdown(); 14497 } catch (RemoteException re) { 14498 /* ignore */ 14499 } 14500 // Only a UiAutomation can set this flag and now that 14501 // it is finished we make sure it is reset to its default. 14502 mUserIsMonkey = false; 14503 } 14504 app.instrumentationWatcher = null; 14505 app.instrumentationUiAutomationConnection = null; 14506 app.instrumentationClass = null; 14507 app.instrumentationInfo = null; 14508 app.instrumentationProfileFile = null; 14509 app.instrumentationArguments = null; 14510 14511 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14512 "finished inst"); 14513 } 14514 14515 public void finishInstrumentation(IApplicationThread target, 14516 int resultCode, Bundle results) { 14517 int userId = UserHandle.getCallingUserId(); 14518 // Refuse possible leaked file descriptors 14519 if (results != null && results.hasFileDescriptors()) { 14520 throw new IllegalArgumentException("File descriptors passed in Intent"); 14521 } 14522 14523 synchronized(this) { 14524 ProcessRecord app = getRecordForAppLocked(target); 14525 if (app == null) { 14526 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14527 return; 14528 } 14529 final long origId = Binder.clearCallingIdentity(); 14530 finishInstrumentationLocked(app, resultCode, results); 14531 Binder.restoreCallingIdentity(origId); 14532 } 14533 } 14534 14535 // ========================================================= 14536 // CONFIGURATION 14537 // ========================================================= 14538 14539 public ConfigurationInfo getDeviceConfigurationInfo() { 14540 ConfigurationInfo config = new ConfigurationInfo(); 14541 synchronized (this) { 14542 config.reqTouchScreen = mConfiguration.touchscreen; 14543 config.reqKeyboardType = mConfiguration.keyboard; 14544 config.reqNavigation = mConfiguration.navigation; 14545 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14546 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14547 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14548 } 14549 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14550 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14551 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14552 } 14553 config.reqGlEsVersion = GL_ES_VERSION; 14554 } 14555 return config; 14556 } 14557 14558 ActivityStack getFocusedStack() { 14559 return mStackSupervisor.getFocusedStack(); 14560 } 14561 14562 public Configuration getConfiguration() { 14563 Configuration ci; 14564 synchronized(this) { 14565 ci = new Configuration(mConfiguration); 14566 } 14567 return ci; 14568 } 14569 14570 public void updatePersistentConfiguration(Configuration values) { 14571 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14572 "updateConfiguration()"); 14573 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14574 "updateConfiguration()"); 14575 if (values == null) { 14576 throw new NullPointerException("Configuration must not be null"); 14577 } 14578 14579 synchronized(this) { 14580 final long origId = Binder.clearCallingIdentity(); 14581 updateConfigurationLocked(values, null, true, false); 14582 Binder.restoreCallingIdentity(origId); 14583 } 14584 } 14585 14586 public void updateConfiguration(Configuration values) { 14587 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14588 "updateConfiguration()"); 14589 14590 synchronized(this) { 14591 if (values == null && mWindowManager != null) { 14592 // sentinel: fetch the current configuration from the window manager 14593 values = mWindowManager.computeNewConfiguration(); 14594 } 14595 14596 if (mWindowManager != null) { 14597 mProcessList.applyDisplaySize(mWindowManager); 14598 } 14599 14600 final long origId = Binder.clearCallingIdentity(); 14601 if (values != null) { 14602 Settings.System.clearConfiguration(values); 14603 } 14604 updateConfigurationLocked(values, null, false, false); 14605 Binder.restoreCallingIdentity(origId); 14606 } 14607 } 14608 14609 /** 14610 * Do either or both things: (1) change the current configuration, and (2) 14611 * make sure the given activity is running with the (now) current 14612 * configuration. Returns true if the activity has been left running, or 14613 * false if <var>starting</var> is being destroyed to match the new 14614 * configuration. 14615 * @param persistent TODO 14616 */ 14617 boolean updateConfigurationLocked(Configuration values, 14618 ActivityRecord starting, boolean persistent, boolean initLocale) { 14619 int changes = 0; 14620 14621 if (values != null) { 14622 Configuration newConfig = new Configuration(mConfiguration); 14623 changes = newConfig.updateFrom(values); 14624 if (changes != 0) { 14625 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14626 Slog.i(TAG, "Updating configuration to: " + values); 14627 } 14628 14629 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14630 14631 if (values.locale != null && !initLocale) { 14632 saveLocaleLocked(values.locale, 14633 !values.locale.equals(mConfiguration.locale), 14634 values.userSetLocale); 14635 } 14636 14637 mConfigurationSeq++; 14638 if (mConfigurationSeq <= 0) { 14639 mConfigurationSeq = 1; 14640 } 14641 newConfig.seq = mConfigurationSeq; 14642 mConfiguration = newConfig; 14643 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14644 mUsageStatsService.noteStartConfig(newConfig); 14645 14646 final Configuration configCopy = new Configuration(mConfiguration); 14647 14648 // TODO: If our config changes, should we auto dismiss any currently 14649 // showing dialogs? 14650 mShowDialogs = shouldShowDialogs(newConfig); 14651 14652 AttributeCache ac = AttributeCache.instance(); 14653 if (ac != null) { 14654 ac.updateConfiguration(configCopy); 14655 } 14656 14657 // Make sure all resources in our process are updated 14658 // right now, so that anyone who is going to retrieve 14659 // resource values after we return will be sure to get 14660 // the new ones. This is especially important during 14661 // boot, where the first config change needs to guarantee 14662 // all resources have that config before following boot 14663 // code is executed. 14664 mSystemThread.applyConfigurationToResources(configCopy); 14665 14666 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14667 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14668 msg.obj = new Configuration(configCopy); 14669 mHandler.sendMessage(msg); 14670 } 14671 14672 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14673 ProcessRecord app = mLruProcesses.get(i); 14674 try { 14675 if (app.thread != null) { 14676 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14677 + app.processName + " new config " + mConfiguration); 14678 app.thread.scheduleConfigurationChanged(configCopy); 14679 } 14680 } catch (Exception e) { 14681 } 14682 } 14683 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14684 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14685 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14686 | Intent.FLAG_RECEIVER_FOREGROUND); 14687 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14688 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14689 Process.SYSTEM_UID, UserHandle.USER_ALL); 14690 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14691 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14692 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14693 broadcastIntentLocked(null, null, intent, 14694 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14695 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14696 } 14697 } 14698 } 14699 14700 boolean kept = true; 14701 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14702 // mainStack is null during startup. 14703 if (mainStack != null) { 14704 if (changes != 0 && starting == null) { 14705 // If the configuration changed, and the caller is not already 14706 // in the process of starting an activity, then find the top 14707 // activity to check if its configuration needs to change. 14708 starting = mainStack.topRunningActivityLocked(null); 14709 } 14710 14711 if (starting != null) { 14712 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14713 // And we need to make sure at this point that all other activities 14714 // are made visible with the correct configuration. 14715 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14716 } 14717 } 14718 14719 if (values != null && mWindowManager != null) { 14720 mWindowManager.setNewConfiguration(mConfiguration); 14721 } 14722 14723 return kept; 14724 } 14725 14726 /** 14727 * Decide based on the configuration whether we should shouw the ANR, 14728 * crash, etc dialogs. The idea is that if there is no affordnace to 14729 * press the on-screen buttons, we shouldn't show the dialog. 14730 * 14731 * A thought: SystemUI might also want to get told about this, the Power 14732 * dialog / global actions also might want different behaviors. 14733 */ 14734 private static final boolean shouldShowDialogs(Configuration config) { 14735 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14736 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14737 } 14738 14739 /** 14740 * Save the locale. You must be inside a synchronized (this) block. 14741 */ 14742 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14743 if(isDiff) { 14744 SystemProperties.set("user.language", l.getLanguage()); 14745 SystemProperties.set("user.region", l.getCountry()); 14746 } 14747 14748 if(isPersist) { 14749 SystemProperties.set("persist.sys.language", l.getLanguage()); 14750 SystemProperties.set("persist.sys.country", l.getCountry()); 14751 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14752 } 14753 } 14754 14755 @Override 14756 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14757 ActivityRecord srec = ActivityRecord.forToken(token); 14758 return srec != null && srec.task.affinity != null && 14759 srec.task.affinity.equals(destAffinity); 14760 } 14761 14762 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14763 Intent resultData) { 14764 14765 synchronized (this) { 14766 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14767 if (stack != null) { 14768 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14769 } 14770 return false; 14771 } 14772 } 14773 14774 public int getLaunchedFromUid(IBinder activityToken) { 14775 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14776 if (srec == null) { 14777 return -1; 14778 } 14779 return srec.launchedFromUid; 14780 } 14781 14782 public String getLaunchedFromPackage(IBinder activityToken) { 14783 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14784 if (srec == null) { 14785 return null; 14786 } 14787 return srec.launchedFromPackage; 14788 } 14789 14790 // ========================================================= 14791 // LIFETIME MANAGEMENT 14792 // ========================================================= 14793 14794 // Returns which broadcast queue the app is the current [or imminent] receiver 14795 // on, or 'null' if the app is not an active broadcast recipient. 14796 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14797 BroadcastRecord r = app.curReceiver; 14798 if (r != null) { 14799 return r.queue; 14800 } 14801 14802 // It's not the current receiver, but it might be starting up to become one 14803 synchronized (this) { 14804 for (BroadcastQueue queue : mBroadcastQueues) { 14805 r = queue.mPendingBroadcast; 14806 if (r != null && r.curApp == app) { 14807 // found it; report which queue it's in 14808 return queue; 14809 } 14810 } 14811 } 14812 14813 return null; 14814 } 14815 14816 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14817 boolean doingAll, long now) { 14818 if (mAdjSeq == app.adjSeq) { 14819 // This adjustment has already been computed. 14820 return app.curRawAdj; 14821 } 14822 14823 if (app.thread == null) { 14824 app.adjSeq = mAdjSeq; 14825 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14826 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14827 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14828 } 14829 14830 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14831 app.adjSource = null; 14832 app.adjTarget = null; 14833 app.empty = false; 14834 app.cached = false; 14835 14836 final int activitiesSize = app.activities.size(); 14837 14838 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14839 // The max adjustment doesn't allow this app to be anything 14840 // below foreground, so it is not worth doing work for it. 14841 app.adjType = "fixed"; 14842 app.adjSeq = mAdjSeq; 14843 app.curRawAdj = app.maxAdj; 14844 app.foregroundActivities = false; 14845 app.keeping = true; 14846 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14847 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14848 // System processes can do UI, and when they do we want to have 14849 // them trim their memory after the user leaves the UI. To 14850 // facilitate this, here we need to determine whether or not it 14851 // is currently showing UI. 14852 app.systemNoUi = true; 14853 if (app == TOP_APP) { 14854 app.systemNoUi = false; 14855 } else if (activitiesSize > 0) { 14856 for (int j = 0; j < activitiesSize; j++) { 14857 final ActivityRecord r = app.activities.get(j); 14858 if (r.visible) { 14859 app.systemNoUi = false; 14860 } 14861 } 14862 } 14863 if (!app.systemNoUi) { 14864 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14865 } 14866 return (app.curAdj=app.maxAdj); 14867 } 14868 14869 app.keeping = false; 14870 app.systemNoUi = false; 14871 14872 // Determine the importance of the process, starting with most 14873 // important to least, and assign an appropriate OOM adjustment. 14874 int adj; 14875 int schedGroup; 14876 int procState; 14877 boolean foregroundActivities = false; 14878 boolean interesting = false; 14879 BroadcastQueue queue; 14880 if (app == TOP_APP) { 14881 // The last app on the list is the foreground app. 14882 adj = ProcessList.FOREGROUND_APP_ADJ; 14883 schedGroup = Process.THREAD_GROUP_DEFAULT; 14884 app.adjType = "top-activity"; 14885 foregroundActivities = true; 14886 interesting = true; 14887 procState = ActivityManager.PROCESS_STATE_TOP; 14888 } else if (app.instrumentationClass != null) { 14889 // Don't want to kill running instrumentation. 14890 adj = ProcessList.FOREGROUND_APP_ADJ; 14891 schedGroup = Process.THREAD_GROUP_DEFAULT; 14892 app.adjType = "instrumentation"; 14893 interesting = true; 14894 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14895 } else if ((queue = isReceivingBroadcast(app)) != null) { 14896 // An app that is currently receiving a broadcast also 14897 // counts as being in the foreground for OOM killer purposes. 14898 // It's placed in a sched group based on the nature of the 14899 // broadcast as reflected by which queue it's active in. 14900 adj = ProcessList.FOREGROUND_APP_ADJ; 14901 schedGroup = (queue == mFgBroadcastQueue) 14902 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14903 app.adjType = "broadcast"; 14904 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14905 } else if (app.executingServices.size() > 0) { 14906 // An app that is currently executing a service callback also 14907 // counts as being in the foreground. 14908 adj = ProcessList.FOREGROUND_APP_ADJ; 14909 schedGroup = app.execServicesFg ? 14910 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14911 app.adjType = "exec-service"; 14912 procState = ActivityManager.PROCESS_STATE_SERVICE; 14913 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14914 } else { 14915 // As far as we know the process is empty. We may change our mind later. 14916 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14917 // At this point we don't actually know the adjustment. Use the cached adj 14918 // value that the caller wants us to. 14919 adj = cachedAdj; 14920 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14921 app.cached = true; 14922 app.empty = true; 14923 app.adjType = "cch-empty"; 14924 } 14925 14926 // Examine all activities if not already foreground. 14927 if (!foregroundActivities && activitiesSize > 0) { 14928 for (int j = 0; j < activitiesSize; j++) { 14929 final ActivityRecord r = app.activities.get(j); 14930 if (r.app != app) { 14931 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14932 + app + "?!?"); 14933 continue; 14934 } 14935 if (r.visible) { 14936 // App has a visible activity; only upgrade adjustment. 14937 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14938 adj = ProcessList.VISIBLE_APP_ADJ; 14939 app.adjType = "visible"; 14940 } 14941 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14942 procState = ActivityManager.PROCESS_STATE_TOP; 14943 } 14944 schedGroup = Process.THREAD_GROUP_DEFAULT; 14945 app.cached = false; 14946 app.empty = false; 14947 foregroundActivities = true; 14948 break; 14949 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14950 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14951 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14952 app.adjType = "pausing"; 14953 } 14954 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14955 procState = ActivityManager.PROCESS_STATE_TOP; 14956 } 14957 schedGroup = Process.THREAD_GROUP_DEFAULT; 14958 app.cached = false; 14959 app.empty = false; 14960 foregroundActivities = true; 14961 } else if (r.state == ActivityState.STOPPING) { 14962 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14963 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14964 app.adjType = "stopping"; 14965 } 14966 // For the process state, we will at this point consider the 14967 // process to be cached. It will be cached either as an activity 14968 // or empty depending on whether the activity is finishing. We do 14969 // this so that we can treat the process as cached for purposes of 14970 // memory trimming (determing current memory level, trim command to 14971 // send to process) since there can be an arbitrary number of stopping 14972 // processes and they should soon all go into the cached state. 14973 if (!r.finishing) { 14974 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14975 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14976 } 14977 } 14978 app.cached = false; 14979 app.empty = false; 14980 foregroundActivities = true; 14981 } else { 14982 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14983 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14984 app.adjType = "cch-act"; 14985 } 14986 } 14987 } 14988 } 14989 14990 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14991 if (app.foregroundServices) { 14992 // The user is aware of this app, so make it visible. 14993 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14994 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14995 app.cached = false; 14996 app.adjType = "fg-service"; 14997 schedGroup = Process.THREAD_GROUP_DEFAULT; 14998 } else if (app.forcingToForeground != null) { 14999 // The user is aware of this app, so make it visible. 15000 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15001 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15002 app.cached = false; 15003 app.adjType = "force-fg"; 15004 app.adjSource = app.forcingToForeground; 15005 schedGroup = Process.THREAD_GROUP_DEFAULT; 15006 } 15007 } 15008 15009 if (app.foregroundServices) { 15010 interesting = true; 15011 } 15012 15013 if (app == mHeavyWeightProcess) { 15014 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15015 // We don't want to kill the current heavy-weight process. 15016 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15017 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15018 app.cached = false; 15019 app.adjType = "heavy"; 15020 } 15021 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15022 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15023 } 15024 } 15025 15026 if (app == mHomeProcess) { 15027 if (adj > ProcessList.HOME_APP_ADJ) { 15028 // This process is hosting what we currently consider to be the 15029 // home app, so we don't want to let it go into the background. 15030 adj = ProcessList.HOME_APP_ADJ; 15031 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15032 app.cached = false; 15033 app.adjType = "home"; 15034 } 15035 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15036 procState = ActivityManager.PROCESS_STATE_HOME; 15037 } 15038 } 15039 15040 if (app == mPreviousProcess && app.activities.size() > 0) { 15041 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15042 // This was the previous process that showed UI to the user. 15043 // We want to try to keep it around more aggressively, to give 15044 // a good experience around switching between two apps. 15045 adj = ProcessList.PREVIOUS_APP_ADJ; 15046 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15047 app.cached = false; 15048 app.adjType = "previous"; 15049 } 15050 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15051 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15052 } 15053 } 15054 15055 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15056 + " reason=" + app.adjType); 15057 15058 // By default, we use the computed adjustment. It may be changed if 15059 // there are applications dependent on our services or providers, but 15060 // this gives us a baseline and makes sure we don't get into an 15061 // infinite recursion. 15062 app.adjSeq = mAdjSeq; 15063 app.curRawAdj = adj; 15064 app.hasStartedServices = false; 15065 15066 if (mBackupTarget != null && app == mBackupTarget.app) { 15067 // If possible we want to avoid killing apps while they're being backed up 15068 if (adj > ProcessList.BACKUP_APP_ADJ) { 15069 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15070 adj = ProcessList.BACKUP_APP_ADJ; 15071 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15072 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15073 } 15074 app.adjType = "backup"; 15075 app.cached = false; 15076 } 15077 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15078 procState = ActivityManager.PROCESS_STATE_BACKUP; 15079 } 15080 } 15081 15082 boolean mayBeTop = false; 15083 15084 for (int is = app.services.size()-1; 15085 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15086 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15087 || procState > ActivityManager.PROCESS_STATE_TOP); 15088 is--) { 15089 ServiceRecord s = app.services.valueAt(is); 15090 if (s.startRequested) { 15091 app.hasStartedServices = true; 15092 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15093 procState = ActivityManager.PROCESS_STATE_SERVICE; 15094 } 15095 if (app.hasShownUi && app != mHomeProcess) { 15096 // If this process has shown some UI, let it immediately 15097 // go to the LRU list because it may be pretty heavy with 15098 // UI stuff. We'll tag it with a label just to help 15099 // debug and understand what is going on. 15100 if (adj > ProcessList.SERVICE_ADJ) { 15101 app.adjType = "cch-started-ui-services"; 15102 } 15103 } else { 15104 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15105 // This service has seen some activity within 15106 // recent memory, so we will keep its process ahead 15107 // of the background processes. 15108 if (adj > ProcessList.SERVICE_ADJ) { 15109 adj = ProcessList.SERVICE_ADJ; 15110 app.adjType = "started-services"; 15111 app.cached = false; 15112 } 15113 } 15114 // If we have let the service slide into the background 15115 // state, still have some text describing what it is doing 15116 // even though the service no longer has an impact. 15117 if (adj > ProcessList.SERVICE_ADJ) { 15118 app.adjType = "cch-started-services"; 15119 } 15120 } 15121 // Don't kill this process because it is doing work; it 15122 // has said it is doing work. 15123 app.keeping = true; 15124 } 15125 for (int conni = s.connections.size()-1; 15126 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15127 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15128 || procState > ActivityManager.PROCESS_STATE_TOP); 15129 conni--) { 15130 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15131 for (int i = 0; 15132 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15133 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15134 || procState > ActivityManager.PROCESS_STATE_TOP); 15135 i++) { 15136 // XXX should compute this based on the max of 15137 // all connected clients. 15138 ConnectionRecord cr = clist.get(i); 15139 if (cr.binding.client == app) { 15140 // Binding to ourself is not interesting. 15141 continue; 15142 } 15143 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15144 ProcessRecord client = cr.binding.client; 15145 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15146 TOP_APP, doingAll, now); 15147 int clientProcState = client.curProcState; 15148 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15149 // If the other app is cached for any reason, for purposes here 15150 // we are going to consider it empty. The specific cached state 15151 // doesn't propagate except under certain conditions. 15152 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15153 } 15154 String adjType = null; 15155 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15156 // Not doing bind OOM management, so treat 15157 // this guy more like a started service. 15158 if (app.hasShownUi && app != mHomeProcess) { 15159 // If this process has shown some UI, let it immediately 15160 // go to the LRU list because it may be pretty heavy with 15161 // UI stuff. We'll tag it with a label just to help 15162 // debug and understand what is going on. 15163 if (adj > clientAdj) { 15164 adjType = "cch-bound-ui-services"; 15165 } 15166 app.cached = false; 15167 clientAdj = adj; 15168 clientProcState = procState; 15169 } else { 15170 if (now >= (s.lastActivity 15171 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15172 // This service has not seen activity within 15173 // recent memory, so allow it to drop to the 15174 // LRU list if there is no other reason to keep 15175 // it around. We'll also tag it with a label just 15176 // to help debug and undertand what is going on. 15177 if (adj > clientAdj) { 15178 adjType = "cch-bound-services"; 15179 } 15180 clientAdj = adj; 15181 } 15182 } 15183 } 15184 if (adj > clientAdj) { 15185 // If this process has recently shown UI, and 15186 // the process that is binding to it is less 15187 // important than being visible, then we don't 15188 // care about the binding as much as we care 15189 // about letting this process get into the LRU 15190 // list to be killed and restarted if needed for 15191 // memory. 15192 if (app.hasShownUi && app != mHomeProcess 15193 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15194 adjType = "cch-bound-ui-services"; 15195 } else { 15196 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15197 |Context.BIND_IMPORTANT)) != 0) { 15198 adj = clientAdj; 15199 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15200 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15201 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15202 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15203 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15204 adj = clientAdj; 15205 } else { 15206 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15207 adj = ProcessList.VISIBLE_APP_ADJ; 15208 } 15209 } 15210 if (!client.cached) { 15211 app.cached = false; 15212 } 15213 if (client.keeping) { 15214 app.keeping = true; 15215 } 15216 adjType = "service"; 15217 } 15218 } 15219 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15220 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15221 schedGroup = Process.THREAD_GROUP_DEFAULT; 15222 } 15223 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15224 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15225 // Special handling of clients who are in the top state. 15226 // We *may* want to consider this process to be in the 15227 // top state as well, but only if there is not another 15228 // reason for it to be running. Being on the top is a 15229 // special state, meaning you are specifically running 15230 // for the current top app. If the process is already 15231 // running in the background for some other reason, it 15232 // is more important to continue considering it to be 15233 // in the background state. 15234 mayBeTop = true; 15235 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15236 } else { 15237 // Special handling for above-top states (persistent 15238 // processes). These should not bring the current process 15239 // into the top state, since they are not on top. Instead 15240 // give them the best state after that. 15241 clientProcState = 15242 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15243 } 15244 } 15245 } else { 15246 if (clientProcState < 15247 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15248 clientProcState = 15249 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15250 } 15251 } 15252 if (procState > clientProcState) { 15253 procState = clientProcState; 15254 } 15255 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15256 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15257 app.pendingUiClean = true; 15258 } 15259 if (adjType != null) { 15260 app.adjType = adjType; 15261 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15262 .REASON_SERVICE_IN_USE; 15263 app.adjSource = cr.binding.client; 15264 app.adjSourceOom = clientAdj; 15265 app.adjTarget = s.name; 15266 } 15267 } 15268 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15269 app.treatLikeActivity = true; 15270 } 15271 final ActivityRecord a = cr.activity; 15272 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15273 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15274 (a.visible || a.state == ActivityState.RESUMED 15275 || a.state == ActivityState.PAUSING)) { 15276 adj = ProcessList.FOREGROUND_APP_ADJ; 15277 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15278 schedGroup = Process.THREAD_GROUP_DEFAULT; 15279 } 15280 app.cached = false; 15281 app.adjType = "service"; 15282 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15283 .REASON_SERVICE_IN_USE; 15284 app.adjSource = a; 15285 app.adjSourceOom = adj; 15286 app.adjTarget = s.name; 15287 } 15288 } 15289 } 15290 } 15291 } 15292 15293 for (int provi = app.pubProviders.size()-1; 15294 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15295 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15296 || procState > ActivityManager.PROCESS_STATE_TOP); 15297 provi--) { 15298 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15299 for (int i = cpr.connections.size()-1; 15300 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15301 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15302 || procState > ActivityManager.PROCESS_STATE_TOP); 15303 i--) { 15304 ContentProviderConnection conn = cpr.connections.get(i); 15305 ProcessRecord client = conn.client; 15306 if (client == app) { 15307 // Being our own client is not interesting. 15308 continue; 15309 } 15310 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15311 int clientProcState = client.curProcState; 15312 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15313 // If the other app is cached for any reason, for purposes here 15314 // we are going to consider it empty. 15315 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15316 } 15317 if (adj > clientAdj) { 15318 if (app.hasShownUi && app != mHomeProcess 15319 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15320 app.adjType = "cch-ui-provider"; 15321 } else { 15322 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15323 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15324 app.adjType = "provider"; 15325 } 15326 app.cached &= client.cached; 15327 app.keeping |= client.keeping; 15328 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15329 .REASON_PROVIDER_IN_USE; 15330 app.adjSource = client; 15331 app.adjSourceOom = clientAdj; 15332 app.adjTarget = cpr.name; 15333 } 15334 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15335 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15336 // Special handling of clients who are in the top state. 15337 // We *may* want to consider this process to be in the 15338 // top state as well, but only if there is not another 15339 // reason for it to be running. Being on the top is a 15340 // special state, meaning you are specifically running 15341 // for the current top app. If the process is already 15342 // running in the background for some other reason, it 15343 // is more important to continue considering it to be 15344 // in the background state. 15345 mayBeTop = true; 15346 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15347 } else { 15348 // Special handling for above-top states (persistent 15349 // processes). These should not bring the current process 15350 // into the top state, since they are not on top. Instead 15351 // give them the best state after that. 15352 clientProcState = 15353 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15354 } 15355 } 15356 if (procState > clientProcState) { 15357 procState = clientProcState; 15358 } 15359 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15360 schedGroup = Process.THREAD_GROUP_DEFAULT; 15361 } 15362 } 15363 // If the provider has external (non-framework) process 15364 // dependencies, ensure that its adjustment is at least 15365 // FOREGROUND_APP_ADJ. 15366 if (cpr.hasExternalProcessHandles()) { 15367 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15368 adj = ProcessList.FOREGROUND_APP_ADJ; 15369 schedGroup = Process.THREAD_GROUP_DEFAULT; 15370 app.cached = false; 15371 app.keeping = true; 15372 app.adjType = "provider"; 15373 app.adjTarget = cpr.name; 15374 } 15375 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15376 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15377 } 15378 } 15379 } 15380 15381 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15382 // A client of one of our services or providers is in the top state. We 15383 // *may* want to be in the top state, but not if we are already running in 15384 // the background for some other reason. For the decision here, we are going 15385 // to pick out a few specific states that we want to remain in when a client 15386 // is top (states that tend to be longer-term) and otherwise allow it to go 15387 // to the top state. 15388 switch (procState) { 15389 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15390 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15391 case ActivityManager.PROCESS_STATE_SERVICE: 15392 // These all are longer-term states, so pull them up to the top 15393 // of the background states, but not all the way to the top state. 15394 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15395 break; 15396 default: 15397 // Otherwise, top is a better choice, so take it. 15398 procState = ActivityManager.PROCESS_STATE_TOP; 15399 break; 15400 } 15401 } 15402 15403 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15404 if (app.hasClientActivities) { 15405 // This is a cached process, but with client activities. Mark it so. 15406 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15407 app.adjType = "cch-client-act"; 15408 } else if (app.treatLikeActivity) { 15409 // This is a cached process, but somebody wants us to treat it like it has 15410 // an activity, okay! 15411 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15412 app.adjType = "cch-as-act"; 15413 } 15414 } 15415 15416 if (adj == ProcessList.SERVICE_ADJ) { 15417 if (doingAll) { 15418 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15419 mNewNumServiceProcs++; 15420 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15421 if (!app.serviceb) { 15422 // This service isn't far enough down on the LRU list to 15423 // normally be a B service, but if we are low on RAM and it 15424 // is large we want to force it down since we would prefer to 15425 // keep launcher over it. 15426 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15427 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15428 app.serviceHighRam = true; 15429 app.serviceb = true; 15430 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15431 } else { 15432 mNewNumAServiceProcs++; 15433 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15434 } 15435 } else { 15436 app.serviceHighRam = false; 15437 } 15438 } 15439 if (app.serviceb) { 15440 adj = ProcessList.SERVICE_B_ADJ; 15441 } 15442 } 15443 15444 app.curRawAdj = adj; 15445 15446 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15447 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15448 if (adj > app.maxAdj) { 15449 adj = app.maxAdj; 15450 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15451 schedGroup = Process.THREAD_GROUP_DEFAULT; 15452 } 15453 } 15454 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15455 app.keeping = true; 15456 } 15457 15458 // Do final modification to adj. Everything we do between here and applying 15459 // the final setAdj must be done in this function, because we will also use 15460 // it when computing the final cached adj later. Note that we don't need to 15461 // worry about this for max adj above, since max adj will always be used to 15462 // keep it out of the cached vaues. 15463 app.curAdj = app.modifyRawOomAdj(adj); 15464 app.curSchedGroup = schedGroup; 15465 app.curProcState = procState; 15466 app.foregroundActivities = foregroundActivities; 15467 15468 return app.curRawAdj; 15469 } 15470 15471 /** 15472 * Schedule PSS collection of a process. 15473 */ 15474 void requestPssLocked(ProcessRecord proc, int procState) { 15475 if (mPendingPssProcesses.contains(proc)) { 15476 return; 15477 } 15478 if (mPendingPssProcesses.size() == 0) { 15479 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15480 } 15481 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15482 proc.pssProcState = procState; 15483 mPendingPssProcesses.add(proc); 15484 } 15485 15486 /** 15487 * Schedule PSS collection of all processes. 15488 */ 15489 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15490 if (!always) { 15491 if (now < (mLastFullPssTime + 15492 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15493 return; 15494 } 15495 } 15496 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15497 mLastFullPssTime = now; 15498 mFullPssPending = true; 15499 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15500 mPendingPssProcesses.clear(); 15501 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15502 ProcessRecord app = mLruProcesses.get(i); 15503 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15504 app.pssProcState = app.setProcState; 15505 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15506 isSleeping(), now); 15507 mPendingPssProcesses.add(app); 15508 } 15509 } 15510 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15511 } 15512 15513 /** 15514 * Ask a given process to GC right now. 15515 */ 15516 final void performAppGcLocked(ProcessRecord app) { 15517 try { 15518 app.lastRequestedGc = SystemClock.uptimeMillis(); 15519 if (app.thread != null) { 15520 if (app.reportLowMemory) { 15521 app.reportLowMemory = false; 15522 app.thread.scheduleLowMemory(); 15523 } else { 15524 app.thread.processInBackground(); 15525 } 15526 } 15527 } catch (Exception e) { 15528 // whatever. 15529 } 15530 } 15531 15532 /** 15533 * Returns true if things are idle enough to perform GCs. 15534 */ 15535 private final boolean canGcNowLocked() { 15536 boolean processingBroadcasts = false; 15537 for (BroadcastQueue q : mBroadcastQueues) { 15538 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15539 processingBroadcasts = true; 15540 } 15541 } 15542 return !processingBroadcasts 15543 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15544 } 15545 15546 /** 15547 * Perform GCs on all processes that are waiting for it, but only 15548 * if things are idle. 15549 */ 15550 final void performAppGcsLocked() { 15551 final int N = mProcessesToGc.size(); 15552 if (N <= 0) { 15553 return; 15554 } 15555 if (canGcNowLocked()) { 15556 while (mProcessesToGc.size() > 0) { 15557 ProcessRecord proc = mProcessesToGc.remove(0); 15558 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15559 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15560 <= SystemClock.uptimeMillis()) { 15561 // To avoid spamming the system, we will GC processes one 15562 // at a time, waiting a few seconds between each. 15563 performAppGcLocked(proc); 15564 scheduleAppGcsLocked(); 15565 return; 15566 } else { 15567 // It hasn't been long enough since we last GCed this 15568 // process... put it in the list to wait for its time. 15569 addProcessToGcListLocked(proc); 15570 break; 15571 } 15572 } 15573 } 15574 15575 scheduleAppGcsLocked(); 15576 } 15577 } 15578 15579 /** 15580 * If all looks good, perform GCs on all processes waiting for them. 15581 */ 15582 final void performAppGcsIfAppropriateLocked() { 15583 if (canGcNowLocked()) { 15584 performAppGcsLocked(); 15585 return; 15586 } 15587 // Still not idle, wait some more. 15588 scheduleAppGcsLocked(); 15589 } 15590 15591 /** 15592 * Schedule the execution of all pending app GCs. 15593 */ 15594 final void scheduleAppGcsLocked() { 15595 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15596 15597 if (mProcessesToGc.size() > 0) { 15598 // Schedule a GC for the time to the next process. 15599 ProcessRecord proc = mProcessesToGc.get(0); 15600 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15601 15602 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15603 long now = SystemClock.uptimeMillis(); 15604 if (when < (now+GC_TIMEOUT)) { 15605 when = now + GC_TIMEOUT; 15606 } 15607 mHandler.sendMessageAtTime(msg, when); 15608 } 15609 } 15610 15611 /** 15612 * Add a process to the array of processes waiting to be GCed. Keeps the 15613 * list in sorted order by the last GC time. The process can't already be 15614 * on the list. 15615 */ 15616 final void addProcessToGcListLocked(ProcessRecord proc) { 15617 boolean added = false; 15618 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15619 if (mProcessesToGc.get(i).lastRequestedGc < 15620 proc.lastRequestedGc) { 15621 added = true; 15622 mProcessesToGc.add(i+1, proc); 15623 break; 15624 } 15625 } 15626 if (!added) { 15627 mProcessesToGc.add(0, proc); 15628 } 15629 } 15630 15631 /** 15632 * Set up to ask a process to GC itself. This will either do it 15633 * immediately, or put it on the list of processes to gc the next 15634 * time things are idle. 15635 */ 15636 final void scheduleAppGcLocked(ProcessRecord app) { 15637 long now = SystemClock.uptimeMillis(); 15638 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15639 return; 15640 } 15641 if (!mProcessesToGc.contains(app)) { 15642 addProcessToGcListLocked(app); 15643 scheduleAppGcsLocked(); 15644 } 15645 } 15646 15647 final void checkExcessivePowerUsageLocked(boolean doKills) { 15648 updateCpuStatsNow(); 15649 15650 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15651 boolean doWakeKills = doKills; 15652 boolean doCpuKills = doKills; 15653 if (mLastPowerCheckRealtime == 0) { 15654 doWakeKills = false; 15655 } 15656 if (mLastPowerCheckUptime == 0) { 15657 doCpuKills = false; 15658 } 15659 if (stats.isScreenOn()) { 15660 doWakeKills = false; 15661 } 15662 final long curRealtime = SystemClock.elapsedRealtime(); 15663 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15664 final long curUptime = SystemClock.uptimeMillis(); 15665 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15666 mLastPowerCheckRealtime = curRealtime; 15667 mLastPowerCheckUptime = curUptime; 15668 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15669 doWakeKills = false; 15670 } 15671 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15672 doCpuKills = false; 15673 } 15674 int i = mLruProcesses.size(); 15675 while (i > 0) { 15676 i--; 15677 ProcessRecord app = mLruProcesses.get(i); 15678 if (!app.keeping) { 15679 long wtime; 15680 synchronized (stats) { 15681 wtime = stats.getProcessWakeTime(app.info.uid, 15682 app.pid, curRealtime); 15683 } 15684 long wtimeUsed = wtime - app.lastWakeTime; 15685 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15686 if (DEBUG_POWER) { 15687 StringBuilder sb = new StringBuilder(128); 15688 sb.append("Wake for "); 15689 app.toShortString(sb); 15690 sb.append(": over "); 15691 TimeUtils.formatDuration(realtimeSince, sb); 15692 sb.append(" used "); 15693 TimeUtils.formatDuration(wtimeUsed, sb); 15694 sb.append(" ("); 15695 sb.append((wtimeUsed*100)/realtimeSince); 15696 sb.append("%)"); 15697 Slog.i(TAG, sb.toString()); 15698 sb.setLength(0); 15699 sb.append("CPU for "); 15700 app.toShortString(sb); 15701 sb.append(": over "); 15702 TimeUtils.formatDuration(uptimeSince, sb); 15703 sb.append(" used "); 15704 TimeUtils.formatDuration(cputimeUsed, sb); 15705 sb.append(" ("); 15706 sb.append((cputimeUsed*100)/uptimeSince); 15707 sb.append("%)"); 15708 Slog.i(TAG, sb.toString()); 15709 } 15710 // If a process has held a wake lock for more 15711 // than 50% of the time during this period, 15712 // that sounds bad. Kill! 15713 if (doWakeKills && realtimeSince > 0 15714 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15715 synchronized (stats) { 15716 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15717 realtimeSince, wtimeUsed); 15718 } 15719 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15720 + " during " + realtimeSince); 15721 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15722 } else if (doCpuKills && uptimeSince > 0 15723 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15724 synchronized (stats) { 15725 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15726 uptimeSince, cputimeUsed); 15727 } 15728 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15729 + " during " + uptimeSince); 15730 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15731 } else { 15732 app.lastWakeTime = wtime; 15733 app.lastCpuTime = app.curCpuTime; 15734 } 15735 } 15736 } 15737 } 15738 15739 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15740 ProcessRecord TOP_APP, boolean doingAll, long now) { 15741 boolean success = true; 15742 15743 if (app.curRawAdj != app.setRawAdj) { 15744 if (wasKeeping && !app.keeping) { 15745 // This app is no longer something we want to keep. Note 15746 // its current wake lock time to later know to kill it if 15747 // it is not behaving well. 15748 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15749 synchronized (stats) { 15750 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15751 app.pid, SystemClock.elapsedRealtime()); 15752 } 15753 app.lastCpuTime = app.curCpuTime; 15754 } 15755 15756 app.setRawAdj = app.curRawAdj; 15757 } 15758 15759 int changes = 0; 15760 15761 if (app.curAdj != app.setAdj) { 15762 ProcessList.setOomAdj(app.pid, app.curAdj); 15763 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15764 TAG, "Set " + app.pid + " " + app.processName + 15765 " adj " + app.curAdj + ": " + app.adjType); 15766 app.setAdj = app.curAdj; 15767 } 15768 15769 if (app.setSchedGroup != app.curSchedGroup) { 15770 app.setSchedGroup = app.curSchedGroup; 15771 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15772 "Setting process group of " + app.processName 15773 + " to " + app.curSchedGroup); 15774 if (app.waitingToKill != null && 15775 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15776 killUnneededProcessLocked(app, app.waitingToKill); 15777 success = false; 15778 } else { 15779 if (true) { 15780 long oldId = Binder.clearCallingIdentity(); 15781 try { 15782 Process.setProcessGroup(app.pid, app.curSchedGroup); 15783 } catch (Exception e) { 15784 Slog.w(TAG, "Failed setting process group of " + app.pid 15785 + " to " + app.curSchedGroup); 15786 e.printStackTrace(); 15787 } finally { 15788 Binder.restoreCallingIdentity(oldId); 15789 } 15790 } else { 15791 if (app.thread != null) { 15792 try { 15793 app.thread.setSchedulingGroup(app.curSchedGroup); 15794 } catch (RemoteException e) { 15795 } 15796 } 15797 } 15798 Process.setSwappiness(app.pid, 15799 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15800 } 15801 } 15802 if (app.repForegroundActivities != app.foregroundActivities) { 15803 app.repForegroundActivities = app.foregroundActivities; 15804 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15805 } 15806 if (app.repProcState != app.curProcState) { 15807 app.repProcState = app.curProcState; 15808 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15809 if (app.thread != null) { 15810 try { 15811 if (false) { 15812 //RuntimeException h = new RuntimeException("here"); 15813 Slog.i(TAG, "Sending new process state " + app.repProcState 15814 + " to " + app /*, h*/); 15815 } 15816 app.thread.setProcessState(app.repProcState); 15817 } catch (RemoteException e) { 15818 } 15819 } 15820 } 15821 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15822 app.setProcState)) { 15823 app.lastStateTime = now; 15824 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15825 isSleeping(), now); 15826 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15827 + ProcessList.makeProcStateString(app.setProcState) + " to " 15828 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15829 + (app.nextPssTime-now) + ": " + app); 15830 } else { 15831 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15832 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15833 requestPssLocked(app, app.setProcState); 15834 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15835 isSleeping(), now); 15836 } else if (false && DEBUG_PSS) { 15837 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15838 } 15839 } 15840 if (app.setProcState != app.curProcState) { 15841 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15842 "Proc state change of " + app.processName 15843 + " to " + app.curProcState); 15844 app.setProcState = app.curProcState; 15845 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15846 app.notCachedSinceIdle = false; 15847 } 15848 if (!doingAll) { 15849 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15850 } else { 15851 app.procStateChanged = true; 15852 } 15853 } 15854 15855 if (changes != 0) { 15856 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15857 int i = mPendingProcessChanges.size()-1; 15858 ProcessChangeItem item = null; 15859 while (i >= 0) { 15860 item = mPendingProcessChanges.get(i); 15861 if (item.pid == app.pid) { 15862 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15863 break; 15864 } 15865 i--; 15866 } 15867 if (i < 0) { 15868 // No existing item in pending changes; need a new one. 15869 final int NA = mAvailProcessChanges.size(); 15870 if (NA > 0) { 15871 item = mAvailProcessChanges.remove(NA-1); 15872 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15873 } else { 15874 item = new ProcessChangeItem(); 15875 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15876 } 15877 item.changes = 0; 15878 item.pid = app.pid; 15879 item.uid = app.info.uid; 15880 if (mPendingProcessChanges.size() == 0) { 15881 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15882 "*** Enqueueing dispatch processes changed!"); 15883 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15884 } 15885 mPendingProcessChanges.add(item); 15886 } 15887 item.changes |= changes; 15888 item.processState = app.repProcState; 15889 item.foregroundActivities = app.repForegroundActivities; 15890 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15891 + Integer.toHexString(System.identityHashCode(item)) 15892 + " " + app.toShortString() + ": changes=" + item.changes 15893 + " procState=" + item.processState 15894 + " foreground=" + item.foregroundActivities 15895 + " type=" + app.adjType + " source=" + app.adjSource 15896 + " target=" + app.adjTarget); 15897 } 15898 15899 return success; 15900 } 15901 15902 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15903 if (proc.thread != null && proc.baseProcessTracker != null) { 15904 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15905 } 15906 } 15907 15908 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15909 ProcessRecord TOP_APP, boolean doingAll, long now) { 15910 if (app.thread == null) { 15911 return false; 15912 } 15913 15914 final boolean wasKeeping = app.keeping; 15915 15916 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15917 15918 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15919 } 15920 15921 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15922 boolean oomAdj) { 15923 if (isForeground != proc.foregroundServices) { 15924 proc.foregroundServices = isForeground; 15925 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15926 proc.info.uid); 15927 if (isForeground) { 15928 if (curProcs == null) { 15929 curProcs = new ArrayList<ProcessRecord>(); 15930 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15931 } 15932 if (!curProcs.contains(proc)) { 15933 curProcs.add(proc); 15934 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15935 proc.info.packageName, proc.info.uid); 15936 } 15937 } else { 15938 if (curProcs != null) { 15939 if (curProcs.remove(proc)) { 15940 mBatteryStatsService.noteEvent( 15941 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15942 proc.info.packageName, proc.info.uid); 15943 if (curProcs.size() <= 0) { 15944 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15945 } 15946 } 15947 } 15948 } 15949 if (oomAdj) { 15950 updateOomAdjLocked(); 15951 } 15952 } 15953 } 15954 15955 private final ActivityRecord resumedAppLocked() { 15956 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15957 String pkg; 15958 int uid; 15959 if (act != null && !act.sleeping) { 15960 pkg = act.packageName; 15961 uid = act.info.applicationInfo.uid; 15962 } else { 15963 pkg = null; 15964 uid = -1; 15965 } 15966 // Has the UID or resumed package name changed? 15967 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15968 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15969 if (mCurResumedPackage != null) { 15970 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15971 mCurResumedPackage, mCurResumedUid); 15972 } 15973 mCurResumedPackage = pkg; 15974 mCurResumedUid = uid; 15975 if (mCurResumedPackage != null) { 15976 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15977 mCurResumedPackage, mCurResumedUid); 15978 } 15979 } 15980 return act; 15981 } 15982 15983 final boolean updateOomAdjLocked(ProcessRecord app) { 15984 final ActivityRecord TOP_ACT = resumedAppLocked(); 15985 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15986 final boolean wasCached = app.cached; 15987 15988 mAdjSeq++; 15989 15990 // This is the desired cached adjusment we want to tell it to use. 15991 // If our app is currently cached, we know it, and that is it. Otherwise, 15992 // we don't know it yet, and it needs to now be cached we will then 15993 // need to do a complete oom adj. 15994 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15995 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15996 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15997 SystemClock.uptimeMillis()); 15998 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15999 // Changed to/from cached state, so apps after it in the LRU 16000 // list may also be changed. 16001 updateOomAdjLocked(); 16002 } 16003 return success; 16004 } 16005 16006 final void updateOomAdjLocked() { 16007 final ActivityRecord TOP_ACT = resumedAppLocked(); 16008 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16009 final long now = SystemClock.uptimeMillis(); 16010 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16011 final int N = mLruProcesses.size(); 16012 16013 if (false) { 16014 RuntimeException e = new RuntimeException(); 16015 e.fillInStackTrace(); 16016 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16017 } 16018 16019 mAdjSeq++; 16020 mNewNumServiceProcs = 0; 16021 mNewNumAServiceProcs = 0; 16022 16023 final int emptyProcessLimit; 16024 final int cachedProcessLimit; 16025 if (mProcessLimit <= 0) { 16026 emptyProcessLimit = cachedProcessLimit = 0; 16027 } else if (mProcessLimit == 1) { 16028 emptyProcessLimit = 1; 16029 cachedProcessLimit = 0; 16030 } else { 16031 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16032 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16033 } 16034 16035 // Let's determine how many processes we have running vs. 16036 // how many slots we have for background processes; we may want 16037 // to put multiple processes in a slot of there are enough of 16038 // them. 16039 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16040 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16041 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16042 if (numEmptyProcs > cachedProcessLimit) { 16043 // If there are more empty processes than our limit on cached 16044 // processes, then use the cached process limit for the factor. 16045 // This ensures that the really old empty processes get pushed 16046 // down to the bottom, so if we are running low on memory we will 16047 // have a better chance at keeping around more cached processes 16048 // instead of a gazillion empty processes. 16049 numEmptyProcs = cachedProcessLimit; 16050 } 16051 int emptyFactor = numEmptyProcs/numSlots; 16052 if (emptyFactor < 1) emptyFactor = 1; 16053 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16054 if (cachedFactor < 1) cachedFactor = 1; 16055 int stepCached = 0; 16056 int stepEmpty = 0; 16057 int numCached = 0; 16058 int numEmpty = 0; 16059 int numTrimming = 0; 16060 16061 mNumNonCachedProcs = 0; 16062 mNumCachedHiddenProcs = 0; 16063 16064 // First update the OOM adjustment for each of the 16065 // application processes based on their current state. 16066 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16067 int nextCachedAdj = curCachedAdj+1; 16068 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16069 int nextEmptyAdj = curEmptyAdj+2; 16070 for (int i=N-1; i>=0; i--) { 16071 ProcessRecord app = mLruProcesses.get(i); 16072 if (!app.killedByAm && app.thread != null) { 16073 app.procStateChanged = false; 16074 final boolean wasKeeping = app.keeping; 16075 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16076 16077 // If we haven't yet assigned the final cached adj 16078 // to the process, do that now. 16079 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16080 switch (app.curProcState) { 16081 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16082 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16083 // This process is a cached process holding activities... 16084 // assign it the next cached value for that type, and then 16085 // step that cached level. 16086 app.curRawAdj = curCachedAdj; 16087 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16088 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16089 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16090 + ")"); 16091 if (curCachedAdj != nextCachedAdj) { 16092 stepCached++; 16093 if (stepCached >= cachedFactor) { 16094 stepCached = 0; 16095 curCachedAdj = nextCachedAdj; 16096 nextCachedAdj += 2; 16097 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16098 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16099 } 16100 } 16101 } 16102 break; 16103 default: 16104 // For everything else, assign next empty cached process 16105 // level and bump that up. Note that this means that 16106 // long-running services that have dropped down to the 16107 // cached level will be treated as empty (since their process 16108 // state is still as a service), which is what we want. 16109 app.curRawAdj = curEmptyAdj; 16110 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16111 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16112 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16113 + ")"); 16114 if (curEmptyAdj != nextEmptyAdj) { 16115 stepEmpty++; 16116 if (stepEmpty >= emptyFactor) { 16117 stepEmpty = 0; 16118 curEmptyAdj = nextEmptyAdj; 16119 nextEmptyAdj += 2; 16120 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16121 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16122 } 16123 } 16124 } 16125 break; 16126 } 16127 } 16128 16129 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16130 16131 // Count the number of process types. 16132 switch (app.curProcState) { 16133 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16134 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16135 mNumCachedHiddenProcs++; 16136 numCached++; 16137 if (numCached > cachedProcessLimit) { 16138 killUnneededProcessLocked(app, "cached #" + numCached); 16139 } 16140 break; 16141 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16142 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16143 && app.lastActivityTime < oldTime) { 16144 killUnneededProcessLocked(app, "empty for " 16145 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16146 / 1000) + "s"); 16147 } else { 16148 numEmpty++; 16149 if (numEmpty > emptyProcessLimit) { 16150 killUnneededProcessLocked(app, "empty #" + numEmpty); 16151 } 16152 } 16153 break; 16154 default: 16155 mNumNonCachedProcs++; 16156 break; 16157 } 16158 16159 if (app.isolated && app.services.size() <= 0) { 16160 // If this is an isolated process, and there are no 16161 // services running in it, then the process is no longer 16162 // needed. We agressively kill these because we can by 16163 // definition not re-use the same process again, and it is 16164 // good to avoid having whatever code was running in them 16165 // left sitting around after no longer needed. 16166 killUnneededProcessLocked(app, "isolated not needed"); 16167 } 16168 16169 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16170 && !app.killedByAm) { 16171 numTrimming++; 16172 } 16173 } 16174 } 16175 16176 mNumServiceProcs = mNewNumServiceProcs; 16177 16178 // Now determine the memory trimming level of background processes. 16179 // Unfortunately we need to start at the back of the list to do this 16180 // properly. We only do this if the number of background apps we 16181 // are managing to keep around is less than half the maximum we desire; 16182 // if we are keeping a good number around, we'll let them use whatever 16183 // memory they want. 16184 final int numCachedAndEmpty = numCached + numEmpty; 16185 int memFactor; 16186 if (numCached <= ProcessList.TRIM_CACHED_APPS 16187 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16188 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16189 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16190 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16191 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16192 } else { 16193 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16194 } 16195 } else { 16196 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16197 } 16198 // We always allow the memory level to go up (better). We only allow it to go 16199 // down if we are in a state where that is allowed, *and* the total number of processes 16200 // has gone down since last time. 16201 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16202 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16203 + " last=" + mLastNumProcesses); 16204 if (memFactor > mLastMemoryLevel) { 16205 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16206 memFactor = mLastMemoryLevel; 16207 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16208 } 16209 } 16210 mLastMemoryLevel = memFactor; 16211 mLastNumProcesses = mLruProcesses.size(); 16212 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16213 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16214 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16215 if (mLowRamStartTime == 0) { 16216 mLowRamStartTime = now; 16217 } 16218 int step = 0; 16219 int fgTrimLevel; 16220 switch (memFactor) { 16221 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16222 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16223 break; 16224 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16225 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16226 break; 16227 default: 16228 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16229 break; 16230 } 16231 int factor = numTrimming/3; 16232 int minFactor = 2; 16233 if (mHomeProcess != null) minFactor++; 16234 if (mPreviousProcess != null) minFactor++; 16235 if (factor < minFactor) factor = minFactor; 16236 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16237 for (int i=N-1; i>=0; i--) { 16238 ProcessRecord app = mLruProcesses.get(i); 16239 if (allChanged || app.procStateChanged) { 16240 setProcessTrackerState(app, trackerMemFactor, now); 16241 app.procStateChanged = false; 16242 } 16243 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16244 && !app.killedByAm) { 16245 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16246 try { 16247 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16248 "Trimming memory of " + app.processName 16249 + " to " + curLevel); 16250 app.thread.scheduleTrimMemory(curLevel); 16251 } catch (RemoteException e) { 16252 } 16253 if (false) { 16254 // For now we won't do this; our memory trimming seems 16255 // to be good enough at this point that destroying 16256 // activities causes more harm than good. 16257 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16258 && app != mHomeProcess && app != mPreviousProcess) { 16259 // Need to do this on its own message because the stack may not 16260 // be in a consistent state at this point. 16261 // For these apps we will also finish their activities 16262 // to help them free memory. 16263 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16264 } 16265 } 16266 } 16267 app.trimMemoryLevel = curLevel; 16268 step++; 16269 if (step >= factor) { 16270 step = 0; 16271 switch (curLevel) { 16272 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16273 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16274 break; 16275 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16276 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16277 break; 16278 } 16279 } 16280 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16281 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16282 && app.thread != null) { 16283 try { 16284 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16285 "Trimming memory of heavy-weight " + app.processName 16286 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16287 app.thread.scheduleTrimMemory( 16288 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16289 } catch (RemoteException e) { 16290 } 16291 } 16292 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16293 } else { 16294 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16295 || app.systemNoUi) && app.pendingUiClean) { 16296 // If this application is now in the background and it 16297 // had done UI, then give it the special trim level to 16298 // have it free UI resources. 16299 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16300 if (app.trimMemoryLevel < level && app.thread != null) { 16301 try { 16302 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16303 "Trimming memory of bg-ui " + app.processName 16304 + " to " + level); 16305 app.thread.scheduleTrimMemory(level); 16306 } catch (RemoteException e) { 16307 } 16308 } 16309 app.pendingUiClean = false; 16310 } 16311 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16312 try { 16313 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16314 "Trimming memory of fg " + app.processName 16315 + " to " + fgTrimLevel); 16316 app.thread.scheduleTrimMemory(fgTrimLevel); 16317 } catch (RemoteException e) { 16318 } 16319 } 16320 app.trimMemoryLevel = fgTrimLevel; 16321 } 16322 } 16323 } else { 16324 if (mLowRamStartTime != 0) { 16325 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16326 mLowRamStartTime = 0; 16327 } 16328 for (int i=N-1; i>=0; i--) { 16329 ProcessRecord app = mLruProcesses.get(i); 16330 if (allChanged || app.procStateChanged) { 16331 setProcessTrackerState(app, trackerMemFactor, now); 16332 app.procStateChanged = false; 16333 } 16334 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16335 || app.systemNoUi) && app.pendingUiClean) { 16336 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16337 && app.thread != null) { 16338 try { 16339 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16340 "Trimming memory of ui hidden " + app.processName 16341 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16342 app.thread.scheduleTrimMemory( 16343 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16344 } catch (RemoteException e) { 16345 } 16346 } 16347 app.pendingUiClean = false; 16348 } 16349 app.trimMemoryLevel = 0; 16350 } 16351 } 16352 16353 if (mAlwaysFinishActivities) { 16354 // Need to do this on its own message because the stack may not 16355 // be in a consistent state at this point. 16356 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16357 } 16358 16359 if (allChanged) { 16360 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16361 } 16362 16363 if (mProcessStats.shouldWriteNowLocked(now)) { 16364 mHandler.post(new Runnable() { 16365 @Override public void run() { 16366 synchronized (ActivityManagerService.this) { 16367 mProcessStats.writeStateAsyncLocked(); 16368 } 16369 } 16370 }); 16371 } 16372 16373 if (DEBUG_OOM_ADJ) { 16374 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16375 } 16376 } 16377 16378 final void trimApplications() { 16379 synchronized (this) { 16380 int i; 16381 16382 // First remove any unused application processes whose package 16383 // has been removed. 16384 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16385 final ProcessRecord app = mRemovedProcesses.get(i); 16386 if (app.activities.size() == 0 16387 && app.curReceiver == null && app.services.size() == 0) { 16388 Slog.i( 16389 TAG, "Exiting empty application process " 16390 + app.processName + " (" 16391 + (app.thread != null ? app.thread.asBinder() : null) 16392 + ")\n"); 16393 if (app.pid > 0 && app.pid != MY_PID) { 16394 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16395 app.processName, app.setAdj, "empty"); 16396 app.killedByAm = true; 16397 Process.killProcessQuiet(app.pid); 16398 } else { 16399 try { 16400 app.thread.scheduleExit(); 16401 } catch (Exception e) { 16402 // Ignore exceptions. 16403 } 16404 } 16405 cleanUpApplicationRecordLocked(app, false, true, -1); 16406 mRemovedProcesses.remove(i); 16407 16408 if (app.persistent) { 16409 if (app.persistent) { 16410 addAppLocked(app.info, false, null /* ABI override */); 16411 } 16412 } 16413 } 16414 } 16415 16416 // Now update the oom adj for all processes. 16417 updateOomAdjLocked(); 16418 } 16419 } 16420 16421 /** This method sends the specified signal to each of the persistent apps */ 16422 public void signalPersistentProcesses(int sig) throws RemoteException { 16423 if (sig != Process.SIGNAL_USR1) { 16424 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16425 } 16426 16427 synchronized (this) { 16428 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16429 != PackageManager.PERMISSION_GRANTED) { 16430 throw new SecurityException("Requires permission " 16431 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16432 } 16433 16434 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16435 ProcessRecord r = mLruProcesses.get(i); 16436 if (r.thread != null && r.persistent) { 16437 Process.sendSignal(r.pid, sig); 16438 } 16439 } 16440 } 16441 } 16442 16443 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16444 if (proc == null || proc == mProfileProc) { 16445 proc = mProfileProc; 16446 path = mProfileFile; 16447 profileType = mProfileType; 16448 clearProfilerLocked(); 16449 } 16450 if (proc == null) { 16451 return; 16452 } 16453 try { 16454 proc.thread.profilerControl(false, path, null, profileType); 16455 } catch (RemoteException e) { 16456 throw new IllegalStateException("Process disappeared"); 16457 } 16458 } 16459 16460 private void clearProfilerLocked() { 16461 if (mProfileFd != null) { 16462 try { 16463 mProfileFd.close(); 16464 } catch (IOException e) { 16465 } 16466 } 16467 mProfileApp = null; 16468 mProfileProc = null; 16469 mProfileFile = null; 16470 mProfileType = 0; 16471 mAutoStopProfiler = false; 16472 } 16473 16474 public boolean profileControl(String process, int userId, boolean start, 16475 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16476 16477 try { 16478 synchronized (this) { 16479 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16480 // its own permission. 16481 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16482 != PackageManager.PERMISSION_GRANTED) { 16483 throw new SecurityException("Requires permission " 16484 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16485 } 16486 16487 if (start && fd == null) { 16488 throw new IllegalArgumentException("null fd"); 16489 } 16490 16491 ProcessRecord proc = null; 16492 if (process != null) { 16493 proc = findProcessLocked(process, userId, "profileControl"); 16494 } 16495 16496 if (start && (proc == null || proc.thread == null)) { 16497 throw new IllegalArgumentException("Unknown process: " + process); 16498 } 16499 16500 if (start) { 16501 stopProfilerLocked(null, null, 0); 16502 setProfileApp(proc.info, proc.processName, path, fd, false); 16503 mProfileProc = proc; 16504 mProfileType = profileType; 16505 try { 16506 fd = fd.dup(); 16507 } catch (IOException e) { 16508 fd = null; 16509 } 16510 proc.thread.profilerControl(start, path, fd, profileType); 16511 fd = null; 16512 mProfileFd = null; 16513 } else { 16514 stopProfilerLocked(proc, path, profileType); 16515 if (fd != null) { 16516 try { 16517 fd.close(); 16518 } catch (IOException e) { 16519 } 16520 } 16521 } 16522 16523 return true; 16524 } 16525 } catch (RemoteException e) { 16526 throw new IllegalStateException("Process disappeared"); 16527 } finally { 16528 if (fd != null) { 16529 try { 16530 fd.close(); 16531 } catch (IOException e) { 16532 } 16533 } 16534 } 16535 } 16536 16537 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16538 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16539 userId, true, true, callName, null); 16540 ProcessRecord proc = null; 16541 try { 16542 int pid = Integer.parseInt(process); 16543 synchronized (mPidsSelfLocked) { 16544 proc = mPidsSelfLocked.get(pid); 16545 } 16546 } catch (NumberFormatException e) { 16547 } 16548 16549 if (proc == null) { 16550 ArrayMap<String, SparseArray<ProcessRecord>> all 16551 = mProcessNames.getMap(); 16552 SparseArray<ProcessRecord> procs = all.get(process); 16553 if (procs != null && procs.size() > 0) { 16554 proc = procs.valueAt(0); 16555 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16556 for (int i=1; i<procs.size(); i++) { 16557 ProcessRecord thisProc = procs.valueAt(i); 16558 if (thisProc.userId == userId) { 16559 proc = thisProc; 16560 break; 16561 } 16562 } 16563 } 16564 } 16565 } 16566 16567 return proc; 16568 } 16569 16570 public boolean dumpHeap(String process, int userId, boolean managed, 16571 String path, ParcelFileDescriptor fd) throws RemoteException { 16572 16573 try { 16574 synchronized (this) { 16575 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16576 // its own permission (same as profileControl). 16577 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16578 != PackageManager.PERMISSION_GRANTED) { 16579 throw new SecurityException("Requires permission " 16580 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16581 } 16582 16583 if (fd == null) { 16584 throw new IllegalArgumentException("null fd"); 16585 } 16586 16587 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16588 if (proc == null || proc.thread == null) { 16589 throw new IllegalArgumentException("Unknown process: " + process); 16590 } 16591 16592 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16593 if (!isDebuggable) { 16594 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16595 throw new SecurityException("Process not debuggable: " + proc); 16596 } 16597 } 16598 16599 proc.thread.dumpHeap(managed, path, fd); 16600 fd = null; 16601 return true; 16602 } 16603 } catch (RemoteException e) { 16604 throw new IllegalStateException("Process disappeared"); 16605 } finally { 16606 if (fd != null) { 16607 try { 16608 fd.close(); 16609 } catch (IOException e) { 16610 } 16611 } 16612 } 16613 } 16614 16615 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16616 public void monitor() { 16617 synchronized (this) { } 16618 } 16619 16620 void onCoreSettingsChange(Bundle settings) { 16621 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16622 ProcessRecord processRecord = mLruProcesses.get(i); 16623 try { 16624 if (processRecord.thread != null) { 16625 processRecord.thread.setCoreSettings(settings); 16626 } 16627 } catch (RemoteException re) { 16628 /* ignore */ 16629 } 16630 } 16631 } 16632 16633 // Multi-user methods 16634 16635 /** 16636 * Start user, if its not already running, but don't bring it to foreground. 16637 */ 16638 @Override 16639 public boolean startUserInBackground(final int userId) { 16640 return startUser(userId, /* foreground */ false); 16641 } 16642 16643 /** 16644 * Refreshes the list of users related to the current user when either a 16645 * user switch happens or when a new related user is started in the 16646 * background. 16647 */ 16648 private void updateCurrentProfileIdsLocked() { 16649 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16650 mCurrentUserId, false /* enabledOnly */); 16651 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16652 for (int i = 0; i < currentProfileIds.length; i++) { 16653 currentProfileIds[i] = profiles.get(i).id; 16654 } 16655 mCurrentProfileIds = currentProfileIds; 16656 } 16657 16658 private Set getProfileIdsLocked(int userId) { 16659 Set userIds = new HashSet<Integer>(); 16660 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16661 userId, false /* enabledOnly */); 16662 for (UserInfo user : profiles) { 16663 userIds.add(Integer.valueOf(user.id)); 16664 } 16665 return userIds; 16666 } 16667 16668 @Override 16669 public boolean switchUser(final int userId) { 16670 return startUser(userId, /* foregound */ true); 16671 } 16672 16673 private boolean startUser(final int userId, boolean foreground) { 16674 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16675 != PackageManager.PERMISSION_GRANTED) { 16676 String msg = "Permission Denial: switchUser() from pid=" 16677 + Binder.getCallingPid() 16678 + ", uid=" + Binder.getCallingUid() 16679 + " requires " + INTERACT_ACROSS_USERS_FULL; 16680 Slog.w(TAG, msg); 16681 throw new SecurityException(msg); 16682 } 16683 16684 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16685 16686 final long ident = Binder.clearCallingIdentity(); 16687 try { 16688 synchronized (this) { 16689 final int oldUserId = mCurrentUserId; 16690 if (oldUserId == userId) { 16691 return true; 16692 } 16693 16694 mStackSupervisor.setLockTaskModeLocked(null); 16695 16696 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16697 if (userInfo == null) { 16698 Slog.w(TAG, "No user info for user #" + userId); 16699 return false; 16700 } 16701 16702 if (foreground) { 16703 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16704 R.anim.screen_user_enter); 16705 } 16706 16707 boolean needStart = false; 16708 16709 // If the user we are switching to is not currently started, then 16710 // we need to start it now. 16711 if (mStartedUsers.get(userId) == null) { 16712 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16713 updateStartedUserArrayLocked(); 16714 needStart = true; 16715 } 16716 16717 final Integer userIdInt = Integer.valueOf(userId); 16718 mUserLru.remove(userIdInt); 16719 mUserLru.add(userIdInt); 16720 16721 if (foreground) { 16722 mCurrentUserId = userId; 16723 updateCurrentProfileIdsLocked(); 16724 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16725 // Once the internal notion of the active user has switched, we lock the device 16726 // with the option to show the user switcher on the keyguard. 16727 mWindowManager.lockNow(null); 16728 } else { 16729 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16730 updateCurrentProfileIdsLocked(); 16731 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16732 mUserLru.remove(currentUserIdInt); 16733 mUserLru.add(currentUserIdInt); 16734 } 16735 16736 final UserStartedState uss = mStartedUsers.get(userId); 16737 16738 // Make sure user is in the started state. If it is currently 16739 // stopping, we need to knock that off. 16740 if (uss.mState == UserStartedState.STATE_STOPPING) { 16741 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16742 // so we can just fairly silently bring the user back from 16743 // the almost-dead. 16744 uss.mState = UserStartedState.STATE_RUNNING; 16745 updateStartedUserArrayLocked(); 16746 needStart = true; 16747 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16748 // This means ACTION_SHUTDOWN has been sent, so we will 16749 // need to treat this as a new boot of the user. 16750 uss.mState = UserStartedState.STATE_BOOTING; 16751 updateStartedUserArrayLocked(); 16752 needStart = true; 16753 } 16754 16755 if (uss.mState == UserStartedState.STATE_BOOTING) { 16756 // Booting up a new user, need to tell system services about it. 16757 // Note that this is on the same handler as scheduling of broadcasts, 16758 // which is important because it needs to go first. 16759 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16760 } 16761 16762 if (foreground) { 16763 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16764 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16765 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16766 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16767 oldUserId, userId, uss)); 16768 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16769 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16770 } 16771 16772 if (needStart) { 16773 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16774 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16775 | Intent.FLAG_RECEIVER_FOREGROUND); 16776 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16777 broadcastIntentLocked(null, null, intent, 16778 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16779 false, false, MY_PID, Process.SYSTEM_UID, userId); 16780 } 16781 16782 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16783 if (userId != UserHandle.USER_OWNER) { 16784 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16785 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16786 broadcastIntentLocked(null, null, intent, null, 16787 new IIntentReceiver.Stub() { 16788 public void performReceive(Intent intent, int resultCode, 16789 String data, Bundle extras, boolean ordered, 16790 boolean sticky, int sendingUser) { 16791 userInitialized(uss, userId); 16792 } 16793 }, 0, null, null, null, AppOpsManager.OP_NONE, 16794 true, false, MY_PID, Process.SYSTEM_UID, 16795 userId); 16796 uss.initializing = true; 16797 } else { 16798 getUserManagerLocked().makeInitialized(userInfo.id); 16799 } 16800 } 16801 16802 if (foreground) { 16803 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16804 if (homeInFront) { 16805 startHomeActivityLocked(userId); 16806 } else { 16807 mStackSupervisor.resumeTopActivitiesLocked(); 16808 } 16809 EventLogTags.writeAmSwitchUser(userId); 16810 getUserManagerLocked().userForeground(userId); 16811 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16812 } else { 16813 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16814 } 16815 16816 if (needStart) { 16817 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16818 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16819 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16820 broadcastIntentLocked(null, null, intent, 16821 null, new IIntentReceiver.Stub() { 16822 @Override 16823 public void performReceive(Intent intent, int resultCode, String data, 16824 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16825 throws RemoteException { 16826 } 16827 }, 0, null, null, 16828 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16829 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16830 } 16831 } 16832 } finally { 16833 Binder.restoreCallingIdentity(ident); 16834 } 16835 16836 return true; 16837 } 16838 16839 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16840 long ident = Binder.clearCallingIdentity(); 16841 try { 16842 Intent intent; 16843 if (oldUserId >= 0) { 16844 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16845 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16846 | Intent.FLAG_RECEIVER_FOREGROUND); 16847 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16848 broadcastIntentLocked(null, null, intent, 16849 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16850 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16851 } 16852 if (newUserId >= 0) { 16853 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16855 | Intent.FLAG_RECEIVER_FOREGROUND); 16856 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16857 broadcastIntentLocked(null, null, intent, 16858 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16859 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16860 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16861 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16862 | Intent.FLAG_RECEIVER_FOREGROUND); 16863 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16864 broadcastIntentLocked(null, null, intent, 16865 null, null, 0, null, null, 16866 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16867 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16868 } 16869 } finally { 16870 Binder.restoreCallingIdentity(ident); 16871 } 16872 } 16873 16874 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16875 final int newUserId) { 16876 final int N = mUserSwitchObservers.beginBroadcast(); 16877 if (N > 0) { 16878 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16879 int mCount = 0; 16880 @Override 16881 public void sendResult(Bundle data) throws RemoteException { 16882 synchronized (ActivityManagerService.this) { 16883 if (mCurUserSwitchCallback == this) { 16884 mCount++; 16885 if (mCount == N) { 16886 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16887 } 16888 } 16889 } 16890 } 16891 }; 16892 synchronized (this) { 16893 uss.switching = true; 16894 mCurUserSwitchCallback = callback; 16895 } 16896 for (int i=0; i<N; i++) { 16897 try { 16898 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16899 newUserId, callback); 16900 } catch (RemoteException e) { 16901 } 16902 } 16903 } else { 16904 synchronized (this) { 16905 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16906 } 16907 } 16908 mUserSwitchObservers.finishBroadcast(); 16909 } 16910 16911 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16912 synchronized (this) { 16913 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16914 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16915 } 16916 } 16917 16918 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16919 mCurUserSwitchCallback = null; 16920 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16921 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16922 oldUserId, newUserId, uss)); 16923 } 16924 16925 void userInitialized(UserStartedState uss, int newUserId) { 16926 completeSwitchAndInitalize(uss, newUserId, true, false); 16927 } 16928 16929 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16930 completeSwitchAndInitalize(uss, newUserId, false, true); 16931 } 16932 16933 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16934 boolean clearInitializing, boolean clearSwitching) { 16935 boolean unfrozen = false; 16936 synchronized (this) { 16937 if (clearInitializing) { 16938 uss.initializing = false; 16939 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16940 } 16941 if (clearSwitching) { 16942 uss.switching = false; 16943 } 16944 if (!uss.switching && !uss.initializing) { 16945 mWindowManager.stopFreezingScreen(); 16946 unfrozen = true; 16947 } 16948 } 16949 if (unfrozen) { 16950 final int N = mUserSwitchObservers.beginBroadcast(); 16951 for (int i=0; i<N; i++) { 16952 try { 16953 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16954 } catch (RemoteException e) { 16955 } 16956 } 16957 mUserSwitchObservers.finishBroadcast(); 16958 } 16959 } 16960 16961 void scheduleStartProfilesLocked() { 16962 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16963 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16964 DateUtils.SECOND_IN_MILLIS); 16965 } 16966 } 16967 16968 void startProfilesLocked() { 16969 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16970 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16971 mCurrentUserId, false /* enabledOnly */); 16972 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16973 for (UserInfo user : profiles) { 16974 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16975 && user.id != mCurrentUserId) { 16976 toStart.add(user); 16977 } 16978 } 16979 final int n = toStart.size(); 16980 int i = 0; 16981 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16982 startUserInBackground(toStart.get(i).id); 16983 } 16984 if (i < n) { 16985 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16986 } 16987 } 16988 16989 void finishUserBoot(UserStartedState uss) { 16990 synchronized (this) { 16991 if (uss.mState == UserStartedState.STATE_BOOTING 16992 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16993 uss.mState = UserStartedState.STATE_RUNNING; 16994 final int userId = uss.mHandle.getIdentifier(); 16995 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16996 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16997 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16998 broadcastIntentLocked(null, null, intent, 16999 null, null, 0, null, null, 17000 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17001 true, false, MY_PID, Process.SYSTEM_UID, userId); 17002 } 17003 } 17004 } 17005 17006 void finishUserSwitch(UserStartedState uss) { 17007 synchronized (this) { 17008 finishUserBoot(uss); 17009 17010 startProfilesLocked(); 17011 17012 int num = mUserLru.size(); 17013 int i = 0; 17014 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17015 Integer oldUserId = mUserLru.get(i); 17016 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17017 if (oldUss == null) { 17018 // Shouldn't happen, but be sane if it does. 17019 mUserLru.remove(i); 17020 num--; 17021 continue; 17022 } 17023 if (oldUss.mState == UserStartedState.STATE_STOPPING 17024 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17025 // This user is already stopping, doesn't count. 17026 num--; 17027 i++; 17028 continue; 17029 } 17030 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17031 // Owner and current can't be stopped, but count as running. 17032 i++; 17033 continue; 17034 } 17035 // This is a user to be stopped. 17036 stopUserLocked(oldUserId, null); 17037 num--; 17038 i++; 17039 } 17040 } 17041 } 17042 17043 @Override 17044 public int stopUser(final int userId, final IStopUserCallback callback) { 17045 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17046 != PackageManager.PERMISSION_GRANTED) { 17047 String msg = "Permission Denial: switchUser() from pid=" 17048 + Binder.getCallingPid() 17049 + ", uid=" + Binder.getCallingUid() 17050 + " requires " + INTERACT_ACROSS_USERS_FULL; 17051 Slog.w(TAG, msg); 17052 throw new SecurityException(msg); 17053 } 17054 if (userId <= 0) { 17055 throw new IllegalArgumentException("Can't stop primary user " + userId); 17056 } 17057 synchronized (this) { 17058 return stopUserLocked(userId, callback); 17059 } 17060 } 17061 17062 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17063 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17064 if (mCurrentUserId == userId) { 17065 return ActivityManager.USER_OP_IS_CURRENT; 17066 } 17067 17068 final UserStartedState uss = mStartedUsers.get(userId); 17069 if (uss == null) { 17070 // User is not started, nothing to do... but we do need to 17071 // callback if requested. 17072 if (callback != null) { 17073 mHandler.post(new Runnable() { 17074 @Override 17075 public void run() { 17076 try { 17077 callback.userStopped(userId); 17078 } catch (RemoteException e) { 17079 } 17080 } 17081 }); 17082 } 17083 return ActivityManager.USER_OP_SUCCESS; 17084 } 17085 17086 if (callback != null) { 17087 uss.mStopCallbacks.add(callback); 17088 } 17089 17090 if (uss.mState != UserStartedState.STATE_STOPPING 17091 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17092 uss.mState = UserStartedState.STATE_STOPPING; 17093 updateStartedUserArrayLocked(); 17094 17095 long ident = Binder.clearCallingIdentity(); 17096 try { 17097 // We are going to broadcast ACTION_USER_STOPPING and then 17098 // once that is done send a final ACTION_SHUTDOWN and then 17099 // stop the user. 17100 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17101 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17102 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17103 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17104 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17105 // This is the result receiver for the final shutdown broadcast. 17106 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17107 @Override 17108 public void performReceive(Intent intent, int resultCode, String data, 17109 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17110 finishUserStop(uss); 17111 } 17112 }; 17113 // This is the result receiver for the initial stopping broadcast. 17114 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17115 @Override 17116 public void performReceive(Intent intent, int resultCode, String data, 17117 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17118 // On to the next. 17119 synchronized (ActivityManagerService.this) { 17120 if (uss.mState != UserStartedState.STATE_STOPPING) { 17121 // Whoops, we are being started back up. Abort, abort! 17122 return; 17123 } 17124 uss.mState = UserStartedState.STATE_SHUTDOWN; 17125 } 17126 mSystemServiceManager.stopUser(userId); 17127 broadcastIntentLocked(null, null, shutdownIntent, 17128 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17129 true, false, MY_PID, Process.SYSTEM_UID, userId); 17130 } 17131 }; 17132 // Kick things off. 17133 broadcastIntentLocked(null, null, stoppingIntent, 17134 null, stoppingReceiver, 0, null, null, 17135 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17136 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17137 } finally { 17138 Binder.restoreCallingIdentity(ident); 17139 } 17140 } 17141 17142 return ActivityManager.USER_OP_SUCCESS; 17143 } 17144 17145 void finishUserStop(UserStartedState uss) { 17146 final int userId = uss.mHandle.getIdentifier(); 17147 boolean stopped; 17148 ArrayList<IStopUserCallback> callbacks; 17149 synchronized (this) { 17150 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17151 if (mStartedUsers.get(userId) != uss) { 17152 stopped = false; 17153 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17154 stopped = false; 17155 } else { 17156 stopped = true; 17157 // User can no longer run. 17158 mStartedUsers.remove(userId); 17159 mUserLru.remove(Integer.valueOf(userId)); 17160 updateStartedUserArrayLocked(); 17161 17162 // Clean up all state and processes associated with the user. 17163 // Kill all the processes for the user. 17164 forceStopUserLocked(userId, "finish user"); 17165 } 17166 } 17167 17168 for (int i=0; i<callbacks.size(); i++) { 17169 try { 17170 if (stopped) callbacks.get(i).userStopped(userId); 17171 else callbacks.get(i).userStopAborted(userId); 17172 } catch (RemoteException e) { 17173 } 17174 } 17175 17176 if (stopped) { 17177 mSystemServiceManager.cleanupUser(userId); 17178 synchronized (this) { 17179 mStackSupervisor.removeUserLocked(userId); 17180 } 17181 } 17182 } 17183 17184 @Override 17185 public UserInfo getCurrentUser() { 17186 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17187 != PackageManager.PERMISSION_GRANTED) && ( 17188 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17189 != PackageManager.PERMISSION_GRANTED)) { 17190 String msg = "Permission Denial: getCurrentUser() from pid=" 17191 + Binder.getCallingPid() 17192 + ", uid=" + Binder.getCallingUid() 17193 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17194 Slog.w(TAG, msg); 17195 throw new SecurityException(msg); 17196 } 17197 synchronized (this) { 17198 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17199 } 17200 } 17201 17202 int getCurrentUserIdLocked() { 17203 return mCurrentUserId; 17204 } 17205 17206 @Override 17207 public boolean isUserRunning(int userId, boolean orStopped) { 17208 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17209 != PackageManager.PERMISSION_GRANTED) { 17210 String msg = "Permission Denial: isUserRunning() from pid=" 17211 + Binder.getCallingPid() 17212 + ", uid=" + Binder.getCallingUid() 17213 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17214 Slog.w(TAG, msg); 17215 throw new SecurityException(msg); 17216 } 17217 synchronized (this) { 17218 return isUserRunningLocked(userId, orStopped); 17219 } 17220 } 17221 17222 boolean isUserRunningLocked(int userId, boolean orStopped) { 17223 UserStartedState state = mStartedUsers.get(userId); 17224 if (state == null) { 17225 return false; 17226 } 17227 if (orStopped) { 17228 return true; 17229 } 17230 return state.mState != UserStartedState.STATE_STOPPING 17231 && state.mState != UserStartedState.STATE_SHUTDOWN; 17232 } 17233 17234 @Override 17235 public int[] getRunningUserIds() { 17236 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17237 != PackageManager.PERMISSION_GRANTED) { 17238 String msg = "Permission Denial: isUserRunning() from pid=" 17239 + Binder.getCallingPid() 17240 + ", uid=" + Binder.getCallingUid() 17241 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17242 Slog.w(TAG, msg); 17243 throw new SecurityException(msg); 17244 } 17245 synchronized (this) { 17246 return mStartedUserArray; 17247 } 17248 } 17249 17250 private void updateStartedUserArrayLocked() { 17251 int num = 0; 17252 for (int i=0; i<mStartedUsers.size(); i++) { 17253 UserStartedState uss = mStartedUsers.valueAt(i); 17254 // This list does not include stopping users. 17255 if (uss.mState != UserStartedState.STATE_STOPPING 17256 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17257 num++; 17258 } 17259 } 17260 mStartedUserArray = new int[num]; 17261 num = 0; 17262 for (int i=0; i<mStartedUsers.size(); i++) { 17263 UserStartedState uss = mStartedUsers.valueAt(i); 17264 if (uss.mState != UserStartedState.STATE_STOPPING 17265 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17266 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17267 num++; 17268 } 17269 } 17270 } 17271 17272 @Override 17273 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17274 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17275 != PackageManager.PERMISSION_GRANTED) { 17276 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17277 + Binder.getCallingPid() 17278 + ", uid=" + Binder.getCallingUid() 17279 + " requires " + INTERACT_ACROSS_USERS_FULL; 17280 Slog.w(TAG, msg); 17281 throw new SecurityException(msg); 17282 } 17283 17284 mUserSwitchObservers.register(observer); 17285 } 17286 17287 @Override 17288 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17289 mUserSwitchObservers.unregister(observer); 17290 } 17291 17292 private boolean userExists(int userId) { 17293 if (userId == 0) { 17294 return true; 17295 } 17296 UserManagerService ums = getUserManagerLocked(); 17297 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17298 } 17299 17300 int[] getUsersLocked() { 17301 UserManagerService ums = getUserManagerLocked(); 17302 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17303 } 17304 17305 UserManagerService getUserManagerLocked() { 17306 if (mUserManager == null) { 17307 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17308 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17309 } 17310 return mUserManager; 17311 } 17312 17313 private int applyUserId(int uid, int userId) { 17314 return UserHandle.getUid(userId, uid); 17315 } 17316 17317 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17318 if (info == null) return null; 17319 ApplicationInfo newInfo = new ApplicationInfo(info); 17320 newInfo.uid = applyUserId(info.uid, userId); 17321 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17322 + info.packageName; 17323 return newInfo; 17324 } 17325 17326 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17327 if (aInfo == null 17328 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17329 return aInfo; 17330 } 17331 17332 ActivityInfo info = new ActivityInfo(aInfo); 17333 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17334 return info; 17335 } 17336 17337 private final class LocalService extends ActivityManagerInternal { 17338 @Override 17339 public void goingToSleep() { 17340 ActivityManagerService.this.goingToSleep(); 17341 } 17342 17343 @Override 17344 public void wakingUp() { 17345 ActivityManagerService.this.wakingUp(); 17346 } 17347 } 17348 17349 /** 17350 * An implementation of IAppTask, that allows an app to manage its own tasks via 17351 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17352 * only the process that calls getAppTasks() can call the AppTask methods. 17353 */ 17354 class AppTaskImpl extends IAppTask.Stub { 17355 private int mTaskId; 17356 private int mCallingUid; 17357 17358 public AppTaskImpl(int taskId, int callingUid) { 17359 mTaskId = taskId; 17360 mCallingUid = callingUid; 17361 } 17362 17363 @Override 17364 public void finishAndRemoveTask() { 17365 // Ensure that we are called from the same process that created this AppTask 17366 if (mCallingUid != Binder.getCallingUid()) { 17367 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17368 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17369 return; 17370 } 17371 17372 synchronized (ActivityManagerService.this) { 17373 long origId = Binder.clearCallingIdentity(); 17374 try { 17375 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17376 if (tr != null) { 17377 // Only kill the process if we are not a new document 17378 int flags = tr.getBaseIntent().getFlags(); 17379 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17380 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17381 removeTaskByIdLocked(mTaskId, 17382 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17383 } 17384 } finally { 17385 Binder.restoreCallingIdentity(origId); 17386 } 17387 } 17388 } 17389 17390 @Override 17391 public ActivityManager.RecentTaskInfo getTaskInfo() { 17392 // Ensure that we are called from the same process that created this AppTask 17393 if (mCallingUid != Binder.getCallingUid()) { 17394 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17395 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17396 return null; 17397 } 17398 17399 synchronized (ActivityManagerService.this) { 17400 long origId = Binder.clearCallingIdentity(); 17401 try { 17402 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17403 if (tr != null) { 17404 return createRecentTaskInfoFromTaskRecord(tr); 17405 } 17406 } finally { 17407 Binder.restoreCallingIdentity(origId); 17408 } 17409 return null; 17410 } 17411 } 17412 } 17413} 17414