ActivityManagerService.java revision 7d9eefd871f1cdc5ebc36fa92dae48a737ae2928
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; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 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 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a recents UI */ 1202 final boolean mHasRecents; 1203 1204 final int mThumbnailWidth; 1205 final int mThumbnailHeight; 1206 1207 final ServiceThread mHandlerThread; 1208 final MainHandler mHandler; 1209 1210 final class MainHandler extends Handler { 1211 public MainHandler(Looper looper) { 1212 super(looper, null, true); 1213 } 1214 1215 @Override 1216 public void handleMessage(Message msg) { 1217 switch (msg.what) { 1218 case SHOW_ERROR_MSG: { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1221 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1222 synchronized (ActivityManagerService.this) { 1223 ProcessRecord proc = (ProcessRecord)data.get("app"); 1224 AppErrorResult res = (AppErrorResult) data.get("result"); 1225 if (proc != null && proc.crashDialog != null) { 1226 Slog.e(TAG, "App already has crash dialog: " + proc); 1227 if (res != null) { 1228 res.set(0); 1229 } 1230 return; 1231 } 1232 boolean isBackground = (UserHandle.getAppId(proc.uid) 1233 >= Process.FIRST_APPLICATION_UID 1234 && proc.pid != MY_PID); 1235 for (int userId : mCurrentProfileIds) { 1236 isBackground &= (proc.userId != userId); 1237 } 1238 if (isBackground && !showBackground) { 1239 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1246 Dialog d = new AppErrorDialog(mContext, 1247 ActivityManagerService.this, res, proc); 1248 d.show(); 1249 proc.crashDialog = d; 1250 } else { 1251 // The device is asleep, so just pretend that the user 1252 // saw a crash dialog and hit "force quit". 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 } 1257 } 1258 1259 ensureBootCompleted(); 1260 } break; 1261 case SHOW_NOT_RESPONDING_MSG: { 1262 synchronized (ActivityManagerService.this) { 1263 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1264 ProcessRecord proc = (ProcessRecord)data.get("app"); 1265 if (proc != null && proc.anrDialog != null) { 1266 Slog.e(TAG, "App already has anr dialog: " + proc); 1267 return; 1268 } 1269 1270 Intent intent = new Intent("android.intent.action.ANR"); 1271 if (!mProcessesReady) { 1272 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1273 | Intent.FLAG_RECEIVER_FOREGROUND); 1274 } 1275 broadcastIntentLocked(null, null, intent, 1276 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1277 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1278 1279 if (mShowDialogs) { 1280 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1281 mContext, proc, (ActivityRecord)data.get("activity"), 1282 msg.arg1 != 0); 1283 d.show(); 1284 proc.anrDialog = d; 1285 } else { 1286 // Just kill the app if there is no dialog to be shown. 1287 killAppAtUsersRequest(proc, null); 1288 } 1289 } 1290 1291 ensureBootCompleted(); 1292 } break; 1293 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1294 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1295 synchronized (ActivityManagerService.this) { 1296 ProcessRecord proc = (ProcessRecord) data.get("app"); 1297 if (proc == null) { 1298 Slog.e(TAG, "App not found when showing strict mode dialog."); 1299 break; 1300 } 1301 if (proc.crashDialog != null) { 1302 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1303 return; 1304 } 1305 AppErrorResult res = (AppErrorResult) data.get("result"); 1306 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1307 Dialog d = new StrictModeViolationDialog(mContext, 1308 ActivityManagerService.this, res, proc); 1309 d.show(); 1310 proc.crashDialog = d; 1311 } else { 1312 // The device is asleep, so just pretend that the user 1313 // saw a crash dialog and hit "force quit". 1314 res.set(0); 1315 } 1316 } 1317 ensureBootCompleted(); 1318 } break; 1319 case SHOW_FACTORY_ERROR_MSG: { 1320 Dialog d = new FactoryErrorDialog( 1321 mContext, msg.getData().getCharSequence("msg")); 1322 d.show(); 1323 ensureBootCompleted(); 1324 } break; 1325 case UPDATE_CONFIGURATION_MSG: { 1326 final ContentResolver resolver = mContext.getContentResolver(); 1327 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1328 } break; 1329 case GC_BACKGROUND_PROCESSES_MSG: { 1330 synchronized (ActivityManagerService.this) { 1331 performAppGcsIfAppropriateLocked(); 1332 } 1333 } break; 1334 case WAIT_FOR_DEBUGGER_MSG: { 1335 synchronized (ActivityManagerService.this) { 1336 ProcessRecord app = (ProcessRecord)msg.obj; 1337 if (msg.arg1 != 0) { 1338 if (!app.waitedForDebugger) { 1339 Dialog d = new AppWaitingForDebuggerDialog( 1340 ActivityManagerService.this, 1341 mContext, app); 1342 app.waitDialog = d; 1343 app.waitedForDebugger = true; 1344 d.show(); 1345 } 1346 } else { 1347 if (app.waitDialog != null) { 1348 app.waitDialog.dismiss(); 1349 app.waitDialog = null; 1350 } 1351 } 1352 } 1353 } break; 1354 case SERVICE_TIMEOUT_MSG: { 1355 if (mDidDexOpt) { 1356 mDidDexOpt = false; 1357 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1358 nmsg.obj = msg.obj; 1359 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1360 return; 1361 } 1362 mServices.serviceTimeout((ProcessRecord)msg.obj); 1363 } break; 1364 case UPDATE_TIME_ZONE: { 1365 synchronized (ActivityManagerService.this) { 1366 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1367 ProcessRecord r = mLruProcesses.get(i); 1368 if (r.thread != null) { 1369 try { 1370 r.thread.updateTimeZone(); 1371 } catch (RemoteException ex) { 1372 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1373 } 1374 } 1375 } 1376 } 1377 } break; 1378 case CLEAR_DNS_CACHE_MSG: { 1379 synchronized (ActivityManagerService.this) { 1380 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1381 ProcessRecord r = mLruProcesses.get(i); 1382 if (r.thread != null) { 1383 try { 1384 r.thread.clearDnsCache(); 1385 } catch (RemoteException ex) { 1386 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1387 } 1388 } 1389 } 1390 } 1391 } break; 1392 case UPDATE_HTTP_PROXY_MSG: { 1393 ProxyInfo proxy = (ProxyInfo)msg.obj; 1394 String host = ""; 1395 String port = ""; 1396 String exclList = ""; 1397 Uri pacFileUrl = Uri.EMPTY; 1398 if (proxy != null) { 1399 host = proxy.getHost(); 1400 port = Integer.toString(proxy.getPort()); 1401 exclList = proxy.getExclusionListAsString(); 1402 pacFileUrl = proxy.getPacFileUrl(); 1403 } 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to update http proxy for: " + 1412 r.info.processName); 1413 } 1414 } 1415 } 1416 } 1417 } break; 1418 case SHOW_UID_ERROR_MSG: { 1419 String title = "System UIDs Inconsistent"; 1420 String text = "UIDs on the system are inconsistent, you need to wipe your" 1421 + " data partition or your device will be unstable."; 1422 Log.e(TAG, title + ": " + text); 1423 if (mShowDialogs) { 1424 // XXX This is a temporary dialog, no need to localize. 1425 AlertDialog d = new BaseErrorDialog(mContext); 1426 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1427 d.setCancelable(false); 1428 d.setTitle(title); 1429 d.setMessage(text); 1430 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1431 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1432 mUidAlert = d; 1433 d.show(); 1434 } 1435 } break; 1436 case IM_FEELING_LUCKY_MSG: { 1437 if (mUidAlert != null) { 1438 mUidAlert.dismiss(); 1439 mUidAlert = null; 1440 } 1441 } break; 1442 case PROC_START_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1448 return; 1449 } 1450 ProcessRecord app = (ProcessRecord)msg.obj; 1451 synchronized (ActivityManagerService.this) { 1452 processStartTimedOutLocked(app); 1453 } 1454 } break; 1455 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1456 synchronized (ActivityManagerService.this) { 1457 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1458 } 1459 } break; 1460 case KILL_APPLICATION_MSG: { 1461 synchronized (ActivityManagerService.this) { 1462 int appid = msg.arg1; 1463 boolean restart = (msg.arg2 == 1); 1464 Bundle bundle = (Bundle)msg.obj; 1465 String pkg = bundle.getString("pkg"); 1466 String reason = bundle.getString("reason"); 1467 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1468 false, UserHandle.USER_ALL, reason); 1469 } 1470 } break; 1471 case FINALIZE_PENDING_INTENT_MSG: { 1472 ((PendingIntentRecord)msg.obj).completeFinalize(); 1473 } break; 1474 case POST_HEAVY_NOTIFICATION_MSG: { 1475 INotificationManager inm = NotificationManager.getService(); 1476 if (inm == null) { 1477 return; 1478 } 1479 1480 ActivityRecord root = (ActivityRecord)msg.obj; 1481 ProcessRecord process = root.app; 1482 if (process == null) { 1483 return; 1484 } 1485 1486 try { 1487 Context context = mContext.createPackageContext(process.info.packageName, 0); 1488 String text = mContext.getString(R.string.heavy_weight_notification, 1489 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1490 Notification notification = new Notification(); 1491 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1492 notification.when = 0; 1493 notification.flags = Notification.FLAG_ONGOING_EVENT; 1494 notification.tickerText = text; 1495 notification.defaults = 0; // please be quiet 1496 notification.sound = null; 1497 notification.vibrate = null; 1498 notification.color = mContext.getResources().getColor( 1499 com.android.internal.R.color.system_notification_accent_color); 1500 notification.setLatestEventInfo(context, text, 1501 mContext.getText(R.string.heavy_weight_notification_detail), 1502 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1503 PendingIntent.FLAG_CANCEL_CURRENT, null, 1504 new UserHandle(root.userId))); 1505 1506 try { 1507 int[] outId = new int[1]; 1508 inm.enqueueNotificationWithTag("android", "android", null, 1509 R.string.heavy_weight_notification, 1510 notification, outId, root.userId); 1511 } catch (RuntimeException e) { 1512 Slog.w(ActivityManagerService.TAG, 1513 "Error showing notification for heavy-weight app", e); 1514 } catch (RemoteException e) { 1515 } 1516 } catch (NameNotFoundException e) { 1517 Slog.w(TAG, "Unable to create context for heavy notification", e); 1518 } 1519 } break; 1520 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 try { 1526 inm.cancelNotificationWithTag("android", null, 1527 R.string.heavy_weight_notification, msg.arg1); 1528 } catch (RuntimeException e) { 1529 Slog.w(ActivityManagerService.TAG, 1530 "Error canceling notification for service", e); 1531 } catch (RemoteException e) { 1532 } 1533 } break; 1534 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1535 synchronized (ActivityManagerService.this) { 1536 checkExcessivePowerUsageLocked(true); 1537 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1538 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1540 } 1541 } break; 1542 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1543 synchronized (ActivityManagerService.this) { 1544 ActivityRecord ar = (ActivityRecord)msg.obj; 1545 if (mCompatModeDialog != null) { 1546 if (mCompatModeDialog.mAppInfo.packageName.equals( 1547 ar.info.applicationInfo.packageName)) { 1548 return; 1549 } 1550 mCompatModeDialog.dismiss(); 1551 mCompatModeDialog = null; 1552 } 1553 if (ar != null && false) { 1554 if (mCompatModePackages.getPackageAskCompatModeLocked( 1555 ar.packageName)) { 1556 int mode = mCompatModePackages.computeCompatModeLocked( 1557 ar.info.applicationInfo); 1558 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1559 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1560 mCompatModeDialog = new CompatModeDialog( 1561 ActivityManagerService.this, mContext, 1562 ar.info.applicationInfo); 1563 mCompatModeDialog.show(); 1564 } 1565 } 1566 } 1567 } 1568 break; 1569 } 1570 case DISPATCH_PROCESSES_CHANGED: { 1571 dispatchProcessesChanged(); 1572 break; 1573 } 1574 case DISPATCH_PROCESS_DIED: { 1575 final int pid = msg.arg1; 1576 final int uid = msg.arg2; 1577 dispatchProcessDied(pid, uid); 1578 break; 1579 } 1580 case REPORT_MEM_USAGE_MSG: { 1581 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1582 Thread thread = new Thread() { 1583 @Override public void run() { 1584 final SparseArray<ProcessMemInfo> infoMap 1585 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1586 for (int i=0, N=memInfos.size(); i<N; i++) { 1587 ProcessMemInfo mi = memInfos.get(i); 1588 infoMap.put(mi.pid, mi); 1589 } 1590 updateCpuStatsNow(); 1591 synchronized (mProcessCpuThread) { 1592 final int N = mProcessCpuTracker.countStats(); 1593 for (int i=0; i<N; i++) { 1594 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1595 if (st.vsize > 0) { 1596 long pss = Debug.getPss(st.pid, null); 1597 if (pss > 0) { 1598 if (infoMap.indexOfKey(st.pid) < 0) { 1599 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1600 ProcessList.NATIVE_ADJ, -1, "native", null); 1601 mi.pss = pss; 1602 memInfos.add(mi); 1603 } 1604 } 1605 } 1606 } 1607 } 1608 1609 long totalPss = 0; 1610 for (int i=0, N=memInfos.size(); i<N; i++) { 1611 ProcessMemInfo mi = memInfos.get(i); 1612 if (mi.pss == 0) { 1613 mi.pss = Debug.getPss(mi.pid, null); 1614 } 1615 totalPss += mi.pss; 1616 } 1617 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1618 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1619 if (lhs.oomAdj != rhs.oomAdj) { 1620 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1621 } 1622 if (lhs.pss != rhs.pss) { 1623 return lhs.pss < rhs.pss ? 1 : -1; 1624 } 1625 return 0; 1626 } 1627 }); 1628 1629 StringBuilder tag = new StringBuilder(128); 1630 StringBuilder stack = new StringBuilder(128); 1631 tag.append("Low on memory -- "); 1632 appendMemBucket(tag, totalPss, "total", false); 1633 appendMemBucket(stack, totalPss, "total", true); 1634 1635 StringBuilder logBuilder = new StringBuilder(1024); 1636 logBuilder.append("Low on memory:\n"); 1637 1638 boolean firstLine = true; 1639 int lastOomAdj = Integer.MIN_VALUE; 1640 for (int i=0, N=memInfos.size(); i<N; i++) { 1641 ProcessMemInfo mi = memInfos.get(i); 1642 1643 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1644 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1645 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1646 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1647 if (lastOomAdj != mi.oomAdj) { 1648 lastOomAdj = mi.oomAdj; 1649 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1650 tag.append(" / "); 1651 } 1652 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1653 if (firstLine) { 1654 stack.append(":"); 1655 firstLine = false; 1656 } 1657 stack.append("\n\t at "); 1658 } else { 1659 stack.append("$"); 1660 } 1661 } else { 1662 tag.append(" "); 1663 stack.append("$"); 1664 } 1665 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1666 appendMemBucket(tag, mi.pss, mi.name, false); 1667 } 1668 appendMemBucket(stack, mi.pss, mi.name, true); 1669 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1670 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1671 stack.append("("); 1672 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1673 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1674 stack.append(DUMP_MEM_OOM_LABEL[k]); 1675 stack.append(":"); 1676 stack.append(DUMP_MEM_OOM_ADJ[k]); 1677 } 1678 } 1679 stack.append(")"); 1680 } 1681 } 1682 1683 logBuilder.append(" "); 1684 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1685 logBuilder.append(' '); 1686 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1687 logBuilder.append(' '); 1688 ProcessList.appendRamKb(logBuilder, mi.pss); 1689 logBuilder.append(" kB: "); 1690 logBuilder.append(mi.name); 1691 logBuilder.append(" ("); 1692 logBuilder.append(mi.pid); 1693 logBuilder.append(") "); 1694 logBuilder.append(mi.adjType); 1695 logBuilder.append('\n'); 1696 if (mi.adjReason != null) { 1697 logBuilder.append(" "); 1698 logBuilder.append(mi.adjReason); 1699 logBuilder.append('\n'); 1700 } 1701 } 1702 1703 logBuilder.append(" "); 1704 ProcessList.appendRamKb(logBuilder, totalPss); 1705 logBuilder.append(" kB: TOTAL\n"); 1706 1707 long[] infos = new long[Debug.MEMINFO_COUNT]; 1708 Debug.getMemInfo(infos); 1709 logBuilder.append(" MemInfo: "); 1710 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1711 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1712 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1713 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1714 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1715 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1716 logBuilder.append(" ZRAM: "); 1717 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1718 logBuilder.append(" kB RAM, "); 1719 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1720 logBuilder.append(" kB swap total, "); 1721 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1722 logBuilder.append(" kB swap free\n"); 1723 } 1724 Slog.i(TAG, logBuilder.toString()); 1725 1726 StringBuilder dropBuilder = new StringBuilder(1024); 1727 /* 1728 StringWriter oomSw = new StringWriter(); 1729 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1730 StringWriter catSw = new StringWriter(); 1731 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1732 String[] emptyArgs = new String[] { }; 1733 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1734 oomPw.flush(); 1735 String oomString = oomSw.toString(); 1736 */ 1737 dropBuilder.append(stack); 1738 dropBuilder.append('\n'); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append(logBuilder); 1741 dropBuilder.append('\n'); 1742 /* 1743 dropBuilder.append(oomString); 1744 dropBuilder.append('\n'); 1745 */ 1746 StringWriter catSw = new StringWriter(); 1747 synchronized (ActivityManagerService.this) { 1748 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1749 String[] emptyArgs = new String[] { }; 1750 catPw.println(); 1751 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1752 catPw.println(); 1753 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1754 false, false, null); 1755 catPw.println(); 1756 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1757 catPw.flush(); 1758 } 1759 dropBuilder.append(catSw.toString()); 1760 addErrorToDropBox("lowmem", null, "system_server", null, 1761 null, tag.toString(), dropBuilder.toString(), null, null); 1762 //Slog.i(TAG, "Sent to dropbox:"); 1763 //Slog.i(TAG, dropBuilder.toString()); 1764 synchronized (ActivityManagerService.this) { 1765 long now = SystemClock.uptimeMillis(); 1766 if (mLastMemUsageReportTime < now) { 1767 mLastMemUsageReportTime = now; 1768 } 1769 } 1770 } 1771 }; 1772 thread.start(); 1773 break; 1774 } 1775 case START_USER_SWITCH_MSG: { 1776 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1777 break; 1778 } 1779 case REPORT_USER_SWITCH_MSG: { 1780 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1781 break; 1782 } 1783 case CONTINUE_USER_SWITCH_MSG: { 1784 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1785 break; 1786 } 1787 case USER_SWITCH_TIMEOUT_MSG: { 1788 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1789 break; 1790 } 1791 case IMMERSIVE_MODE_LOCK_MSG: { 1792 final boolean nextState = (msg.arg1 != 0); 1793 if (mUpdateLock.isHeld() != nextState) { 1794 if (DEBUG_IMMERSIVE) { 1795 final ActivityRecord r = (ActivityRecord) msg.obj; 1796 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1797 } 1798 if (nextState) { 1799 mUpdateLock.acquire(); 1800 } else { 1801 mUpdateLock.release(); 1802 } 1803 } 1804 break; 1805 } 1806 case PERSIST_URI_GRANTS_MSG: { 1807 writeGrantedUriPermissions(); 1808 break; 1809 } 1810 case REQUEST_ALL_PSS_MSG: { 1811 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1812 break; 1813 } 1814 case START_PROFILES_MSG: { 1815 synchronized (ActivityManagerService.this) { 1816 startProfilesLocked(); 1817 } 1818 break; 1819 } 1820 case UPDATE_TIME: { 1821 synchronized (ActivityManagerService.this) { 1822 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1823 ProcessRecord r = mLruProcesses.get(i); 1824 if (r.thread != null) { 1825 try { 1826 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1827 } catch (RemoteException ex) { 1828 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1829 } 1830 } 1831 } 1832 } 1833 break; 1834 } 1835 case SYSTEM_USER_START_MSG: { 1836 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1837 Integer.toString(msg.arg1), msg.arg1); 1838 mSystemServiceManager.startUser(msg.arg1); 1839 break; 1840 } 1841 case SYSTEM_USER_CURRENT_MSG: { 1842 mBatteryStatsService.noteEvent( 1843 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1844 Integer.toString(msg.arg2), msg.arg2); 1845 mBatteryStatsService.noteEvent( 1846 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1847 Integer.toString(msg.arg1), msg.arg1); 1848 mSystemServiceManager.switchUser(msg.arg1); 1849 mLockToAppRequest.clearPrompt(); 1850 break; 1851 } 1852 case ENTER_ANIMATION_COMPLETE_MSG: { 1853 synchronized (ActivityManagerService.this) { 1854 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1855 if (r != null && r.app != null && r.app.thread != null) { 1856 try { 1857 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1858 } catch (RemoteException e) { 1859 } 1860 } 1861 } 1862 break; 1863 } 1864 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1865 enableScreenAfterBoot(); 1866 break; 1867 } 1868 } 1869 } 1870 }; 1871 1872 static final int COLLECT_PSS_BG_MSG = 1; 1873 1874 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1875 @Override 1876 public void handleMessage(Message msg) { 1877 switch (msg.what) { 1878 case COLLECT_PSS_BG_MSG: { 1879 long start = SystemClock.uptimeMillis(); 1880 MemInfoReader memInfo = null; 1881 synchronized (ActivityManagerService.this) { 1882 if (mFullPssPending) { 1883 mFullPssPending = false; 1884 memInfo = new MemInfoReader(); 1885 } 1886 } 1887 if (memInfo != null) { 1888 updateCpuStatsNow(); 1889 long nativeTotalPss = 0; 1890 synchronized (mProcessCpuThread) { 1891 final int N = mProcessCpuTracker.countStats(); 1892 for (int j=0; j<N; j++) { 1893 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1894 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1895 // This is definitely an application process; skip it. 1896 continue; 1897 } 1898 synchronized (mPidsSelfLocked) { 1899 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1900 // This is one of our own processes; skip it. 1901 continue; 1902 } 1903 } 1904 nativeTotalPss += Debug.getPss(st.pid, null); 1905 } 1906 } 1907 memInfo.readMemInfo(); 1908 synchronized (this) { 1909 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1910 + (SystemClock.uptimeMillis()-start) + "ms"); 1911 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1912 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1913 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1914 +memInfo.getSlabSizeKb(), 1915 nativeTotalPss); 1916 } 1917 } 1918 1919 int i=0, num=0; 1920 long[] tmp = new long[1]; 1921 do { 1922 ProcessRecord proc; 1923 int procState; 1924 int pid; 1925 synchronized (ActivityManagerService.this) { 1926 if (i >= mPendingPssProcesses.size()) { 1927 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1928 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1929 mPendingPssProcesses.clear(); 1930 return; 1931 } 1932 proc = mPendingPssProcesses.get(i); 1933 procState = proc.pssProcState; 1934 if (proc.thread != null && procState == proc.setProcState) { 1935 pid = proc.pid; 1936 } else { 1937 proc = null; 1938 pid = 0; 1939 } 1940 i++; 1941 } 1942 if (proc != null) { 1943 long pss = Debug.getPss(pid, tmp); 1944 synchronized (ActivityManagerService.this) { 1945 if (proc.thread != null && proc.setProcState == procState 1946 && proc.pid == pid) { 1947 num++; 1948 proc.lastPssTime = SystemClock.uptimeMillis(); 1949 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1950 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1951 + ": " + pss + " lastPss=" + proc.lastPss 1952 + " state=" + ProcessList.makeProcStateString(procState)); 1953 if (proc.initialIdlePss == 0) { 1954 proc.initialIdlePss = pss; 1955 } 1956 proc.lastPss = pss; 1957 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1958 proc.lastCachedPss = pss; 1959 } 1960 } 1961 } 1962 } 1963 } while (true); 1964 } 1965 } 1966 } 1967 }; 1968 1969 /** 1970 * Monitor for package changes and update our internal state. 1971 */ 1972 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1973 @Override 1974 public void onPackageRemoved(String packageName, int uid) { 1975 // Remove all tasks with activities in the specified package from the list of recent tasks 1976 synchronized (ActivityManagerService.this) { 1977 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1978 TaskRecord tr = mRecentTasks.get(i); 1979 ComponentName cn = tr.intent.getComponent(); 1980 if (cn != null && cn.getPackageName().equals(packageName)) { 1981 // If the package name matches, remove the task and kill the process 1982 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1983 } 1984 } 1985 } 1986 } 1987 1988 @Override 1989 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1990 onPackageModified(packageName); 1991 return true; 1992 } 1993 1994 @Override 1995 public void onPackageModified(String packageName) { 1996 final PackageManager pm = mContext.getPackageManager(); 1997 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1998 new ArrayList<Pair<Intent, Integer>>(); 1999 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2000 // Copy the list of recent tasks so that we don't hold onto the lock on 2001 // ActivityManagerService for long periods while checking if components exist. 2002 synchronized (ActivityManagerService.this) { 2003 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2004 TaskRecord tr = mRecentTasks.get(i); 2005 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2006 } 2007 } 2008 // Check the recent tasks and filter out all tasks with components that no longer exist. 2009 Intent tmpI = new Intent(); 2010 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2011 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2012 ComponentName cn = p.first.getComponent(); 2013 if (cn != null && cn.getPackageName().equals(packageName)) { 2014 try { 2015 // Add the task to the list to remove if the component no longer exists 2016 tmpI.setComponent(cn); 2017 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2018 tasksToRemove.add(p.second); 2019 } 2020 } catch (Exception e) {} 2021 } 2022 } 2023 // Prune all the tasks with removed components from the list of recent tasks 2024 synchronized (ActivityManagerService.this) { 2025 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2026 // Remove the task but don't kill the process (since other components in that 2027 // package may still be running and in the background) 2028 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2035 // Force stop the specified packages 2036 if (packages != null) { 2037 for (String pkg : packages) { 2038 synchronized (ActivityManagerService.this) { 2039 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2040 "finished booting")) { 2041 return true; 2042 } 2043 } 2044 } 2045 } 2046 return false; 2047 } 2048 }; 2049 2050 public void setSystemProcess() { 2051 try { 2052 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2053 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2054 ServiceManager.addService("meminfo", new MemBinder(this)); 2055 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2056 ServiceManager.addService("dbinfo", new DbBinder(this)); 2057 if (MONITOR_CPU_USAGE) { 2058 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2059 } 2060 ServiceManager.addService("permission", new PermissionController(this)); 2061 2062 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2063 "android", STOCK_PM_FLAGS); 2064 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2065 2066 synchronized (this) { 2067 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2068 app.persistent = true; 2069 app.pid = MY_PID; 2070 app.maxAdj = ProcessList.SYSTEM_ADJ; 2071 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2072 mProcessNames.put(app.processName, app.uid, app); 2073 synchronized (mPidsSelfLocked) { 2074 mPidsSelfLocked.put(app.pid, app); 2075 } 2076 updateLruProcessLocked(app, false, null); 2077 updateOomAdjLocked(); 2078 } 2079 } catch (PackageManager.NameNotFoundException e) { 2080 throw new RuntimeException( 2081 "Unable to find android system package", e); 2082 } 2083 } 2084 2085 public void setWindowManager(WindowManagerService wm) { 2086 mWindowManager = wm; 2087 mStackSupervisor.setWindowManager(wm); 2088 } 2089 2090 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2091 mUsageStatsService = usageStatsManager; 2092 } 2093 2094 public void startObservingNativeCrashes() { 2095 final NativeCrashListener ncl = new NativeCrashListener(this); 2096 ncl.start(); 2097 } 2098 2099 public IAppOpsService getAppOpsService() { 2100 return mAppOpsService; 2101 } 2102 2103 static class MemBinder extends Binder { 2104 ActivityManagerService mActivityManagerService; 2105 MemBinder(ActivityManagerService activityManagerService) { 2106 mActivityManagerService = activityManagerService; 2107 } 2108 2109 @Override 2110 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2111 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2112 != PackageManager.PERMISSION_GRANTED) { 2113 pw.println("Permission Denial: can't dump meminfo from from pid=" 2114 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2115 + " without permission " + android.Manifest.permission.DUMP); 2116 return; 2117 } 2118 2119 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2120 } 2121 } 2122 2123 static class GraphicsBinder extends Binder { 2124 ActivityManagerService mActivityManagerService; 2125 GraphicsBinder(ActivityManagerService activityManagerService) { 2126 mActivityManagerService = activityManagerService; 2127 } 2128 2129 @Override 2130 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2131 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2132 != PackageManager.PERMISSION_GRANTED) { 2133 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2134 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2135 + " without permission " + android.Manifest.permission.DUMP); 2136 return; 2137 } 2138 2139 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2140 } 2141 } 2142 2143 static class DbBinder extends Binder { 2144 ActivityManagerService mActivityManagerService; 2145 DbBinder(ActivityManagerService activityManagerService) { 2146 mActivityManagerService = activityManagerService; 2147 } 2148 2149 @Override 2150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2151 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2152 != PackageManager.PERMISSION_GRANTED) { 2153 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2154 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2155 + " without permission " + android.Manifest.permission.DUMP); 2156 return; 2157 } 2158 2159 mActivityManagerService.dumpDbInfo(fd, pw, args); 2160 } 2161 } 2162 2163 static class CpuBinder extends Binder { 2164 ActivityManagerService mActivityManagerService; 2165 CpuBinder(ActivityManagerService activityManagerService) { 2166 mActivityManagerService = activityManagerService; 2167 } 2168 2169 @Override 2170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2171 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2172 != PackageManager.PERMISSION_GRANTED) { 2173 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2174 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2175 + " without permission " + android.Manifest.permission.DUMP); 2176 return; 2177 } 2178 2179 synchronized (mActivityManagerService.mProcessCpuThread) { 2180 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2182 SystemClock.uptimeMillis())); 2183 } 2184 } 2185 } 2186 2187 public static final class Lifecycle extends SystemService { 2188 private final ActivityManagerService mService; 2189 2190 public Lifecycle(Context context) { 2191 super(context); 2192 mService = new ActivityManagerService(context); 2193 } 2194 2195 @Override 2196 public void onStart() { 2197 mService.start(); 2198 } 2199 2200 public ActivityManagerService getService() { 2201 return mService; 2202 } 2203 } 2204 2205 // Note: This method is invoked on the main thread but may need to attach various 2206 // handlers to other threads. So take care to be explicit about the looper. 2207 public ActivityManagerService(Context systemContext) { 2208 mContext = systemContext; 2209 mFactoryTest = FactoryTest.getMode(); 2210 mSystemThread = ActivityThread.currentActivityThread(); 2211 2212 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2213 2214 mHandlerThread = new ServiceThread(TAG, 2215 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2216 mHandlerThread.start(); 2217 mHandler = new MainHandler(mHandlerThread.getLooper()); 2218 2219 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2220 "foreground", BROADCAST_FG_TIMEOUT, false); 2221 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2222 "background", BROADCAST_BG_TIMEOUT, true); 2223 mBroadcastQueues[0] = mFgBroadcastQueue; 2224 mBroadcastQueues[1] = mBgBroadcastQueue; 2225 2226 mServices = new ActiveServices(this); 2227 mProviderMap = new ProviderMap(this); 2228 2229 // TODO: Move creation of battery stats service outside of activity manager service. 2230 File dataDir = Environment.getDataDirectory(); 2231 File systemDir = new File(dataDir, "system"); 2232 systemDir.mkdirs(); 2233 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2234 mBatteryStatsService.getActiveStatistics().readLocked(); 2235 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2236 mOnBattery = DEBUG_POWER ? true 2237 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2238 mBatteryStatsService.getActiveStatistics().setCallback(this); 2239 2240 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2241 2242 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2243 2244 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2245 2246 // User 0 is the first and only user that runs at boot. 2247 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2248 mUserLru.add(Integer.valueOf(0)); 2249 updateStartedUserArrayLocked(); 2250 2251 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2252 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2253 2254 mConfiguration.setToDefaults(); 2255 mConfiguration.setLocale(Locale.getDefault()); 2256 2257 mConfigurationSeq = mConfiguration.seq = 1; 2258 mProcessCpuTracker.init(); 2259 2260 final Resources res = mContext.getResources(); 2261 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 2262 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2263 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2264 2265 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2266 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2267 mStackSupervisor = new ActivityStackSupervisor(this); 2268 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2269 2270 mProcessCpuThread = new Thread("CpuTracker") { 2271 @Override 2272 public void run() { 2273 while (true) { 2274 try { 2275 try { 2276 synchronized(this) { 2277 final long now = SystemClock.uptimeMillis(); 2278 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2279 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2280 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2281 // + ", write delay=" + nextWriteDelay); 2282 if (nextWriteDelay < nextCpuDelay) { 2283 nextCpuDelay = nextWriteDelay; 2284 } 2285 if (nextCpuDelay > 0) { 2286 mProcessCpuMutexFree.set(true); 2287 this.wait(nextCpuDelay); 2288 } 2289 } 2290 } catch (InterruptedException e) { 2291 } 2292 updateCpuStatsNow(); 2293 } catch (Exception e) { 2294 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2295 } 2296 } 2297 } 2298 }; 2299 2300 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2301 2302 Watchdog.getInstance().addMonitor(this); 2303 Watchdog.getInstance().addThread(mHandler); 2304 } 2305 2306 public void setSystemServiceManager(SystemServiceManager mgr) { 2307 mSystemServiceManager = mgr; 2308 } 2309 2310 private void start() { 2311 Process.removeAllProcessGroups(); 2312 mProcessCpuThread.start(); 2313 2314 mBatteryStatsService.publish(mContext); 2315 mAppOpsService.publish(mContext); 2316 Slog.d("AppOps", "AppOpsService published"); 2317 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2318 } 2319 2320 public void initPowerManagement() { 2321 mStackSupervisor.initPowerManagement(); 2322 mBatteryStatsService.initPowerManagement(); 2323 } 2324 2325 @Override 2326 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2327 throws RemoteException { 2328 if (code == SYSPROPS_TRANSACTION) { 2329 // We need to tell all apps about the system property change. 2330 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2331 synchronized(this) { 2332 final int NP = mProcessNames.getMap().size(); 2333 for (int ip=0; ip<NP; ip++) { 2334 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2335 final int NA = apps.size(); 2336 for (int ia=0; ia<NA; ia++) { 2337 ProcessRecord app = apps.valueAt(ia); 2338 if (app.thread != null) { 2339 procs.add(app.thread.asBinder()); 2340 } 2341 } 2342 } 2343 } 2344 2345 int N = procs.size(); 2346 for (int i=0; i<N; i++) { 2347 Parcel data2 = Parcel.obtain(); 2348 try { 2349 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2350 } catch (RemoteException e) { 2351 } 2352 data2.recycle(); 2353 } 2354 } 2355 try { 2356 return super.onTransact(code, data, reply, flags); 2357 } catch (RuntimeException e) { 2358 // The activity manager only throws security exceptions, so let's 2359 // log all others. 2360 if (!(e instanceof SecurityException)) { 2361 Slog.wtf(TAG, "Activity Manager Crash", e); 2362 } 2363 throw e; 2364 } 2365 } 2366 2367 void updateCpuStats() { 2368 final long now = SystemClock.uptimeMillis(); 2369 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2370 return; 2371 } 2372 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2373 synchronized (mProcessCpuThread) { 2374 mProcessCpuThread.notify(); 2375 } 2376 } 2377 } 2378 2379 void updateCpuStatsNow() { 2380 synchronized (mProcessCpuThread) { 2381 mProcessCpuMutexFree.set(false); 2382 final long now = SystemClock.uptimeMillis(); 2383 boolean haveNewCpuStats = false; 2384 2385 if (MONITOR_CPU_USAGE && 2386 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2387 mLastCpuTime.set(now); 2388 haveNewCpuStats = true; 2389 mProcessCpuTracker.update(); 2390 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2391 //Slog.i(TAG, "Total CPU usage: " 2392 // + mProcessCpu.getTotalCpuPercent() + "%"); 2393 2394 // Slog the cpu usage if the property is set. 2395 if ("true".equals(SystemProperties.get("events.cpu"))) { 2396 int user = mProcessCpuTracker.getLastUserTime(); 2397 int system = mProcessCpuTracker.getLastSystemTime(); 2398 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2399 int irq = mProcessCpuTracker.getLastIrqTime(); 2400 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2401 int idle = mProcessCpuTracker.getLastIdleTime(); 2402 2403 int total = user + system + iowait + irq + softIrq + idle; 2404 if (total == 0) total = 1; 2405 2406 EventLog.writeEvent(EventLogTags.CPU, 2407 ((user+system+iowait+irq+softIrq) * 100) / total, 2408 (user * 100) / total, 2409 (system * 100) / total, 2410 (iowait * 100) / total, 2411 (irq * 100) / total, 2412 (softIrq * 100) / total); 2413 } 2414 } 2415 2416 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2417 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2418 synchronized(bstats) { 2419 synchronized(mPidsSelfLocked) { 2420 if (haveNewCpuStats) { 2421 if (mOnBattery) { 2422 int perc = bstats.startAddingCpuLocked(); 2423 int totalUTime = 0; 2424 int totalSTime = 0; 2425 final int N = mProcessCpuTracker.countStats(); 2426 for (int i=0; i<N; i++) { 2427 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2428 if (!st.working) { 2429 continue; 2430 } 2431 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2432 int otherUTime = (st.rel_utime*perc)/100; 2433 int otherSTime = (st.rel_stime*perc)/100; 2434 totalUTime += otherUTime; 2435 totalSTime += otherSTime; 2436 if (pr != null) { 2437 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2438 if (ps == null || !ps.isActive()) { 2439 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2440 pr.info.uid, pr.processName); 2441 } 2442 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2443 st.rel_stime-otherSTime); 2444 ps.addSpeedStepTimes(cpuSpeedTimes); 2445 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2446 } else { 2447 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2448 if (ps == null || !ps.isActive()) { 2449 st.batteryStats = ps = bstats.getProcessStatsLocked( 2450 bstats.mapUid(st.uid), st.name); 2451 } 2452 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2453 st.rel_stime-otherSTime); 2454 ps.addSpeedStepTimes(cpuSpeedTimes); 2455 } 2456 } 2457 bstats.finishAddingCpuLocked(perc, totalUTime, 2458 totalSTime, cpuSpeedTimes); 2459 } 2460 } 2461 } 2462 2463 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2464 mLastWriteTime = now; 2465 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2466 } 2467 } 2468 } 2469 } 2470 2471 @Override 2472 public void batteryNeedsCpuUpdate() { 2473 updateCpuStatsNow(); 2474 } 2475 2476 @Override 2477 public void batteryPowerChanged(boolean onBattery) { 2478 // When plugging in, update the CPU stats first before changing 2479 // the plug state. 2480 updateCpuStatsNow(); 2481 synchronized (this) { 2482 synchronized(mPidsSelfLocked) { 2483 mOnBattery = DEBUG_POWER ? true : onBattery; 2484 } 2485 } 2486 } 2487 2488 /** 2489 * Initialize the application bind args. These are passed to each 2490 * process when the bindApplication() IPC is sent to the process. They're 2491 * lazily setup to make sure the services are running when they're asked for. 2492 */ 2493 private HashMap<String, IBinder> getCommonServicesLocked() { 2494 if (mAppBindArgs == null) { 2495 mAppBindArgs = new HashMap<String, IBinder>(); 2496 2497 // Setup the application init args 2498 mAppBindArgs.put("package", ServiceManager.getService("package")); 2499 mAppBindArgs.put("window", ServiceManager.getService("window")); 2500 mAppBindArgs.put(Context.ALARM_SERVICE, 2501 ServiceManager.getService(Context.ALARM_SERVICE)); 2502 } 2503 return mAppBindArgs; 2504 } 2505 2506 final void setFocusedActivityLocked(ActivityRecord r) { 2507 if (mFocusedActivity != r) { 2508 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2509 mFocusedActivity = r; 2510 if (r.task != null && r.task.voiceInteractor != null) { 2511 startRunningVoiceLocked(); 2512 } else { 2513 finishRunningVoiceLocked(); 2514 } 2515 mStackSupervisor.setFocusedStack(r); 2516 if (r != null) { 2517 mWindowManager.setFocusedApp(r.appToken, true); 2518 } 2519 applyUpdateLockStateLocked(r); 2520 } 2521 } 2522 2523 final void clearFocusedActivity(ActivityRecord r) { 2524 if (mFocusedActivity == r) { 2525 mFocusedActivity = null; 2526 } 2527 } 2528 2529 @Override 2530 public void setFocusedStack(int stackId) { 2531 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2532 synchronized (ActivityManagerService.this) { 2533 ActivityStack stack = mStackSupervisor.getStack(stackId); 2534 if (stack != null) { 2535 ActivityRecord r = stack.topRunningActivityLocked(null); 2536 if (r != null) { 2537 setFocusedActivityLocked(r); 2538 } 2539 } 2540 } 2541 } 2542 2543 @Override 2544 public void notifyActivityDrawn(IBinder token) { 2545 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2546 synchronized (this) { 2547 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2548 if (r != null) { 2549 r.task.stack.notifyActivityDrawnLocked(r); 2550 } 2551 } 2552 } 2553 2554 final void applyUpdateLockStateLocked(ActivityRecord r) { 2555 // Modifications to the UpdateLock state are done on our handler, outside 2556 // the activity manager's locks. The new state is determined based on the 2557 // state *now* of the relevant activity record. The object is passed to 2558 // the handler solely for logging detail, not to be consulted/modified. 2559 final boolean nextState = r != null && r.immersive; 2560 mHandler.sendMessage( 2561 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2562 } 2563 2564 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2565 Message msg = Message.obtain(); 2566 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2567 msg.obj = r.task.askedCompatMode ? null : r; 2568 mHandler.sendMessage(msg); 2569 } 2570 2571 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2572 String what, Object obj, ProcessRecord srcApp) { 2573 app.lastActivityTime = now; 2574 2575 if (app.activities.size() > 0) { 2576 // Don't want to touch dependent processes that are hosting activities. 2577 return index; 2578 } 2579 2580 int lrui = mLruProcesses.lastIndexOf(app); 2581 if (lrui < 0) { 2582 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2583 + what + " " + obj + " from " + srcApp); 2584 return index; 2585 } 2586 2587 if (lrui >= index) { 2588 // Don't want to cause this to move dependent processes *back* in the 2589 // list as if they were less frequently used. 2590 return index; 2591 } 2592 2593 if (lrui >= mLruProcessActivityStart) { 2594 // Don't want to touch dependent processes that are hosting activities. 2595 return index; 2596 } 2597 2598 mLruProcesses.remove(lrui); 2599 if (index > 0) { 2600 index--; 2601 } 2602 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2603 + " in LRU list: " + app); 2604 mLruProcesses.add(index, app); 2605 return index; 2606 } 2607 2608 final void removeLruProcessLocked(ProcessRecord app) { 2609 int lrui = mLruProcesses.lastIndexOf(app); 2610 if (lrui >= 0) { 2611 if (lrui <= mLruProcessActivityStart) { 2612 mLruProcessActivityStart--; 2613 } 2614 if (lrui <= mLruProcessServiceStart) { 2615 mLruProcessServiceStart--; 2616 } 2617 mLruProcesses.remove(lrui); 2618 } 2619 } 2620 2621 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2622 ProcessRecord client) { 2623 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2624 || app.treatLikeActivity; 2625 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2626 if (!activityChange && hasActivity) { 2627 // The process has activities, so we are only allowing activity-based adjustments 2628 // to move it. It should be kept in the front of the list with other 2629 // processes that have activities, and we don't want those to change their 2630 // order except due to activity operations. 2631 return; 2632 } 2633 2634 mLruSeq++; 2635 final long now = SystemClock.uptimeMillis(); 2636 app.lastActivityTime = now; 2637 2638 // First a quick reject: if the app is already at the position we will 2639 // put it, then there is nothing to do. 2640 if (hasActivity) { 2641 final int N = mLruProcesses.size(); 2642 if (N > 0 && mLruProcesses.get(N-1) == app) { 2643 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2644 return; 2645 } 2646 } else { 2647 if (mLruProcessServiceStart > 0 2648 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2649 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2650 return; 2651 } 2652 } 2653 2654 int lrui = mLruProcesses.lastIndexOf(app); 2655 2656 if (app.persistent && lrui >= 0) { 2657 // We don't care about the position of persistent processes, as long as 2658 // they are in the list. 2659 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2660 return; 2661 } 2662 2663 /* In progress: compute new position first, so we can avoid doing work 2664 if the process is not actually going to move. Not yet working. 2665 int addIndex; 2666 int nextIndex; 2667 boolean inActivity = false, inService = false; 2668 if (hasActivity) { 2669 // Process has activities, put it at the very tipsy-top. 2670 addIndex = mLruProcesses.size(); 2671 nextIndex = mLruProcessServiceStart; 2672 inActivity = true; 2673 } else if (hasService) { 2674 // Process has services, put it at the top of the service list. 2675 addIndex = mLruProcessActivityStart; 2676 nextIndex = mLruProcessServiceStart; 2677 inActivity = true; 2678 inService = true; 2679 } else { 2680 // Process not otherwise of interest, it goes to the top of the non-service area. 2681 addIndex = mLruProcessServiceStart; 2682 if (client != null) { 2683 int clientIndex = mLruProcesses.lastIndexOf(client); 2684 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2685 + app); 2686 if (clientIndex >= 0 && addIndex > clientIndex) { 2687 addIndex = clientIndex; 2688 } 2689 } 2690 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2691 } 2692 2693 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2694 + mLruProcessActivityStart + "): " + app); 2695 */ 2696 2697 if (lrui >= 0) { 2698 if (lrui < mLruProcessActivityStart) { 2699 mLruProcessActivityStart--; 2700 } 2701 if (lrui < mLruProcessServiceStart) { 2702 mLruProcessServiceStart--; 2703 } 2704 /* 2705 if (addIndex > lrui) { 2706 addIndex--; 2707 } 2708 if (nextIndex > lrui) { 2709 nextIndex--; 2710 } 2711 */ 2712 mLruProcesses.remove(lrui); 2713 } 2714 2715 /* 2716 mLruProcesses.add(addIndex, app); 2717 if (inActivity) { 2718 mLruProcessActivityStart++; 2719 } 2720 if (inService) { 2721 mLruProcessActivityStart++; 2722 } 2723 */ 2724 2725 int nextIndex; 2726 if (hasActivity) { 2727 final int N = mLruProcesses.size(); 2728 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2729 // Process doesn't have activities, but has clients with 2730 // activities... move it up, but one below the top (the top 2731 // should always have a real activity). 2732 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2733 mLruProcesses.add(N-1, app); 2734 // To keep it from spamming the LRU list (by making a bunch of clients), 2735 // we will push down any other entries owned by the app. 2736 final int uid = app.info.uid; 2737 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2738 ProcessRecord subProc = mLruProcesses.get(i); 2739 if (subProc.info.uid == uid) { 2740 // We want to push this one down the list. If the process after 2741 // it is for the same uid, however, don't do so, because we don't 2742 // want them internally to be re-ordered. 2743 if (mLruProcesses.get(i-1).info.uid != uid) { 2744 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2745 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2746 ProcessRecord tmp = mLruProcesses.get(i); 2747 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2748 mLruProcesses.set(i-1, tmp); 2749 i--; 2750 } 2751 } else { 2752 // A gap, we can stop here. 2753 break; 2754 } 2755 } 2756 } else { 2757 // Process has activities, put it at the very tipsy-top. 2758 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2759 mLruProcesses.add(app); 2760 } 2761 nextIndex = mLruProcessServiceStart; 2762 } else if (hasService) { 2763 // Process has services, put it at the top of the service list. 2764 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2765 mLruProcesses.add(mLruProcessActivityStart, app); 2766 nextIndex = mLruProcessServiceStart; 2767 mLruProcessActivityStart++; 2768 } else { 2769 // Process not otherwise of interest, it goes to the top of the non-service area. 2770 int index = mLruProcessServiceStart; 2771 if (client != null) { 2772 // If there is a client, don't allow the process to be moved up higher 2773 // in the list than that client. 2774 int clientIndex = mLruProcesses.lastIndexOf(client); 2775 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2776 + " when updating " + app); 2777 if (clientIndex <= lrui) { 2778 // Don't allow the client index restriction to push it down farther in the 2779 // list than it already is. 2780 clientIndex = lrui; 2781 } 2782 if (clientIndex >= 0 && index > clientIndex) { 2783 index = clientIndex; 2784 } 2785 } 2786 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2787 mLruProcesses.add(index, app); 2788 nextIndex = index-1; 2789 mLruProcessActivityStart++; 2790 mLruProcessServiceStart++; 2791 } 2792 2793 // If the app is currently using a content provider or service, 2794 // bump those processes as well. 2795 for (int j=app.connections.size()-1; j>=0; j--) { 2796 ConnectionRecord cr = app.connections.valueAt(j); 2797 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2798 && cr.binding.service.app != null 2799 && cr.binding.service.app.lruSeq != mLruSeq 2800 && !cr.binding.service.app.persistent) { 2801 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2802 "service connection", cr, app); 2803 } 2804 } 2805 for (int j=app.conProviders.size()-1; j>=0; j--) { 2806 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2807 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2808 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2809 "provider reference", cpr, app); 2810 } 2811 } 2812 } 2813 2814 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2815 if (uid == Process.SYSTEM_UID) { 2816 // The system gets to run in any process. If there are multiple 2817 // processes with the same uid, just pick the first (this 2818 // should never happen). 2819 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2820 if (procs == null) return null; 2821 final int N = procs.size(); 2822 for (int i = 0; i < N; i++) { 2823 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2824 } 2825 } 2826 ProcessRecord proc = mProcessNames.get(processName, uid); 2827 if (false && proc != null && !keepIfLarge 2828 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2829 && proc.lastCachedPss >= 4000) { 2830 // Turn this condition on to cause killing to happen regularly, for testing. 2831 if (proc.baseProcessTracker != null) { 2832 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2833 } 2834 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2835 } else if (proc != null && !keepIfLarge 2836 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2837 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2838 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2839 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2840 if (proc.baseProcessTracker != null) { 2841 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2842 } 2843 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2844 } 2845 } 2846 return proc; 2847 } 2848 2849 void ensurePackageDexOpt(String packageName) { 2850 IPackageManager pm = AppGlobals.getPackageManager(); 2851 try { 2852 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2853 mDidDexOpt = true; 2854 } 2855 } catch (RemoteException e) { 2856 } 2857 } 2858 2859 boolean isNextTransitionForward() { 2860 int transit = mWindowManager.getPendingAppTransition(); 2861 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2862 || transit == AppTransition.TRANSIT_TASK_OPEN 2863 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2864 } 2865 2866 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2867 String processName, String abiOverride, int uid, Runnable crashHandler) { 2868 synchronized(this) { 2869 ApplicationInfo info = new ApplicationInfo(); 2870 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2871 // For isolated processes, the former contains the parent's uid and the latter the 2872 // actual uid of the isolated process. 2873 // In the special case introduced by this method (which is, starting an isolated 2874 // process directly from the SystemServer without an actual parent app process) the 2875 // closest thing to a parent's uid is SYSTEM_UID. 2876 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2877 // the |isolated| logic in the ProcessRecord constructor. 2878 info.uid = Process.SYSTEM_UID; 2879 info.processName = processName; 2880 info.className = entryPoint; 2881 info.packageName = "android"; 2882 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2883 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2884 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2885 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2886 crashHandler); 2887 return proc != null ? proc.pid : 0; 2888 } 2889 } 2890 2891 final ProcessRecord startProcessLocked(String processName, 2892 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2893 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2894 boolean isolated, boolean keepIfLarge) { 2895 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2896 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2897 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2898 null /* crashHandler */); 2899 } 2900 2901 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2902 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2903 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2904 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2905 ProcessRecord app; 2906 if (!isolated) { 2907 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2908 } else { 2909 // If this is an isolated process, it can't re-use an existing process. 2910 app = null; 2911 } 2912 // We don't have to do anything more if: 2913 // (1) There is an existing application record; and 2914 // (2) The caller doesn't think it is dead, OR there is no thread 2915 // object attached to it so we know it couldn't have crashed; and 2916 // (3) There is a pid assigned to it, so it is either starting or 2917 // already running. 2918 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2919 + " app=" + app + " knownToBeDead=" + knownToBeDead 2920 + " thread=" + (app != null ? app.thread : null) 2921 + " pid=" + (app != null ? app.pid : -1)); 2922 if (app != null && app.pid > 0) { 2923 if (!knownToBeDead || app.thread == null) { 2924 // We already have the app running, or are waiting for it to 2925 // come up (we have a pid but not yet its thread), so keep it. 2926 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2927 // If this is a new package in the process, add the package to the list 2928 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2929 return app; 2930 } 2931 2932 // An application record is attached to a previous process, 2933 // clean it up now. 2934 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2935 Process.killProcessGroup(app.info.uid, app.pid); 2936 handleAppDiedLocked(app, true, true); 2937 } 2938 2939 String hostingNameStr = hostingName != null 2940 ? hostingName.flattenToShortString() : null; 2941 2942 if (!isolated) { 2943 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2944 // If we are in the background, then check to see if this process 2945 // is bad. If so, we will just silently fail. 2946 if (mBadProcesses.get(info.processName, info.uid) != null) { 2947 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2948 + "/" + info.processName); 2949 return null; 2950 } 2951 } else { 2952 // When the user is explicitly starting a process, then clear its 2953 // crash count so that we won't make it bad until they see at 2954 // least one crash dialog again, and make the process good again 2955 // if it had been bad. 2956 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2957 + "/" + info.processName); 2958 mProcessCrashTimes.remove(info.processName, info.uid); 2959 if (mBadProcesses.get(info.processName, info.uid) != null) { 2960 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2961 UserHandle.getUserId(info.uid), info.uid, 2962 info.processName); 2963 mBadProcesses.remove(info.processName, info.uid); 2964 if (app != null) { 2965 app.bad = false; 2966 } 2967 } 2968 } 2969 } 2970 2971 if (app == null) { 2972 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2973 app.crashHandler = crashHandler; 2974 if (app == null) { 2975 Slog.w(TAG, "Failed making new process record for " 2976 + processName + "/" + info.uid + " isolated=" + isolated); 2977 return null; 2978 } 2979 mProcessNames.put(processName, app.uid, app); 2980 if (isolated) { 2981 mIsolatedProcesses.put(app.uid, app); 2982 } 2983 } else { 2984 // If this is a new package in the process, add the package to the list 2985 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2986 } 2987 2988 // If the system is not ready yet, then hold off on starting this 2989 // process until it is. 2990 if (!mProcessesReady 2991 && !isAllowedWhileBooting(info) 2992 && !allowWhileBooting) { 2993 if (!mProcessesOnHold.contains(app)) { 2994 mProcessesOnHold.add(app); 2995 } 2996 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2997 return app; 2998 } 2999 3000 startProcessLocked( 3001 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3002 return (app.pid != 0) ? app : null; 3003 } 3004 3005 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3006 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3007 } 3008 3009 private final void startProcessLocked(ProcessRecord app, 3010 String hostingType, String hostingNameStr) { 3011 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3012 null /* entryPoint */, null /* entryPointArgs */); 3013 } 3014 3015 private final void startProcessLocked(ProcessRecord app, String hostingType, 3016 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3017 if (app.pid > 0 && app.pid != MY_PID) { 3018 synchronized (mPidsSelfLocked) { 3019 mPidsSelfLocked.remove(app.pid); 3020 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3021 } 3022 app.setPid(0); 3023 } 3024 3025 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3026 "startProcessLocked removing on hold: " + app); 3027 mProcessesOnHold.remove(app); 3028 3029 updateCpuStats(); 3030 3031 try { 3032 int uid = app.uid; 3033 3034 int[] gids = null; 3035 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3036 if (!app.isolated) { 3037 int[] permGids = null; 3038 try { 3039 final PackageManager pm = mContext.getPackageManager(); 3040 permGids = pm.getPackageGids(app.info.packageName); 3041 3042 if (Environment.isExternalStorageEmulated()) { 3043 if (pm.checkPermission( 3044 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3045 app.info.packageName) == PERMISSION_GRANTED) { 3046 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3047 } else { 3048 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3049 } 3050 } 3051 } catch (PackageManager.NameNotFoundException e) { 3052 Slog.w(TAG, "Unable to retrieve gids", e); 3053 } 3054 3055 /* 3056 * Add shared application and profile GIDs so applications can share some 3057 * resources like shared libraries and access user-wide resources 3058 */ 3059 if (permGids == null) { 3060 gids = new int[2]; 3061 } else { 3062 gids = new int[permGids.length + 2]; 3063 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3064 } 3065 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3066 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3067 } 3068 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3069 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3070 && mTopComponent != null 3071 && app.processName.equals(mTopComponent.getPackageName())) { 3072 uid = 0; 3073 } 3074 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3075 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3076 uid = 0; 3077 } 3078 } 3079 int debugFlags = 0; 3080 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3081 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3082 // Also turn on CheckJNI for debuggable apps. It's quite 3083 // awkward to turn on otherwise. 3084 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3085 } 3086 // Run the app in safe mode if its manifest requests so or the 3087 // system is booted in safe mode. 3088 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3089 mSafeMode == true) { 3090 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3091 } 3092 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3093 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3094 } 3095 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3096 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3097 } 3098 if ("1".equals(SystemProperties.get("debug.assert"))) { 3099 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3100 } 3101 3102 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3103 if (requiredAbi == null) { 3104 requiredAbi = Build.SUPPORTED_ABIS[0]; 3105 } 3106 3107 // Start the process. It will either succeed and return a result containing 3108 // the PID of the new process, or else throw a RuntimeException. 3109 boolean isActivityProcess = (entryPoint == null); 3110 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3111 Process.ProcessStartResult startResult = Process.start(entryPoint, 3112 app.processName, uid, uid, gids, debugFlags, mountExternal, 3113 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3114 3115 if (app.isolated) { 3116 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3117 } 3118 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3119 3120 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3121 UserHandle.getUserId(uid), startResult.pid, uid, 3122 app.processName, hostingType, 3123 hostingNameStr != null ? hostingNameStr : ""); 3124 3125 if (app.persistent) { 3126 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3127 } 3128 3129 StringBuilder buf = mStringBuilder; 3130 buf.setLength(0); 3131 buf.append("Start proc "); 3132 buf.append(app.processName); 3133 if (!isActivityProcess) { 3134 buf.append(" ["); 3135 buf.append(entryPoint); 3136 buf.append("]"); 3137 } 3138 buf.append(" for "); 3139 buf.append(hostingType); 3140 if (hostingNameStr != null) { 3141 buf.append(" "); 3142 buf.append(hostingNameStr); 3143 } 3144 buf.append(": pid="); 3145 buf.append(startResult.pid); 3146 buf.append(" uid="); 3147 buf.append(uid); 3148 buf.append(" gids={"); 3149 if (gids != null) { 3150 for (int gi=0; gi<gids.length; gi++) { 3151 if (gi != 0) buf.append(", "); 3152 buf.append(gids[gi]); 3153 3154 } 3155 } 3156 buf.append("}"); 3157 if (requiredAbi != null) { 3158 buf.append(" abi="); 3159 buf.append(requiredAbi); 3160 } 3161 Slog.i(TAG, buf.toString()); 3162 app.setPid(startResult.pid); 3163 app.usingWrapper = startResult.usingWrapper; 3164 app.removed = false; 3165 app.killedByAm = false; 3166 synchronized (mPidsSelfLocked) { 3167 this.mPidsSelfLocked.put(startResult.pid, app); 3168 if (isActivityProcess) { 3169 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3170 msg.obj = app; 3171 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3172 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3173 } 3174 } 3175 } catch (RuntimeException e) { 3176 // XXX do better error recovery. 3177 app.setPid(0); 3178 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3179 if (app.isolated) { 3180 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3181 } 3182 Slog.e(TAG, "Failure starting process " + app.processName, e); 3183 } 3184 } 3185 3186 void updateUsageStats(ActivityRecord component, boolean resumed) { 3187 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3188 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3189 if (resumed) { 3190 if (mUsageStatsService != null) { 3191 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3192 System.currentTimeMillis(), 3193 UsageEvents.Event.MOVE_TO_FOREGROUND); 3194 } 3195 synchronized (stats) { 3196 stats.noteActivityResumedLocked(component.app.uid); 3197 } 3198 } else { 3199 if (mUsageStatsService != null) { 3200 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3201 System.currentTimeMillis(), 3202 UsageEvents.Event.MOVE_TO_BACKGROUND); 3203 } 3204 synchronized (stats) { 3205 stats.noteActivityPausedLocked(component.app.uid); 3206 } 3207 } 3208 } 3209 3210 Intent getHomeIntent() { 3211 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3212 intent.setComponent(mTopComponent); 3213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3214 intent.addCategory(Intent.CATEGORY_HOME); 3215 } 3216 return intent; 3217 } 3218 3219 boolean startHomeActivityLocked(int userId) { 3220 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3221 && mTopAction == null) { 3222 // We are running in factory test mode, but unable to find 3223 // the factory test app, so just sit around displaying the 3224 // error message and don't try to start anything. 3225 return false; 3226 } 3227 Intent intent = getHomeIntent(); 3228 ActivityInfo aInfo = 3229 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3230 if (aInfo != null) { 3231 intent.setComponent(new ComponentName( 3232 aInfo.applicationInfo.packageName, aInfo.name)); 3233 // Don't do this if the home app is currently being 3234 // instrumented. 3235 aInfo = new ActivityInfo(aInfo); 3236 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3237 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3238 aInfo.applicationInfo.uid, true); 3239 if (app == null || app.instrumentationClass == null) { 3240 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3241 mStackSupervisor.startHomeActivity(intent, aInfo); 3242 } 3243 } 3244 3245 return true; 3246 } 3247 3248 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3249 ActivityInfo ai = null; 3250 ComponentName comp = intent.getComponent(); 3251 try { 3252 if (comp != null) { 3253 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3254 } else { 3255 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3256 intent, 3257 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3258 flags, userId); 3259 3260 if (info != null) { 3261 ai = info.activityInfo; 3262 } 3263 } 3264 } catch (RemoteException e) { 3265 // ignore 3266 } 3267 3268 return ai; 3269 } 3270 3271 /** 3272 * Starts the "new version setup screen" if appropriate. 3273 */ 3274 void startSetupActivityLocked() { 3275 // Only do this once per boot. 3276 if (mCheckedForSetup) { 3277 return; 3278 } 3279 3280 // We will show this screen if the current one is a different 3281 // version than the last one shown, and we are not running in 3282 // low-level factory test mode. 3283 final ContentResolver resolver = mContext.getContentResolver(); 3284 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3285 Settings.Global.getInt(resolver, 3286 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3287 mCheckedForSetup = true; 3288 3289 // See if we should be showing the platform update setup UI. 3290 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3291 List<ResolveInfo> ris = mContext.getPackageManager() 3292 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3293 3294 // We don't allow third party apps to replace this. 3295 ResolveInfo ri = null; 3296 for (int i=0; ris != null && i<ris.size(); i++) { 3297 if ((ris.get(i).activityInfo.applicationInfo.flags 3298 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3299 ri = ris.get(i); 3300 break; 3301 } 3302 } 3303 3304 if (ri != null) { 3305 String vers = ri.activityInfo.metaData != null 3306 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3307 : null; 3308 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3309 vers = ri.activityInfo.applicationInfo.metaData.getString( 3310 Intent.METADATA_SETUP_VERSION); 3311 } 3312 String lastVers = Settings.Secure.getString( 3313 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3314 if (vers != null && !vers.equals(lastVers)) { 3315 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3316 intent.setComponent(new ComponentName( 3317 ri.activityInfo.packageName, ri.activityInfo.name)); 3318 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3319 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3320 null); 3321 } 3322 } 3323 } 3324 } 3325 3326 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3327 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3328 } 3329 3330 void enforceNotIsolatedCaller(String caller) { 3331 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3332 throw new SecurityException("Isolated process not allowed to call " + caller); 3333 } 3334 } 3335 3336 @Override 3337 public int getFrontActivityScreenCompatMode() { 3338 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3339 synchronized (this) { 3340 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3341 } 3342 } 3343 3344 @Override 3345 public void setFrontActivityScreenCompatMode(int mode) { 3346 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3347 "setFrontActivityScreenCompatMode"); 3348 synchronized (this) { 3349 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3350 } 3351 } 3352 3353 @Override 3354 public int getPackageScreenCompatMode(String packageName) { 3355 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3356 synchronized (this) { 3357 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3358 } 3359 } 3360 3361 @Override 3362 public void setPackageScreenCompatMode(String packageName, int mode) { 3363 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3364 "setPackageScreenCompatMode"); 3365 synchronized (this) { 3366 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3367 } 3368 } 3369 3370 @Override 3371 public boolean getPackageAskScreenCompat(String packageName) { 3372 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3373 synchronized (this) { 3374 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3375 } 3376 } 3377 3378 @Override 3379 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3380 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3381 "setPackageAskScreenCompat"); 3382 synchronized (this) { 3383 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3384 } 3385 } 3386 3387 private void dispatchProcessesChanged() { 3388 int N; 3389 synchronized (this) { 3390 N = mPendingProcessChanges.size(); 3391 if (mActiveProcessChanges.length < N) { 3392 mActiveProcessChanges = new ProcessChangeItem[N]; 3393 } 3394 mPendingProcessChanges.toArray(mActiveProcessChanges); 3395 mAvailProcessChanges.addAll(mPendingProcessChanges); 3396 mPendingProcessChanges.clear(); 3397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3398 } 3399 3400 int i = mProcessObservers.beginBroadcast(); 3401 while (i > 0) { 3402 i--; 3403 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3404 if (observer != null) { 3405 try { 3406 for (int j=0; j<N; j++) { 3407 ProcessChangeItem item = mActiveProcessChanges[j]; 3408 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3409 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3410 + item.pid + " uid=" + item.uid + ": " 3411 + item.foregroundActivities); 3412 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3413 item.foregroundActivities); 3414 } 3415 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3416 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3417 + item.pid + " uid=" + item.uid + ": " + item.processState); 3418 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3419 } 3420 } 3421 } catch (RemoteException e) { 3422 } 3423 } 3424 } 3425 mProcessObservers.finishBroadcast(); 3426 } 3427 3428 private void dispatchProcessDied(int pid, int uid) { 3429 int i = mProcessObservers.beginBroadcast(); 3430 while (i > 0) { 3431 i--; 3432 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3433 if (observer != null) { 3434 try { 3435 observer.onProcessDied(pid, uid); 3436 } catch (RemoteException e) { 3437 } 3438 } 3439 } 3440 mProcessObservers.finishBroadcast(); 3441 } 3442 3443 @Override 3444 public final int startActivity(IApplicationThread caller, String callingPackage, 3445 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3446 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3447 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3448 resultWho, requestCode, startFlags, profilerInfo, options, 3449 UserHandle.getCallingUserId()); 3450 } 3451 3452 @Override 3453 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3454 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3455 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3456 enforceNotIsolatedCaller("startActivity"); 3457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3458 false, ALLOW_FULL_ONLY, "startActivity", null); 3459 // TODO: Switch to user app stacks here. 3460 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3461 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3462 profilerInfo, null, null, options, userId, null, null); 3463 } 3464 3465 @Override 3466 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3467 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3468 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3469 3470 // This is very dangerous -- it allows you to perform a start activity (including 3471 // permission grants) as any app that may launch one of your own activities. So 3472 // we will only allow this to be done from activities that are part of the core framework, 3473 // and then only when they are running as the system. 3474 final ActivityRecord sourceRecord; 3475 final int targetUid; 3476 final String targetPackage; 3477 synchronized (this) { 3478 if (resultTo == null) { 3479 throw new SecurityException("Must be called from an activity"); 3480 } 3481 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3482 if (sourceRecord == null) { 3483 throw new SecurityException("Called with bad activity token: " + resultTo); 3484 } 3485 if (!sourceRecord.info.packageName.equals("android")) { 3486 throw new SecurityException( 3487 "Must be called from an activity that is declared in the android package"); 3488 } 3489 if (sourceRecord.app == null) { 3490 throw new SecurityException("Called without a process attached to activity"); 3491 } 3492 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3493 // This is still okay, as long as this activity is running under the 3494 // uid of the original calling activity. 3495 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3496 throw new SecurityException( 3497 "Calling activity in uid " + sourceRecord.app.uid 3498 + " must be system uid or original calling uid " 3499 + sourceRecord.launchedFromUid); 3500 } 3501 } 3502 targetUid = sourceRecord.launchedFromUid; 3503 targetPackage = sourceRecord.launchedFromPackage; 3504 } 3505 3506 // TODO: Switch to user app stacks here. 3507 try { 3508 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3509 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3510 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3511 return ret; 3512 } catch (SecurityException e) { 3513 // XXX need to figure out how to propagate to original app. 3514 // A SecurityException here is generally actually a fault of the original 3515 // calling activity (such as a fairly granting permissions), so propagate it 3516 // back to them. 3517 /* 3518 StringBuilder msg = new StringBuilder(); 3519 msg.append("While launching"); 3520 msg.append(intent.toString()); 3521 msg.append(": "); 3522 msg.append(e.getMessage()); 3523 */ 3524 throw e; 3525 } 3526 } 3527 3528 @Override 3529 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3530 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3531 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3532 enforceNotIsolatedCaller("startActivityAndWait"); 3533 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3534 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3535 WaitResult res = new WaitResult(); 3536 // TODO: Switch to user app stacks here. 3537 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3538 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3539 options, userId, null, null); 3540 return res; 3541 } 3542 3543 @Override 3544 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3545 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3546 int startFlags, Configuration config, Bundle options, int userId) { 3547 enforceNotIsolatedCaller("startActivityWithConfig"); 3548 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3549 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3550 // TODO: Switch to user app stacks here. 3551 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3552 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3553 null, null, config, options, userId, null, null); 3554 return ret; 3555 } 3556 3557 @Override 3558 public int startActivityIntentSender(IApplicationThread caller, 3559 IntentSender intent, Intent fillInIntent, String resolvedType, 3560 IBinder resultTo, String resultWho, int requestCode, 3561 int flagsMask, int flagsValues, Bundle options) { 3562 enforceNotIsolatedCaller("startActivityIntentSender"); 3563 // Refuse possible leaked file descriptors 3564 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3565 throw new IllegalArgumentException("File descriptors passed in Intent"); 3566 } 3567 3568 IIntentSender sender = intent.getTarget(); 3569 if (!(sender instanceof PendingIntentRecord)) { 3570 throw new IllegalArgumentException("Bad PendingIntent object"); 3571 } 3572 3573 PendingIntentRecord pir = (PendingIntentRecord)sender; 3574 3575 synchronized (this) { 3576 // If this is coming from the currently resumed activity, it is 3577 // effectively saying that app switches are allowed at this point. 3578 final ActivityStack stack = getFocusedStack(); 3579 if (stack.mResumedActivity != null && 3580 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3581 mAppSwitchesAllowedTime = 0; 3582 } 3583 } 3584 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3585 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3586 return ret; 3587 } 3588 3589 @Override 3590 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3591 Intent intent, String resolvedType, IVoiceInteractionSession session, 3592 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3593 Bundle options, int userId) { 3594 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3595 != PackageManager.PERMISSION_GRANTED) { 3596 String msg = "Permission Denial: startVoiceActivity() from pid=" 3597 + Binder.getCallingPid() 3598 + ", uid=" + Binder.getCallingUid() 3599 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3600 Slog.w(TAG, msg); 3601 throw new SecurityException(msg); 3602 } 3603 if (session == null || interactor == null) { 3604 throw new NullPointerException("null session or interactor"); 3605 } 3606 userId = handleIncomingUser(callingPid, callingUid, userId, 3607 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3608 // TODO: Switch to user app stacks here. 3609 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3610 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3611 null, options, userId, null, null); 3612 } 3613 3614 @Override 3615 public boolean startNextMatchingActivity(IBinder callingActivity, 3616 Intent intent, Bundle options) { 3617 // Refuse possible leaked file descriptors 3618 if (intent != null && intent.hasFileDescriptors() == true) { 3619 throw new IllegalArgumentException("File descriptors passed in Intent"); 3620 } 3621 3622 synchronized (this) { 3623 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3624 if (r == null) { 3625 ActivityOptions.abort(options); 3626 return false; 3627 } 3628 if (r.app == null || r.app.thread == null) { 3629 // The caller is not running... d'oh! 3630 ActivityOptions.abort(options); 3631 return false; 3632 } 3633 intent = new Intent(intent); 3634 // The caller is not allowed to change the data. 3635 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3636 // And we are resetting to find the next component... 3637 intent.setComponent(null); 3638 3639 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3640 3641 ActivityInfo aInfo = null; 3642 try { 3643 List<ResolveInfo> resolves = 3644 AppGlobals.getPackageManager().queryIntentActivities( 3645 intent, r.resolvedType, 3646 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3647 UserHandle.getCallingUserId()); 3648 3649 // Look for the original activity in the list... 3650 final int N = resolves != null ? resolves.size() : 0; 3651 for (int i=0; i<N; i++) { 3652 ResolveInfo rInfo = resolves.get(i); 3653 if (rInfo.activityInfo.packageName.equals(r.packageName) 3654 && rInfo.activityInfo.name.equals(r.info.name)) { 3655 // We found the current one... the next matching is 3656 // after it. 3657 i++; 3658 if (i<N) { 3659 aInfo = resolves.get(i).activityInfo; 3660 } 3661 if (debug) { 3662 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3663 + "/" + r.info.name); 3664 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3665 + "/" + aInfo.name); 3666 } 3667 break; 3668 } 3669 } 3670 } catch (RemoteException e) { 3671 } 3672 3673 if (aInfo == null) { 3674 // Nobody who is next! 3675 ActivityOptions.abort(options); 3676 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3677 return false; 3678 } 3679 3680 intent.setComponent(new ComponentName( 3681 aInfo.applicationInfo.packageName, aInfo.name)); 3682 intent.setFlags(intent.getFlags()&~( 3683 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3684 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3685 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3686 Intent.FLAG_ACTIVITY_NEW_TASK)); 3687 3688 // Okay now we need to start the new activity, replacing the 3689 // currently running activity. This is a little tricky because 3690 // we want to start the new one as if the current one is finished, 3691 // but not finish the current one first so that there is no flicker. 3692 // And thus... 3693 final boolean wasFinishing = r.finishing; 3694 r.finishing = true; 3695 3696 // Propagate reply information over to the new activity. 3697 final ActivityRecord resultTo = r.resultTo; 3698 final String resultWho = r.resultWho; 3699 final int requestCode = r.requestCode; 3700 r.resultTo = null; 3701 if (resultTo != null) { 3702 resultTo.removeResultsLocked(r, resultWho, requestCode); 3703 } 3704 3705 final long origId = Binder.clearCallingIdentity(); 3706 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3707 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3708 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3709 options, false, null, null, null); 3710 Binder.restoreCallingIdentity(origId); 3711 3712 r.finishing = wasFinishing; 3713 if (res != ActivityManager.START_SUCCESS) { 3714 return false; 3715 } 3716 return true; 3717 } 3718 } 3719 3720 @Override 3721 public final int startActivityFromRecents(int taskId, Bundle options) { 3722 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3723 String msg = "Permission Denial: startActivityFromRecents called without " + 3724 START_TASKS_FROM_RECENTS; 3725 Slog.w(TAG, msg); 3726 throw new SecurityException(msg); 3727 } 3728 return startActivityFromRecentsInner(taskId, options); 3729 } 3730 3731 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3732 final TaskRecord task; 3733 final int callingUid; 3734 final String callingPackage; 3735 final Intent intent; 3736 final int userId; 3737 synchronized (this) { 3738 task = recentTaskForIdLocked(taskId); 3739 if (task == null) { 3740 throw new IllegalArgumentException("Task " + taskId + " not found."); 3741 } 3742 callingUid = task.mCallingUid; 3743 callingPackage = task.mCallingPackage; 3744 intent = task.intent; 3745 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3746 userId = task.userId; 3747 } 3748 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3749 options, userId, null, task); 3750 } 3751 3752 final int startActivityInPackage(int uid, String callingPackage, 3753 Intent intent, String resolvedType, IBinder resultTo, 3754 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3755 IActivityContainer container, TaskRecord inTask) { 3756 3757 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3758 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3759 3760 // TODO: Switch to user app stacks here. 3761 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3762 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3763 null, null, null, options, userId, container, inTask); 3764 return ret; 3765 } 3766 3767 @Override 3768 public final int startActivities(IApplicationThread caller, String callingPackage, 3769 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3770 int userId) { 3771 enforceNotIsolatedCaller("startActivities"); 3772 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3773 false, ALLOW_FULL_ONLY, "startActivity", null); 3774 // TODO: Switch to user app stacks here. 3775 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3776 resolvedTypes, resultTo, options, userId); 3777 return ret; 3778 } 3779 3780 final int startActivitiesInPackage(int uid, String callingPackage, 3781 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3782 Bundle options, int userId) { 3783 3784 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3785 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3786 // TODO: Switch to user app stacks here. 3787 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3788 resultTo, options, userId); 3789 return ret; 3790 } 3791 3792 //explicitly remove thd old information in mRecentTasks when removing existing user. 3793 private void removeRecentTasksForUserLocked(int userId) { 3794 if(userId <= 0) { 3795 Slog.i(TAG, "Can't remove recent task on user " + userId); 3796 return; 3797 } 3798 3799 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3800 TaskRecord tr = mRecentTasks.get(i); 3801 if (tr.userId == userId) { 3802 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3803 + " when finishing user" + userId); 3804 mRecentTasks.remove(i); 3805 tr.removedFromRecents(mTaskPersister); 3806 } 3807 } 3808 3809 // Remove tasks from persistent storage. 3810 mTaskPersister.wakeup(null, true); 3811 } 3812 3813 /** 3814 * Update the recent tasks lists: make sure tasks should still be here (their 3815 * applications / activities still exist), update their availability, fixup ordering 3816 * of affiliations. 3817 */ 3818 void cleanupRecentTasksLocked(int userId) { 3819 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3820 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3821 final IPackageManager pm = AppGlobals.getPackageManager(); 3822 final ActivityInfo dummyAct = new ActivityInfo(); 3823 final ApplicationInfo dummyApp = new ApplicationInfo(); 3824 3825 int N = mRecentTasks.size(); 3826 3827 int[] users = userId == UserHandle.USER_ALL 3828 ? getUsersLocked() : new int[] { userId }; 3829 for (int user : users) { 3830 for (int i = 0; i < N; i++) { 3831 TaskRecord task = mRecentTasks.get(i); 3832 if (task.userId != user) { 3833 // Only look at tasks for the user ID of interest. 3834 continue; 3835 } 3836 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3837 // This situation is broken, and we should just get rid of it now. 3838 mRecentTasks.remove(i); 3839 task.removedFromRecents(mTaskPersister); 3840 i--; 3841 N--; 3842 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3843 continue; 3844 } 3845 // Check whether this activity is currently available. 3846 if (task.realActivity != null) { 3847 ActivityInfo ai = availActCache.get(task.realActivity); 3848 if (ai == null) { 3849 try { 3850 ai = pm.getActivityInfo(task.realActivity, 3851 PackageManager.GET_UNINSTALLED_PACKAGES 3852 | PackageManager.GET_DISABLED_COMPONENTS, user); 3853 } catch (RemoteException e) { 3854 // Will never happen. 3855 continue; 3856 } 3857 if (ai == null) { 3858 ai = dummyAct; 3859 } 3860 availActCache.put(task.realActivity, ai); 3861 } 3862 if (ai == dummyAct) { 3863 // This could be either because the activity no longer exists, or the 3864 // app is temporarily gone. For the former we want to remove the recents 3865 // entry; for the latter we want to mark it as unavailable. 3866 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3867 if (app == null) { 3868 try { 3869 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3870 PackageManager.GET_UNINSTALLED_PACKAGES 3871 | PackageManager.GET_DISABLED_COMPONENTS, user); 3872 } catch (RemoteException e) { 3873 // Will never happen. 3874 continue; 3875 } 3876 if (app == null) { 3877 app = dummyApp; 3878 } 3879 availAppCache.put(task.realActivity.getPackageName(), app); 3880 } 3881 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3882 // Doesn't exist any more! Good-bye. 3883 mRecentTasks.remove(i); 3884 task.removedFromRecents(mTaskPersister); 3885 i--; 3886 N--; 3887 Slog.w(TAG, "Removing no longer valid recent: " + task); 3888 continue; 3889 } else { 3890 // Otherwise just not available for now. 3891 if (task.isAvailable) { 3892 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3893 + task); 3894 } 3895 task.isAvailable = false; 3896 } 3897 } else { 3898 if (!ai.enabled || !ai.applicationInfo.enabled 3899 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3900 if (task.isAvailable) { 3901 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3902 + task + " (enabled=" + ai.enabled + "/" 3903 + ai.applicationInfo.enabled + " flags=" 3904 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3905 } 3906 task.isAvailable = false; 3907 } else { 3908 if (!task.isAvailable) { 3909 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3910 + task); 3911 } 3912 task.isAvailable = true; 3913 } 3914 } 3915 } 3916 } 3917 } 3918 3919 // Verify the affiliate chain for each task. 3920 for (int i = 0; i < N; ) { 3921 TaskRecord task = mRecentTasks.remove(i); 3922 if (mTmpRecents.contains(task)) { 3923 continue; 3924 } 3925 int affiliatedTaskId = task.mAffiliatedTaskId; 3926 while (true) { 3927 TaskRecord next = task.mNextAffiliate; 3928 if (next == null) { 3929 break; 3930 } 3931 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3932 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3933 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3934 task.setNextAffiliate(null); 3935 if (next.mPrevAffiliate == task) { 3936 next.setPrevAffiliate(null); 3937 } 3938 break; 3939 } 3940 if (next.mPrevAffiliate != task) { 3941 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3942 next.mPrevAffiliate + " task=" + task); 3943 next.setPrevAffiliate(null); 3944 task.setNextAffiliate(null); 3945 break; 3946 } 3947 if (!mRecentTasks.contains(next)) { 3948 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3949 task.setNextAffiliate(null); 3950 // We know that next.mPrevAffiliate is always task, from above, so clear 3951 // its previous affiliate. 3952 next.setPrevAffiliate(null); 3953 break; 3954 } 3955 task = next; 3956 } 3957 // task is now the end of the list 3958 do { 3959 mRecentTasks.remove(task); 3960 mRecentTasks.add(i++, task); 3961 mTmpRecents.add(task); 3962 task.inRecents = true; 3963 } while ((task = task.mPrevAffiliate) != null); 3964 } 3965 mTmpRecents.clear(); 3966 // mRecentTasks is now in sorted, affiliated order. 3967 } 3968 3969 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3970 int N = mRecentTasks.size(); 3971 TaskRecord top = task; 3972 int topIndex = taskIndex; 3973 while (top.mNextAffiliate != null && topIndex > 0) { 3974 top = top.mNextAffiliate; 3975 topIndex--; 3976 } 3977 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3978 + topIndex + " from intial " + taskIndex); 3979 // Find the end of the chain, doing a sanity check along the way. 3980 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3981 int endIndex = topIndex; 3982 TaskRecord prev = top; 3983 while (endIndex < N) { 3984 TaskRecord cur = mRecentTasks.get(endIndex); 3985 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3986 + endIndex + " " + cur); 3987 if (cur == top) { 3988 // Verify start of the chain. 3989 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3990 Slog.wtf(TAG, "Bad chain @" + endIndex 3991 + ": first task has next affiliate: " + prev); 3992 sane = false; 3993 break; 3994 } 3995 } else { 3996 // Verify middle of the chain's next points back to the one before. 3997 if (cur.mNextAffiliate != prev 3998 || cur.mNextAffiliateTaskId != prev.taskId) { 3999 Slog.wtf(TAG, "Bad chain @" + endIndex 4000 + ": middle task " + cur + " @" + endIndex 4001 + " has bad next affiliate " 4002 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4003 + ", expected " + prev); 4004 sane = false; 4005 break; 4006 } 4007 } 4008 if (cur.mPrevAffiliateTaskId == -1) { 4009 // Chain ends here. 4010 if (cur.mPrevAffiliate != null) { 4011 Slog.wtf(TAG, "Bad chain @" + endIndex 4012 + ": last task " + cur + " has previous affiliate " 4013 + cur.mPrevAffiliate); 4014 sane = false; 4015 } 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4017 break; 4018 } else { 4019 // Verify middle of the chain's prev points to a valid item. 4020 if (cur.mPrevAffiliate == null) { 4021 Slog.wtf(TAG, "Bad chain @" + endIndex 4022 + ": task " + cur + " has previous affiliate " 4023 + cur.mPrevAffiliate + " but should be id " 4024 + cur.mPrevAffiliate); 4025 sane = false; 4026 break; 4027 } 4028 } 4029 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4030 Slog.wtf(TAG, "Bad chain @" + endIndex 4031 + ": task " + cur + " has affiliated id " 4032 + cur.mAffiliatedTaskId + " but should be " 4033 + task.mAffiliatedTaskId); 4034 sane = false; 4035 break; 4036 } 4037 prev = cur; 4038 endIndex++; 4039 if (endIndex >= N) { 4040 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4041 + ": last task " + prev); 4042 sane = false; 4043 break; 4044 } 4045 } 4046 if (sane) { 4047 if (endIndex < taskIndex) { 4048 Slog.wtf(TAG, "Bad chain @" + endIndex 4049 + ": did not extend to task " + task + " @" + taskIndex); 4050 sane = false; 4051 } 4052 } 4053 if (sane) { 4054 // All looks good, we can just move all of the affiliated tasks 4055 // to the top. 4056 for (int i=topIndex; i<=endIndex; i++) { 4057 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4058 + " from " + i + " to " + (i-topIndex)); 4059 TaskRecord cur = mRecentTasks.remove(i); 4060 mRecentTasks.add(i-topIndex, cur); 4061 } 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4063 + " to " + endIndex); 4064 return true; 4065 } 4066 4067 // Whoops, couldn't do it. 4068 return false; 4069 } 4070 4071 final void addRecentTaskLocked(TaskRecord task) { 4072 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4073 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4074 4075 int N = mRecentTasks.size(); 4076 // Quick case: check if the top-most recent task is the same. 4077 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4078 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4079 return; 4080 } 4081 // Another quick case: check if this is part of a set of affiliated 4082 // tasks that are at the top. 4083 if (isAffiliated && N > 0 && task.inRecents 4084 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4086 + " at top when adding " + task); 4087 return; 4088 } 4089 // Another quick case: never add voice sessions. 4090 if (task.voiceSession != null) { 4091 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4092 return; 4093 } 4094 4095 boolean needAffiliationFix = false; 4096 4097 // Slightly less quick case: the task is already in recents, so all we need 4098 // to do is move it. 4099 if (task.inRecents) { 4100 int taskIndex = mRecentTasks.indexOf(task); 4101 if (taskIndex >= 0) { 4102 if (!isAffiliated) { 4103 // Simple case: this is not an affiliated task, so we just move it to the front. 4104 mRecentTasks.remove(taskIndex); 4105 mRecentTasks.add(0, task); 4106 notifyTaskPersisterLocked(task, false); 4107 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4108 + " from " + taskIndex); 4109 return; 4110 } else { 4111 // More complicated: need to keep all affiliated tasks together. 4112 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4113 // All went well. 4114 return; 4115 } 4116 4117 // Uh oh... something bad in the affiliation chain, try to rebuild 4118 // everything and then go through our general path of adding a new task. 4119 needAffiliationFix = true; 4120 } 4121 } else { 4122 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4123 needAffiliationFix = true; 4124 } 4125 } 4126 4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4128 trimRecentsForTask(task, true); 4129 4130 N = mRecentTasks.size(); 4131 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4132 final TaskRecord tr = mRecentTasks.remove(N - 1); 4133 tr.removedFromRecents(mTaskPersister); 4134 N--; 4135 } 4136 task.inRecents = true; 4137 if (!isAffiliated || needAffiliationFix) { 4138 // If this is a simple non-affiliated task, or we had some failure trying to 4139 // handle it as part of an affilated task, then just place it at the top. 4140 mRecentTasks.add(0, task); 4141 } else if (isAffiliated) { 4142 // If this is a new affiliated task, then move all of the affiliated tasks 4143 // to the front and insert this new one. 4144 TaskRecord other = task.mNextAffiliate; 4145 if (other == null) { 4146 other = task.mPrevAffiliate; 4147 } 4148 if (other != null) { 4149 int otherIndex = mRecentTasks.indexOf(other); 4150 if (otherIndex >= 0) { 4151 // Insert new task at appropriate location. 4152 int taskIndex; 4153 if (other == task.mNextAffiliate) { 4154 // We found the index of our next affiliation, which is who is 4155 // before us in the list, so add after that point. 4156 taskIndex = otherIndex+1; 4157 } else { 4158 // We found the index of our previous affiliation, which is who is 4159 // after us in the list, so add at their position. 4160 taskIndex = otherIndex; 4161 } 4162 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4163 + taskIndex + ": " + task); 4164 mRecentTasks.add(taskIndex, task); 4165 4166 // Now move everything to the front. 4167 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4168 // All went well. 4169 return; 4170 } 4171 4172 // Uh oh... something bad in the affiliation chain, try to rebuild 4173 // everything and then go through our general path of adding a new task. 4174 needAffiliationFix = true; 4175 } else { 4176 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4177 + other); 4178 needAffiliationFix = true; 4179 } 4180 } else { 4181 if (DEBUG_RECENTS) Slog.d(TAG, 4182 "addRecent: adding affiliated task without next/prev:" + task); 4183 needAffiliationFix = true; 4184 } 4185 } 4186 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4187 4188 if (needAffiliationFix) { 4189 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4190 cleanupRecentTasksLocked(task.userId); 4191 } 4192 } 4193 4194 /** 4195 * If needed, remove oldest existing entries in recents that are for the same kind 4196 * of task as the given one. 4197 */ 4198 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4199 int N = mRecentTasks.size(); 4200 final Intent intent = task.intent; 4201 final boolean document = intent != null && intent.isDocument(); 4202 4203 int maxRecents = task.maxRecents - 1; 4204 for (int i=0; i<N; i++) { 4205 final TaskRecord tr = mRecentTasks.get(i); 4206 if (task != tr) { 4207 if (task.userId != tr.userId) { 4208 continue; 4209 } 4210 if (i > MAX_RECENT_BITMAPS) { 4211 tr.freeLastThumbnail(); 4212 } 4213 final Intent trIntent = tr.intent; 4214 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4215 (intent == null || !intent.filterEquals(trIntent))) { 4216 continue; 4217 } 4218 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4219 if (document && trIsDocument) { 4220 // These are the same document activity (not necessarily the same doc). 4221 if (maxRecents > 0) { 4222 --maxRecents; 4223 continue; 4224 } 4225 // Hit the maximum number of documents for this task. Fall through 4226 // and remove this document from recents. 4227 } else if (document || trIsDocument) { 4228 // Only one of these is a document. Not the droid we're looking for. 4229 continue; 4230 } 4231 } 4232 4233 if (!doTrim) { 4234 // If the caller is not actually asking for a trim, just tell them we reached 4235 // a point where the trim would happen. 4236 return i; 4237 } 4238 4239 // Either task and tr are the same or, their affinities match or their intents match 4240 // and neither of them is a document, or they are documents using the same activity 4241 // and their maxRecents has been reached. 4242 tr.disposeThumbnail(); 4243 mRecentTasks.remove(i); 4244 if (task != tr) { 4245 tr.removedFromRecents(mTaskPersister); 4246 } 4247 i--; 4248 N--; 4249 if (task.intent == null) { 4250 // If the new recent task we are adding is not fully 4251 // specified, then replace it with the existing recent task. 4252 task = tr; 4253 } 4254 notifyTaskPersisterLocked(tr, false); 4255 } 4256 4257 return -1; 4258 } 4259 4260 @Override 4261 public void reportActivityFullyDrawn(IBinder token) { 4262 synchronized (this) { 4263 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4264 if (r == null) { 4265 return; 4266 } 4267 r.reportFullyDrawnLocked(); 4268 } 4269 } 4270 4271 @Override 4272 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4273 synchronized (this) { 4274 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4275 if (r == null) { 4276 return; 4277 } 4278 final long origId = Binder.clearCallingIdentity(); 4279 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4280 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4281 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4282 if (config != null) { 4283 r.frozenBeforeDestroy = true; 4284 if (!updateConfigurationLocked(config, r, false, false)) { 4285 mStackSupervisor.resumeTopActivitiesLocked(); 4286 } 4287 } 4288 Binder.restoreCallingIdentity(origId); 4289 } 4290 } 4291 4292 @Override 4293 public int getRequestedOrientation(IBinder token) { 4294 synchronized (this) { 4295 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4296 if (r == null) { 4297 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4298 } 4299 return mWindowManager.getAppOrientation(r.appToken); 4300 } 4301 } 4302 4303 /** 4304 * This is the internal entry point for handling Activity.finish(). 4305 * 4306 * @param token The Binder token referencing the Activity we want to finish. 4307 * @param resultCode Result code, if any, from this Activity. 4308 * @param resultData Result data (Intent), if any, from this Activity. 4309 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4310 * the root Activity in the task. 4311 * 4312 * @return Returns true if the activity successfully finished, or false if it is still running. 4313 */ 4314 @Override 4315 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4316 boolean finishTask) { 4317 // Refuse possible leaked file descriptors 4318 if (resultData != null && resultData.hasFileDescriptors() == true) { 4319 throw new IllegalArgumentException("File descriptors passed in Intent"); 4320 } 4321 4322 synchronized(this) { 4323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4324 if (r == null) { 4325 return true; 4326 } 4327 // Keep track of the root activity of the task before we finish it 4328 TaskRecord tr = r.task; 4329 ActivityRecord rootR = tr.getRootActivity(); 4330 // Do not allow task to finish in Lock Task mode. 4331 if (tr == mStackSupervisor.mLockTaskModeTask) { 4332 if (rootR == r) { 4333 mStackSupervisor.showLockTaskToast(); 4334 return false; 4335 } 4336 } 4337 if (mController != null) { 4338 // Find the first activity that is not finishing. 4339 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4340 if (next != null) { 4341 // ask watcher if this is allowed 4342 boolean resumeOK = true; 4343 try { 4344 resumeOK = mController.activityResuming(next.packageName); 4345 } catch (RemoteException e) { 4346 mController = null; 4347 Watchdog.getInstance().setActivityController(null); 4348 } 4349 4350 if (!resumeOK) { 4351 return false; 4352 } 4353 } 4354 } 4355 final long origId = Binder.clearCallingIdentity(); 4356 try { 4357 boolean res; 4358 if (finishTask && r == rootR) { 4359 // If requested, remove the task that is associated to this activity only if it 4360 // was the root activity in the task. The result code and data is ignored because 4361 // we don't support returning them across task boundaries. 4362 res = removeTaskByIdLocked(tr.taskId, 0); 4363 } else { 4364 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4365 resultData, "app-request", true); 4366 } 4367 return res; 4368 } finally { 4369 Binder.restoreCallingIdentity(origId); 4370 } 4371 } 4372 } 4373 4374 @Override 4375 public final void finishHeavyWeightApp() { 4376 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4377 != PackageManager.PERMISSION_GRANTED) { 4378 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4379 + Binder.getCallingPid() 4380 + ", uid=" + Binder.getCallingUid() 4381 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4382 Slog.w(TAG, msg); 4383 throw new SecurityException(msg); 4384 } 4385 4386 synchronized(this) { 4387 if (mHeavyWeightProcess == null) { 4388 return; 4389 } 4390 4391 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4392 mHeavyWeightProcess.activities); 4393 for (int i=0; i<activities.size(); i++) { 4394 ActivityRecord r = activities.get(i); 4395 if (!r.finishing) { 4396 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4397 null, "finish-heavy", true); 4398 } 4399 } 4400 4401 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4402 mHeavyWeightProcess.userId, 0)); 4403 mHeavyWeightProcess = null; 4404 } 4405 } 4406 4407 @Override 4408 public void crashApplication(int uid, int initialPid, String packageName, 4409 String message) { 4410 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4411 != PackageManager.PERMISSION_GRANTED) { 4412 String msg = "Permission Denial: crashApplication() from pid=" 4413 + Binder.getCallingPid() 4414 + ", uid=" + Binder.getCallingUid() 4415 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4416 Slog.w(TAG, msg); 4417 throw new SecurityException(msg); 4418 } 4419 4420 synchronized(this) { 4421 ProcessRecord proc = null; 4422 4423 // Figure out which process to kill. We don't trust that initialPid 4424 // still has any relation to current pids, so must scan through the 4425 // list. 4426 synchronized (mPidsSelfLocked) { 4427 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4428 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4429 if (p.uid != uid) { 4430 continue; 4431 } 4432 if (p.pid == initialPid) { 4433 proc = p; 4434 break; 4435 } 4436 if (p.pkgList.containsKey(packageName)) { 4437 proc = p; 4438 } 4439 } 4440 } 4441 4442 if (proc == null) { 4443 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4444 + " initialPid=" + initialPid 4445 + " packageName=" + packageName); 4446 return; 4447 } 4448 4449 if (proc.thread != null) { 4450 if (proc.pid == Process.myPid()) { 4451 Log.w(TAG, "crashApplication: trying to crash self!"); 4452 return; 4453 } 4454 long ident = Binder.clearCallingIdentity(); 4455 try { 4456 proc.thread.scheduleCrash(message); 4457 } catch (RemoteException e) { 4458 } 4459 Binder.restoreCallingIdentity(ident); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public final void finishSubActivity(IBinder token, String resultWho, 4466 int requestCode) { 4467 synchronized(this) { 4468 final long origId = Binder.clearCallingIdentity(); 4469 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4470 if (r != null) { 4471 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4472 } 4473 Binder.restoreCallingIdentity(origId); 4474 } 4475 } 4476 4477 @Override 4478 public boolean finishActivityAffinity(IBinder token) { 4479 synchronized(this) { 4480 final long origId = Binder.clearCallingIdentity(); 4481 try { 4482 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4483 4484 ActivityRecord rootR = r.task.getRootActivity(); 4485 // Do not allow task to finish in Lock Task mode. 4486 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4487 if (rootR == r) { 4488 mStackSupervisor.showLockTaskToast(); 4489 return false; 4490 } 4491 } 4492 boolean res = false; 4493 if (r != null) { 4494 res = r.task.stack.finishActivityAffinityLocked(r); 4495 } 4496 return res; 4497 } finally { 4498 Binder.restoreCallingIdentity(origId); 4499 } 4500 } 4501 } 4502 4503 @Override 4504 public void finishVoiceTask(IVoiceInteractionSession session) { 4505 synchronized(this) { 4506 final long origId = Binder.clearCallingIdentity(); 4507 try { 4508 mStackSupervisor.finishVoiceTask(session); 4509 } finally { 4510 Binder.restoreCallingIdentity(origId); 4511 } 4512 } 4513 4514 } 4515 4516 @Override 4517 public boolean releaseActivityInstance(IBinder token) { 4518 synchronized(this) { 4519 final long origId = Binder.clearCallingIdentity(); 4520 try { 4521 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4522 if (r.task == null || r.task.stack == null) { 4523 return false; 4524 } 4525 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4526 } finally { 4527 Binder.restoreCallingIdentity(origId); 4528 } 4529 } 4530 } 4531 4532 @Override 4533 public void releaseSomeActivities(IApplicationThread appInt) { 4534 synchronized(this) { 4535 final long origId = Binder.clearCallingIdentity(); 4536 try { 4537 ProcessRecord app = getRecordForAppLocked(appInt); 4538 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4539 } finally { 4540 Binder.restoreCallingIdentity(origId); 4541 } 4542 } 4543 } 4544 4545 @Override 4546 public boolean willActivityBeVisible(IBinder token) { 4547 synchronized(this) { 4548 ActivityStack stack = ActivityRecord.getStackLocked(token); 4549 if (stack != null) { 4550 return stack.willActivityBeVisibleLocked(token); 4551 } 4552 return false; 4553 } 4554 } 4555 4556 @Override 4557 public void overridePendingTransition(IBinder token, String packageName, 4558 int enterAnim, int exitAnim) { 4559 synchronized(this) { 4560 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4561 if (self == null) { 4562 return; 4563 } 4564 4565 final long origId = Binder.clearCallingIdentity(); 4566 4567 if (self.state == ActivityState.RESUMED 4568 || self.state == ActivityState.PAUSING) { 4569 mWindowManager.overridePendingAppTransition(packageName, 4570 enterAnim, exitAnim, null); 4571 } 4572 4573 Binder.restoreCallingIdentity(origId); 4574 } 4575 } 4576 4577 /** 4578 * Main function for removing an existing process from the activity manager 4579 * as a result of that process going away. Clears out all connections 4580 * to the process. 4581 */ 4582 private final void handleAppDiedLocked(ProcessRecord app, 4583 boolean restarting, boolean allowRestart) { 4584 int pid = app.pid; 4585 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4586 if (!restarting) { 4587 removeLruProcessLocked(app); 4588 if (pid > 0) { 4589 ProcessList.remove(pid); 4590 } 4591 } 4592 4593 if (mProfileProc == app) { 4594 clearProfilerLocked(); 4595 } 4596 4597 // Remove this application's activities from active lists. 4598 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4599 4600 app.activities.clear(); 4601 4602 if (app.instrumentationClass != null) { 4603 Slog.w(TAG, "Crash of app " + app.processName 4604 + " running instrumentation " + app.instrumentationClass); 4605 Bundle info = new Bundle(); 4606 info.putString("shortMsg", "Process crashed."); 4607 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4608 } 4609 4610 if (!restarting) { 4611 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4612 // If there was nothing to resume, and we are not already 4613 // restarting this process, but there is a visible activity that 4614 // is hosted by the process... then make sure all visible 4615 // activities are running, taking care of restarting this 4616 // process. 4617 if (hasVisibleActivities) { 4618 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4619 } 4620 } 4621 } 4622 } 4623 4624 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4625 IBinder threadBinder = thread.asBinder(); 4626 // Find the application record. 4627 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4628 ProcessRecord rec = mLruProcesses.get(i); 4629 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4630 return i; 4631 } 4632 } 4633 return -1; 4634 } 4635 4636 final ProcessRecord getRecordForAppLocked( 4637 IApplicationThread thread) { 4638 if (thread == null) { 4639 return null; 4640 } 4641 4642 int appIndex = getLRURecordIndexForAppLocked(thread); 4643 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4644 } 4645 4646 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4647 // If there are no longer any background processes running, 4648 // and the app that died was not running instrumentation, 4649 // then tell everyone we are now low on memory. 4650 boolean haveBg = false; 4651 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4652 ProcessRecord rec = mLruProcesses.get(i); 4653 if (rec.thread != null 4654 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4655 haveBg = true; 4656 break; 4657 } 4658 } 4659 4660 if (!haveBg) { 4661 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4662 if (doReport) { 4663 long now = SystemClock.uptimeMillis(); 4664 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4665 doReport = false; 4666 } else { 4667 mLastMemUsageReportTime = now; 4668 } 4669 } 4670 final ArrayList<ProcessMemInfo> memInfos 4671 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4672 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4673 long now = SystemClock.uptimeMillis(); 4674 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4675 ProcessRecord rec = mLruProcesses.get(i); 4676 if (rec == dyingProc || rec.thread == null) { 4677 continue; 4678 } 4679 if (doReport) { 4680 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4681 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4682 } 4683 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4684 // The low memory report is overriding any current 4685 // state for a GC request. Make sure to do 4686 // heavy/important/visible/foreground processes first. 4687 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4688 rec.lastRequestedGc = 0; 4689 } else { 4690 rec.lastRequestedGc = rec.lastLowMemory; 4691 } 4692 rec.reportLowMemory = true; 4693 rec.lastLowMemory = now; 4694 mProcessesToGc.remove(rec); 4695 addProcessToGcListLocked(rec); 4696 } 4697 } 4698 if (doReport) { 4699 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4700 mHandler.sendMessage(msg); 4701 } 4702 scheduleAppGcsLocked(); 4703 } 4704 } 4705 4706 final void appDiedLocked(ProcessRecord app) { 4707 appDiedLocked(app, app.pid, app.thread); 4708 } 4709 4710 final void appDiedLocked(ProcessRecord app, int pid, 4711 IApplicationThread thread) { 4712 4713 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4714 synchronized (stats) { 4715 stats.noteProcessDiedLocked(app.info.uid, pid); 4716 } 4717 4718 Process.killProcessGroup(app.info.uid, pid); 4719 4720 // Clean up already done if the process has been re-started. 4721 if (app.pid == pid && app.thread != null && 4722 app.thread.asBinder() == thread.asBinder()) { 4723 boolean doLowMem = app.instrumentationClass == null; 4724 boolean doOomAdj = doLowMem; 4725 if (!app.killedByAm) { 4726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4727 + ") has died."); 4728 mAllowLowerMemLevel = true; 4729 } else { 4730 // Note that we always want to do oom adj to update our state with the 4731 // new number of procs. 4732 mAllowLowerMemLevel = false; 4733 doLowMem = false; 4734 } 4735 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4736 if (DEBUG_CLEANUP) Slog.v( 4737 TAG, "Dying app: " + app + ", pid: " + pid 4738 + ", thread: " + thread.asBinder()); 4739 handleAppDiedLocked(app, false, true); 4740 4741 if (doOomAdj) { 4742 updateOomAdjLocked(); 4743 } 4744 if (doLowMem) { 4745 doLowMemReportIfNeededLocked(app); 4746 } 4747 } else if (app.pid != pid) { 4748 // A new process has already been started. 4749 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4750 + ") has died and restarted (pid " + app.pid + ")."); 4751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4752 } else if (DEBUG_PROCESSES) { 4753 Slog.d(TAG, "Received spurious death notification for thread " 4754 + thread.asBinder()); 4755 } 4756 } 4757 4758 /** 4759 * If a stack trace dump file is configured, dump process stack traces. 4760 * @param clearTraces causes the dump file to be erased prior to the new 4761 * traces being written, if true; when false, the new traces will be 4762 * appended to any existing file content. 4763 * @param firstPids of dalvik VM processes to dump stack traces for first 4764 * @param lastPids of dalvik VM processes to dump stack traces for last 4765 * @param nativeProcs optional list of native process names to dump stack crawls 4766 * @return file containing stack traces, or null if no dump file is configured 4767 */ 4768 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4769 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4770 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4771 if (tracesPath == null || tracesPath.length() == 0) { 4772 return null; 4773 } 4774 4775 File tracesFile = new File(tracesPath); 4776 try { 4777 File tracesDir = tracesFile.getParentFile(); 4778 if (!tracesDir.exists()) { 4779 tracesFile.mkdirs(); 4780 if (!SELinux.restorecon(tracesDir)) { 4781 return null; 4782 } 4783 } 4784 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4785 4786 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4787 tracesFile.createNewFile(); 4788 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4789 } catch (IOException e) { 4790 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4791 return null; 4792 } 4793 4794 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4795 return tracesFile; 4796 } 4797 4798 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4799 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4800 // Use a FileObserver to detect when traces finish writing. 4801 // The order of traces is considered important to maintain for legibility. 4802 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4803 @Override 4804 public synchronized void onEvent(int event, String path) { notify(); } 4805 }; 4806 4807 try { 4808 observer.startWatching(); 4809 4810 // First collect all of the stacks of the most important pids. 4811 if (firstPids != null) { 4812 try { 4813 int num = firstPids.size(); 4814 for (int i = 0; i < num; i++) { 4815 synchronized (observer) { 4816 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4817 observer.wait(200); // Wait for write-close, give up after 200msec 4818 } 4819 } 4820 } catch (InterruptedException e) { 4821 Log.wtf(TAG, e); 4822 } 4823 } 4824 4825 // Next collect the stacks of the native pids 4826 if (nativeProcs != null) { 4827 int[] pids = Process.getPidsForCommands(nativeProcs); 4828 if (pids != null) { 4829 for (int pid : pids) { 4830 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4831 } 4832 } 4833 } 4834 4835 // Lastly, measure CPU usage. 4836 if (processCpuTracker != null) { 4837 processCpuTracker.init(); 4838 System.gc(); 4839 processCpuTracker.update(); 4840 try { 4841 synchronized (processCpuTracker) { 4842 processCpuTracker.wait(500); // measure over 1/2 second. 4843 } 4844 } catch (InterruptedException e) { 4845 } 4846 processCpuTracker.update(); 4847 4848 // We'll take the stack crawls of just the top apps using CPU. 4849 final int N = processCpuTracker.countWorkingStats(); 4850 int numProcs = 0; 4851 for (int i=0; i<N && numProcs<5; i++) { 4852 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4853 if (lastPids.indexOfKey(stats.pid) >= 0) { 4854 numProcs++; 4855 try { 4856 synchronized (observer) { 4857 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4858 observer.wait(200); // Wait for write-close, give up after 200msec 4859 } 4860 } catch (InterruptedException e) { 4861 Log.wtf(TAG, e); 4862 } 4863 4864 } 4865 } 4866 } 4867 } finally { 4868 observer.stopWatching(); 4869 } 4870 } 4871 4872 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4873 if (true || IS_USER_BUILD) { 4874 return; 4875 } 4876 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4877 if (tracesPath == null || tracesPath.length() == 0) { 4878 return; 4879 } 4880 4881 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4882 StrictMode.allowThreadDiskWrites(); 4883 try { 4884 final File tracesFile = new File(tracesPath); 4885 final File tracesDir = tracesFile.getParentFile(); 4886 final File tracesTmp = new File(tracesDir, "__tmp__"); 4887 try { 4888 if (!tracesDir.exists()) { 4889 tracesFile.mkdirs(); 4890 if (!SELinux.restorecon(tracesDir.getPath())) { 4891 return; 4892 } 4893 } 4894 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4895 4896 if (tracesFile.exists()) { 4897 tracesTmp.delete(); 4898 tracesFile.renameTo(tracesTmp); 4899 } 4900 StringBuilder sb = new StringBuilder(); 4901 Time tobj = new Time(); 4902 tobj.set(System.currentTimeMillis()); 4903 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4904 sb.append(": "); 4905 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4906 sb.append(" since "); 4907 sb.append(msg); 4908 FileOutputStream fos = new FileOutputStream(tracesFile); 4909 fos.write(sb.toString().getBytes()); 4910 if (app == null) { 4911 fos.write("\n*** No application process!".getBytes()); 4912 } 4913 fos.close(); 4914 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4915 } catch (IOException e) { 4916 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4917 return; 4918 } 4919 4920 if (app != null) { 4921 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4922 firstPids.add(app.pid); 4923 dumpStackTraces(tracesPath, firstPids, null, null, null); 4924 } 4925 4926 File lastTracesFile = null; 4927 File curTracesFile = null; 4928 for (int i=9; i>=0; i--) { 4929 String name = String.format(Locale.US, "slow%02d.txt", i); 4930 curTracesFile = new File(tracesDir, name); 4931 if (curTracesFile.exists()) { 4932 if (lastTracesFile != null) { 4933 curTracesFile.renameTo(lastTracesFile); 4934 } else { 4935 curTracesFile.delete(); 4936 } 4937 } 4938 lastTracesFile = curTracesFile; 4939 } 4940 tracesFile.renameTo(curTracesFile); 4941 if (tracesTmp.exists()) { 4942 tracesTmp.renameTo(tracesFile); 4943 } 4944 } finally { 4945 StrictMode.setThreadPolicy(oldPolicy); 4946 } 4947 } 4948 4949 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4950 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4951 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4952 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4953 4954 if (mController != null) { 4955 try { 4956 // 0 == continue, -1 = kill process immediately 4957 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4958 if (res < 0 && app.pid != MY_PID) { 4959 app.kill("anr", true); 4960 } 4961 } catch (RemoteException e) { 4962 mController = null; 4963 Watchdog.getInstance().setActivityController(null); 4964 } 4965 } 4966 4967 long anrTime = SystemClock.uptimeMillis(); 4968 if (MONITOR_CPU_USAGE) { 4969 updateCpuStatsNow(); 4970 } 4971 4972 synchronized (this) { 4973 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4974 if (mShuttingDown) { 4975 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4976 return; 4977 } else if (app.notResponding) { 4978 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4979 return; 4980 } else if (app.crashing) { 4981 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4982 return; 4983 } 4984 4985 // In case we come through here for the same app before completing 4986 // this one, mark as anring now so we will bail out. 4987 app.notResponding = true; 4988 4989 // Log the ANR to the event log. 4990 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4991 app.processName, app.info.flags, annotation); 4992 4993 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4994 firstPids.add(app.pid); 4995 4996 int parentPid = app.pid; 4997 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4998 if (parentPid != app.pid) firstPids.add(parentPid); 4999 5000 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5001 5002 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5003 ProcessRecord r = mLruProcesses.get(i); 5004 if (r != null && r.thread != null) { 5005 int pid = r.pid; 5006 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5007 if (r.persistent) { 5008 firstPids.add(pid); 5009 } else { 5010 lastPids.put(pid, Boolean.TRUE); 5011 } 5012 } 5013 } 5014 } 5015 } 5016 5017 // Log the ANR to the main log. 5018 StringBuilder info = new StringBuilder(); 5019 info.setLength(0); 5020 info.append("ANR in ").append(app.processName); 5021 if (activity != null && activity.shortComponentName != null) { 5022 info.append(" (").append(activity.shortComponentName).append(")"); 5023 } 5024 info.append("\n"); 5025 info.append("PID: ").append(app.pid).append("\n"); 5026 if (annotation != null) { 5027 info.append("Reason: ").append(annotation).append("\n"); 5028 } 5029 if (parent != null && parent != activity) { 5030 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5031 } 5032 5033 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5034 5035 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5036 NATIVE_STACKS_OF_INTEREST); 5037 5038 String cpuInfo = null; 5039 if (MONITOR_CPU_USAGE) { 5040 updateCpuStatsNow(); 5041 synchronized (mProcessCpuThread) { 5042 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5043 } 5044 info.append(processCpuTracker.printCurrentLoad()); 5045 info.append(cpuInfo); 5046 } 5047 5048 info.append(processCpuTracker.printCurrentState(anrTime)); 5049 5050 Slog.e(TAG, info.toString()); 5051 if (tracesFile == null) { 5052 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5053 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5054 } 5055 5056 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5057 cpuInfo, tracesFile, null); 5058 5059 if (mController != null) { 5060 try { 5061 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5062 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5063 if (res != 0) { 5064 if (res < 0 && app.pid != MY_PID) { 5065 app.kill("anr", true); 5066 } else { 5067 synchronized (this) { 5068 mServices.scheduleServiceTimeoutLocked(app); 5069 } 5070 } 5071 return; 5072 } 5073 } catch (RemoteException e) { 5074 mController = null; 5075 Watchdog.getInstance().setActivityController(null); 5076 } 5077 } 5078 5079 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5080 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5081 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5082 5083 synchronized (this) { 5084 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5085 app.kill("bg anr", true); 5086 return; 5087 } 5088 5089 // Set the app's notResponding state, and look up the errorReportReceiver 5090 makeAppNotRespondingLocked(app, 5091 activity != null ? activity.shortComponentName : null, 5092 annotation != null ? "ANR " + annotation : "ANR", 5093 info.toString()); 5094 5095 // Bring up the infamous App Not Responding dialog 5096 Message msg = Message.obtain(); 5097 HashMap<String, Object> map = new HashMap<String, Object>(); 5098 msg.what = SHOW_NOT_RESPONDING_MSG; 5099 msg.obj = map; 5100 msg.arg1 = aboveSystem ? 1 : 0; 5101 map.put("app", app); 5102 if (activity != null) { 5103 map.put("activity", activity); 5104 } 5105 5106 mHandler.sendMessage(msg); 5107 } 5108 } 5109 5110 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5111 if (!mLaunchWarningShown) { 5112 mLaunchWarningShown = true; 5113 mHandler.post(new Runnable() { 5114 @Override 5115 public void run() { 5116 synchronized (ActivityManagerService.this) { 5117 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5118 d.show(); 5119 mHandler.postDelayed(new Runnable() { 5120 @Override 5121 public void run() { 5122 synchronized (ActivityManagerService.this) { 5123 d.dismiss(); 5124 mLaunchWarningShown = false; 5125 } 5126 } 5127 }, 4000); 5128 } 5129 } 5130 }); 5131 } 5132 } 5133 5134 @Override 5135 public boolean clearApplicationUserData(final String packageName, 5136 final IPackageDataObserver observer, int userId) { 5137 enforceNotIsolatedCaller("clearApplicationUserData"); 5138 int uid = Binder.getCallingUid(); 5139 int pid = Binder.getCallingPid(); 5140 userId = handleIncomingUser(pid, uid, 5141 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5142 long callingId = Binder.clearCallingIdentity(); 5143 try { 5144 IPackageManager pm = AppGlobals.getPackageManager(); 5145 int pkgUid = -1; 5146 synchronized(this) { 5147 try { 5148 pkgUid = pm.getPackageUid(packageName, userId); 5149 } catch (RemoteException e) { 5150 } 5151 if (pkgUid == -1) { 5152 Slog.w(TAG, "Invalid packageName: " + packageName); 5153 if (observer != null) { 5154 try { 5155 observer.onRemoveCompleted(packageName, false); 5156 } catch (RemoteException e) { 5157 Slog.i(TAG, "Observer no longer exists."); 5158 } 5159 } 5160 return false; 5161 } 5162 if (uid == pkgUid || checkComponentPermission( 5163 android.Manifest.permission.CLEAR_APP_USER_DATA, 5164 pid, uid, -1, true) 5165 == PackageManager.PERMISSION_GRANTED) { 5166 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5167 } else { 5168 throw new SecurityException("PID " + pid + " does not have permission " 5169 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5170 + " of package " + packageName); 5171 } 5172 5173 // Remove all tasks match the cleared application package and user 5174 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5175 final TaskRecord tr = mRecentTasks.get(i); 5176 final String taskPackageName = 5177 tr.getBaseIntent().getComponent().getPackageName(); 5178 if (tr.userId != userId) continue; 5179 if (!taskPackageName.equals(packageName)) continue; 5180 removeTaskByIdLocked(tr.taskId, 0); 5181 } 5182 } 5183 5184 try { 5185 // Clear application user data 5186 pm.clearApplicationUserData(packageName, observer, userId); 5187 5188 synchronized(this) { 5189 // Remove all permissions granted from/to this package 5190 removeUriPermissionsForPackageLocked(packageName, userId, true); 5191 } 5192 5193 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5194 Uri.fromParts("package", packageName, null)); 5195 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5196 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5197 null, null, 0, null, null, null, false, false, userId); 5198 } catch (RemoteException e) { 5199 } 5200 } finally { 5201 Binder.restoreCallingIdentity(callingId); 5202 } 5203 return true; 5204 } 5205 5206 @Override 5207 public void killBackgroundProcesses(final String packageName, int userId) { 5208 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5209 != PackageManager.PERMISSION_GRANTED && 5210 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5211 != PackageManager.PERMISSION_GRANTED) { 5212 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5213 + Binder.getCallingPid() 5214 + ", uid=" + Binder.getCallingUid() 5215 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5216 Slog.w(TAG, msg); 5217 throw new SecurityException(msg); 5218 } 5219 5220 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5221 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5222 long callingId = Binder.clearCallingIdentity(); 5223 try { 5224 IPackageManager pm = AppGlobals.getPackageManager(); 5225 synchronized(this) { 5226 int appId = -1; 5227 try { 5228 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5229 } catch (RemoteException e) { 5230 } 5231 if (appId == -1) { 5232 Slog.w(TAG, "Invalid packageName: " + packageName); 5233 return; 5234 } 5235 killPackageProcessesLocked(packageName, appId, userId, 5236 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5237 } 5238 } finally { 5239 Binder.restoreCallingIdentity(callingId); 5240 } 5241 } 5242 5243 @Override 5244 public void killAllBackgroundProcesses() { 5245 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5246 != PackageManager.PERMISSION_GRANTED) { 5247 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5248 + Binder.getCallingPid() 5249 + ", uid=" + Binder.getCallingUid() 5250 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5251 Slog.w(TAG, msg); 5252 throw new SecurityException(msg); 5253 } 5254 5255 long callingId = Binder.clearCallingIdentity(); 5256 try { 5257 synchronized(this) { 5258 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5259 final int NP = mProcessNames.getMap().size(); 5260 for (int ip=0; ip<NP; ip++) { 5261 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5262 final int NA = apps.size(); 5263 for (int ia=0; ia<NA; ia++) { 5264 ProcessRecord app = apps.valueAt(ia); 5265 if (app.persistent) { 5266 // we don't kill persistent processes 5267 continue; 5268 } 5269 if (app.removed) { 5270 procs.add(app); 5271 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5272 app.removed = true; 5273 procs.add(app); 5274 } 5275 } 5276 } 5277 5278 int N = procs.size(); 5279 for (int i=0; i<N; i++) { 5280 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5281 } 5282 mAllowLowerMemLevel = true; 5283 updateOomAdjLocked(); 5284 doLowMemReportIfNeededLocked(null); 5285 } 5286 } finally { 5287 Binder.restoreCallingIdentity(callingId); 5288 } 5289 } 5290 5291 @Override 5292 public void forceStopPackage(final String packageName, int userId) { 5293 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5294 != PackageManager.PERMISSION_GRANTED) { 5295 String msg = "Permission Denial: forceStopPackage() from pid=" 5296 + Binder.getCallingPid() 5297 + ", uid=" + Binder.getCallingUid() 5298 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5299 Slog.w(TAG, msg); 5300 throw new SecurityException(msg); 5301 } 5302 final int callingPid = Binder.getCallingPid(); 5303 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5304 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5305 long callingId = Binder.clearCallingIdentity(); 5306 try { 5307 IPackageManager pm = AppGlobals.getPackageManager(); 5308 synchronized(this) { 5309 int[] users = userId == UserHandle.USER_ALL 5310 ? getUsersLocked() : new int[] { userId }; 5311 for (int user : users) { 5312 int pkgUid = -1; 5313 try { 5314 pkgUid = pm.getPackageUid(packageName, user); 5315 } catch (RemoteException e) { 5316 } 5317 if (pkgUid == -1) { 5318 Slog.w(TAG, "Invalid packageName: " + packageName); 5319 continue; 5320 } 5321 try { 5322 pm.setPackageStoppedState(packageName, true, user); 5323 } catch (RemoteException e) { 5324 } catch (IllegalArgumentException e) { 5325 Slog.w(TAG, "Failed trying to unstop package " 5326 + packageName + ": " + e); 5327 } 5328 if (isUserRunningLocked(user, false)) { 5329 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5330 } 5331 } 5332 } 5333 } finally { 5334 Binder.restoreCallingIdentity(callingId); 5335 } 5336 } 5337 5338 @Override 5339 public void addPackageDependency(String packageName) { 5340 synchronized (this) { 5341 int callingPid = Binder.getCallingPid(); 5342 if (callingPid == Process.myPid()) { 5343 // Yeah, um, no. 5344 Slog.w(TAG, "Can't addPackageDependency on system process"); 5345 return; 5346 } 5347 ProcessRecord proc; 5348 synchronized (mPidsSelfLocked) { 5349 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5350 } 5351 if (proc != null) { 5352 if (proc.pkgDeps == null) { 5353 proc.pkgDeps = new ArraySet<String>(1); 5354 } 5355 proc.pkgDeps.add(packageName); 5356 } 5357 } 5358 } 5359 5360 /* 5361 * The pkg name and app id have to be specified. 5362 */ 5363 @Override 5364 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5365 if (pkg == null) { 5366 return; 5367 } 5368 // Make sure the uid is valid. 5369 if (appid < 0) { 5370 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5371 return; 5372 } 5373 int callerUid = Binder.getCallingUid(); 5374 // Only the system server can kill an application 5375 if (callerUid == Process.SYSTEM_UID) { 5376 // Post an aysnc message to kill the application 5377 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5378 msg.arg1 = appid; 5379 msg.arg2 = 0; 5380 Bundle bundle = new Bundle(); 5381 bundle.putString("pkg", pkg); 5382 bundle.putString("reason", reason); 5383 msg.obj = bundle; 5384 mHandler.sendMessage(msg); 5385 } else { 5386 throw new SecurityException(callerUid + " cannot kill pkg: " + 5387 pkg); 5388 } 5389 } 5390 5391 @Override 5392 public void closeSystemDialogs(String reason) { 5393 enforceNotIsolatedCaller("closeSystemDialogs"); 5394 5395 final int pid = Binder.getCallingPid(); 5396 final int uid = Binder.getCallingUid(); 5397 final long origId = Binder.clearCallingIdentity(); 5398 try { 5399 synchronized (this) { 5400 // Only allow this from foreground processes, so that background 5401 // applications can't abuse it to prevent system UI from being shown. 5402 if (uid >= Process.FIRST_APPLICATION_UID) { 5403 ProcessRecord proc; 5404 synchronized (mPidsSelfLocked) { 5405 proc = mPidsSelfLocked.get(pid); 5406 } 5407 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5408 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5409 + " from background process " + proc); 5410 return; 5411 } 5412 } 5413 closeSystemDialogsLocked(reason); 5414 } 5415 } finally { 5416 Binder.restoreCallingIdentity(origId); 5417 } 5418 } 5419 5420 void closeSystemDialogsLocked(String reason) { 5421 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5422 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5423 | Intent.FLAG_RECEIVER_FOREGROUND); 5424 if (reason != null) { 5425 intent.putExtra("reason", reason); 5426 } 5427 mWindowManager.closeSystemDialogs(reason); 5428 5429 mStackSupervisor.closeSystemDialogsLocked(); 5430 5431 broadcastIntentLocked(null, null, intent, null, 5432 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5433 Process.SYSTEM_UID, UserHandle.USER_ALL); 5434 } 5435 5436 @Override 5437 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5438 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5439 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5440 for (int i=pids.length-1; i>=0; i--) { 5441 ProcessRecord proc; 5442 int oomAdj; 5443 synchronized (this) { 5444 synchronized (mPidsSelfLocked) { 5445 proc = mPidsSelfLocked.get(pids[i]); 5446 oomAdj = proc != null ? proc.setAdj : 0; 5447 } 5448 } 5449 infos[i] = new Debug.MemoryInfo(); 5450 Debug.getMemoryInfo(pids[i], infos[i]); 5451 if (proc != null) { 5452 synchronized (this) { 5453 if (proc.thread != null && proc.setAdj == oomAdj) { 5454 // Record this for posterity if the process has been stable. 5455 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5456 infos[i].getTotalUss(), false, proc.pkgList); 5457 } 5458 } 5459 } 5460 } 5461 return infos; 5462 } 5463 5464 @Override 5465 public long[] getProcessPss(int[] pids) { 5466 enforceNotIsolatedCaller("getProcessPss"); 5467 long[] pss = new long[pids.length]; 5468 for (int i=pids.length-1; i>=0; i--) { 5469 ProcessRecord proc; 5470 int oomAdj; 5471 synchronized (this) { 5472 synchronized (mPidsSelfLocked) { 5473 proc = mPidsSelfLocked.get(pids[i]); 5474 oomAdj = proc != null ? proc.setAdj : 0; 5475 } 5476 } 5477 long[] tmpUss = new long[1]; 5478 pss[i] = Debug.getPss(pids[i], tmpUss); 5479 if (proc != null) { 5480 synchronized (this) { 5481 if (proc.thread != null && proc.setAdj == oomAdj) { 5482 // Record this for posterity if the process has been stable. 5483 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5484 } 5485 } 5486 } 5487 } 5488 return pss; 5489 } 5490 5491 @Override 5492 public void killApplicationProcess(String processName, int uid) { 5493 if (processName == null) { 5494 return; 5495 } 5496 5497 int callerUid = Binder.getCallingUid(); 5498 // Only the system server can kill an application 5499 if (callerUid == Process.SYSTEM_UID) { 5500 synchronized (this) { 5501 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5502 if (app != null && app.thread != null) { 5503 try { 5504 app.thread.scheduleSuicide(); 5505 } catch (RemoteException e) { 5506 // If the other end already died, then our work here is done. 5507 } 5508 } else { 5509 Slog.w(TAG, "Process/uid not found attempting kill of " 5510 + processName + " / " + uid); 5511 } 5512 } 5513 } else { 5514 throw new SecurityException(callerUid + " cannot kill app process: " + 5515 processName); 5516 } 5517 } 5518 5519 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5520 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5521 false, true, false, false, UserHandle.getUserId(uid), reason); 5522 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5523 Uri.fromParts("package", packageName, null)); 5524 if (!mProcessesReady) { 5525 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5526 | Intent.FLAG_RECEIVER_FOREGROUND); 5527 } 5528 intent.putExtra(Intent.EXTRA_UID, uid); 5529 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5530 broadcastIntentLocked(null, null, intent, 5531 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5532 false, false, 5533 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5534 } 5535 5536 private void forceStopUserLocked(int userId, String reason) { 5537 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5538 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5540 | Intent.FLAG_RECEIVER_FOREGROUND); 5541 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5542 broadcastIntentLocked(null, null, intent, 5543 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5544 false, false, 5545 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5546 } 5547 5548 private final boolean killPackageProcessesLocked(String packageName, int appId, 5549 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5550 boolean doit, boolean evenPersistent, String reason) { 5551 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5552 5553 // Remove all processes this package may have touched: all with the 5554 // same UID (except for the system or root user), and all whose name 5555 // matches the package name. 5556 final int NP = mProcessNames.getMap().size(); 5557 for (int ip=0; ip<NP; ip++) { 5558 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5559 final int NA = apps.size(); 5560 for (int ia=0; ia<NA; ia++) { 5561 ProcessRecord app = apps.valueAt(ia); 5562 if (app.persistent && !evenPersistent) { 5563 // we don't kill persistent processes 5564 continue; 5565 } 5566 if (app.removed) { 5567 if (doit) { 5568 procs.add(app); 5569 } 5570 continue; 5571 } 5572 5573 // Skip process if it doesn't meet our oom adj requirement. 5574 if (app.setAdj < minOomAdj) { 5575 continue; 5576 } 5577 5578 // If no package is specified, we call all processes under the 5579 // give user id. 5580 if (packageName == null) { 5581 if (app.userId != userId) { 5582 continue; 5583 } 5584 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5585 continue; 5586 } 5587 // Package has been specified, we want to hit all processes 5588 // that match it. We need to qualify this by the processes 5589 // that are running under the specified app and user ID. 5590 } else { 5591 final boolean isDep = app.pkgDeps != null 5592 && app.pkgDeps.contains(packageName); 5593 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5594 continue; 5595 } 5596 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5597 continue; 5598 } 5599 if (!app.pkgList.containsKey(packageName) && !isDep) { 5600 continue; 5601 } 5602 } 5603 5604 // Process has passed all conditions, kill it! 5605 if (!doit) { 5606 return true; 5607 } 5608 app.removed = true; 5609 procs.add(app); 5610 } 5611 } 5612 5613 int N = procs.size(); 5614 for (int i=0; i<N; i++) { 5615 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5616 } 5617 updateOomAdjLocked(); 5618 return N > 0; 5619 } 5620 5621 private final boolean forceStopPackageLocked(String name, int appId, 5622 boolean callerWillRestart, boolean purgeCache, boolean doit, 5623 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5624 int i; 5625 int N; 5626 5627 if (userId == UserHandle.USER_ALL && name == null) { 5628 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5629 } 5630 5631 if (appId < 0 && name != null) { 5632 try { 5633 appId = UserHandle.getAppId( 5634 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5635 } catch (RemoteException e) { 5636 } 5637 } 5638 5639 if (doit) { 5640 if (name != null) { 5641 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5642 + " user=" + userId + ": " + reason); 5643 } else { 5644 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5645 } 5646 5647 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5648 for (int ip=pmap.size()-1; ip>=0; ip--) { 5649 SparseArray<Long> ba = pmap.valueAt(ip); 5650 for (i=ba.size()-1; i>=0; i--) { 5651 boolean remove = false; 5652 final int entUid = ba.keyAt(i); 5653 if (name != null) { 5654 if (userId == UserHandle.USER_ALL) { 5655 if (UserHandle.getAppId(entUid) == appId) { 5656 remove = true; 5657 } 5658 } else { 5659 if (entUid == UserHandle.getUid(userId, appId)) { 5660 remove = true; 5661 } 5662 } 5663 } else if (UserHandle.getUserId(entUid) == userId) { 5664 remove = true; 5665 } 5666 if (remove) { 5667 ba.removeAt(i); 5668 } 5669 } 5670 if (ba.size() == 0) { 5671 pmap.removeAt(ip); 5672 } 5673 } 5674 } 5675 5676 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5677 -100, callerWillRestart, true, doit, evenPersistent, 5678 name == null ? ("stop user " + userId) : ("stop " + name)); 5679 5680 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5681 if (!doit) { 5682 return true; 5683 } 5684 didSomething = true; 5685 } 5686 5687 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5688 if (!doit) { 5689 return true; 5690 } 5691 didSomething = true; 5692 } 5693 5694 if (name == null) { 5695 // Remove all sticky broadcasts from this user. 5696 mStickyBroadcasts.remove(userId); 5697 } 5698 5699 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5700 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5701 userId, providers)) { 5702 if (!doit) { 5703 return true; 5704 } 5705 didSomething = true; 5706 } 5707 N = providers.size(); 5708 for (i=0; i<N; i++) { 5709 removeDyingProviderLocked(null, providers.get(i), true); 5710 } 5711 5712 // Remove transient permissions granted from/to this package/user 5713 removeUriPermissionsForPackageLocked(name, userId, false); 5714 5715 if (name == null || uninstalling) { 5716 // Remove pending intents. For now we only do this when force 5717 // stopping users, because we have some problems when doing this 5718 // for packages -- app widgets are not currently cleaned up for 5719 // such packages, so they can be left with bad pending intents. 5720 if (mIntentSenderRecords.size() > 0) { 5721 Iterator<WeakReference<PendingIntentRecord>> it 5722 = mIntentSenderRecords.values().iterator(); 5723 while (it.hasNext()) { 5724 WeakReference<PendingIntentRecord> wpir = it.next(); 5725 if (wpir == null) { 5726 it.remove(); 5727 continue; 5728 } 5729 PendingIntentRecord pir = wpir.get(); 5730 if (pir == null) { 5731 it.remove(); 5732 continue; 5733 } 5734 if (name == null) { 5735 // Stopping user, remove all objects for the user. 5736 if (pir.key.userId != userId) { 5737 // Not the same user, skip it. 5738 continue; 5739 } 5740 } else { 5741 if (UserHandle.getAppId(pir.uid) != appId) { 5742 // Different app id, skip it. 5743 continue; 5744 } 5745 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5746 // Different user, skip it. 5747 continue; 5748 } 5749 if (!pir.key.packageName.equals(name)) { 5750 // Different package, skip it. 5751 continue; 5752 } 5753 } 5754 if (!doit) { 5755 return true; 5756 } 5757 didSomething = true; 5758 it.remove(); 5759 pir.canceled = true; 5760 if (pir.key.activity != null) { 5761 pir.key.activity.pendingResults.remove(pir.ref); 5762 } 5763 } 5764 } 5765 } 5766 5767 if (doit) { 5768 if (purgeCache && name != null) { 5769 AttributeCache ac = AttributeCache.instance(); 5770 if (ac != null) { 5771 ac.removePackage(name); 5772 } 5773 } 5774 if (mBooted) { 5775 mStackSupervisor.resumeTopActivitiesLocked(); 5776 mStackSupervisor.scheduleIdleLocked(); 5777 } 5778 } 5779 5780 return didSomething; 5781 } 5782 5783 private final boolean removeProcessLocked(ProcessRecord app, 5784 boolean callerWillRestart, boolean allowRestart, String reason) { 5785 final String name = app.processName; 5786 final int uid = app.uid; 5787 if (DEBUG_PROCESSES) Slog.d( 5788 TAG, "Force removing proc " + app.toShortString() + " (" + name 5789 + "/" + uid + ")"); 5790 5791 mProcessNames.remove(name, uid); 5792 mIsolatedProcesses.remove(app.uid); 5793 if (mHeavyWeightProcess == app) { 5794 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5795 mHeavyWeightProcess.userId, 0)); 5796 mHeavyWeightProcess = null; 5797 } 5798 boolean needRestart = false; 5799 if (app.pid > 0 && app.pid != MY_PID) { 5800 int pid = app.pid; 5801 synchronized (mPidsSelfLocked) { 5802 mPidsSelfLocked.remove(pid); 5803 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5804 } 5805 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5806 if (app.isolated) { 5807 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5808 } 5809 app.kill(reason, true); 5810 handleAppDiedLocked(app, true, allowRestart); 5811 removeLruProcessLocked(app); 5812 5813 if (app.persistent && !app.isolated) { 5814 if (!callerWillRestart) { 5815 addAppLocked(app.info, false, null /* ABI override */); 5816 } else { 5817 needRestart = true; 5818 } 5819 } 5820 } else { 5821 mRemovedProcesses.add(app); 5822 } 5823 5824 return needRestart; 5825 } 5826 5827 private final void processStartTimedOutLocked(ProcessRecord app) { 5828 final int pid = app.pid; 5829 boolean gone = false; 5830 synchronized (mPidsSelfLocked) { 5831 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5832 if (knownApp != null && knownApp.thread == null) { 5833 mPidsSelfLocked.remove(pid); 5834 gone = true; 5835 } 5836 } 5837 5838 if (gone) { 5839 Slog.w(TAG, "Process " + app + " failed to attach"); 5840 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5841 pid, app.uid, app.processName); 5842 mProcessNames.remove(app.processName, app.uid); 5843 mIsolatedProcesses.remove(app.uid); 5844 if (mHeavyWeightProcess == app) { 5845 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5846 mHeavyWeightProcess.userId, 0)); 5847 mHeavyWeightProcess = null; 5848 } 5849 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5850 if (app.isolated) { 5851 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5852 } 5853 // Take care of any launching providers waiting for this process. 5854 checkAppInLaunchingProvidersLocked(app, true); 5855 // Take care of any services that are waiting for the process. 5856 mServices.processStartTimedOutLocked(app); 5857 app.kill("start timeout", true); 5858 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5859 Slog.w(TAG, "Unattached app died before backup, skipping"); 5860 try { 5861 IBackupManager bm = IBackupManager.Stub.asInterface( 5862 ServiceManager.getService(Context.BACKUP_SERVICE)); 5863 bm.agentDisconnected(app.info.packageName); 5864 } catch (RemoteException e) { 5865 // Can't happen; the backup manager is local 5866 } 5867 } 5868 if (isPendingBroadcastProcessLocked(pid)) { 5869 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5870 skipPendingBroadcastLocked(pid); 5871 } 5872 } else { 5873 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5874 } 5875 } 5876 5877 private final boolean attachApplicationLocked(IApplicationThread thread, 5878 int pid) { 5879 5880 // Find the application record that is being attached... either via 5881 // the pid if we are running in multiple processes, or just pull the 5882 // next app record if we are emulating process with anonymous threads. 5883 ProcessRecord app; 5884 if (pid != MY_PID && pid >= 0) { 5885 synchronized (mPidsSelfLocked) { 5886 app = mPidsSelfLocked.get(pid); 5887 } 5888 } else { 5889 app = null; 5890 } 5891 5892 if (app == null) { 5893 Slog.w(TAG, "No pending application record for pid " + pid 5894 + " (IApplicationThread " + thread + "); dropping process"); 5895 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5896 if (pid > 0 && pid != MY_PID) { 5897 Process.killProcessQuiet(pid); 5898 //TODO: Process.killProcessGroup(app.info.uid, pid); 5899 } else { 5900 try { 5901 thread.scheduleExit(); 5902 } catch (Exception e) { 5903 // Ignore exceptions. 5904 } 5905 } 5906 return false; 5907 } 5908 5909 // If this application record is still attached to a previous 5910 // process, clean it up now. 5911 if (app.thread != null) { 5912 handleAppDiedLocked(app, true, true); 5913 } 5914 5915 // Tell the process all about itself. 5916 5917 if (localLOGV) Slog.v( 5918 TAG, "Binding process pid " + pid + " to record " + app); 5919 5920 final String processName = app.processName; 5921 try { 5922 AppDeathRecipient adr = new AppDeathRecipient( 5923 app, pid, thread); 5924 thread.asBinder().linkToDeath(adr, 0); 5925 app.deathRecipient = adr; 5926 } catch (RemoteException e) { 5927 app.resetPackageList(mProcessStats); 5928 startProcessLocked(app, "link fail", processName); 5929 return false; 5930 } 5931 5932 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5933 5934 app.makeActive(thread, mProcessStats); 5935 app.curAdj = app.setAdj = -100; 5936 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5937 app.forcingToForeground = null; 5938 updateProcessForegroundLocked(app, false, false); 5939 app.hasShownUi = false; 5940 app.debugging = false; 5941 app.cached = false; 5942 5943 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5944 5945 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5946 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5947 5948 if (!normalMode) { 5949 Slog.i(TAG, "Launching preboot mode app: " + app); 5950 } 5951 5952 if (localLOGV) Slog.v( 5953 TAG, "New app record " + app 5954 + " thread=" + thread.asBinder() + " pid=" + pid); 5955 try { 5956 int testMode = IApplicationThread.DEBUG_OFF; 5957 if (mDebugApp != null && mDebugApp.equals(processName)) { 5958 testMode = mWaitForDebugger 5959 ? IApplicationThread.DEBUG_WAIT 5960 : IApplicationThread.DEBUG_ON; 5961 app.debugging = true; 5962 if (mDebugTransient) { 5963 mDebugApp = mOrigDebugApp; 5964 mWaitForDebugger = mOrigWaitForDebugger; 5965 } 5966 } 5967 String profileFile = app.instrumentationProfileFile; 5968 ParcelFileDescriptor profileFd = null; 5969 int samplingInterval = 0; 5970 boolean profileAutoStop = false; 5971 if (mProfileApp != null && mProfileApp.equals(processName)) { 5972 mProfileProc = app; 5973 profileFile = mProfileFile; 5974 profileFd = mProfileFd; 5975 samplingInterval = mSamplingInterval; 5976 profileAutoStop = mAutoStopProfiler; 5977 } 5978 boolean enableOpenGlTrace = false; 5979 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5980 enableOpenGlTrace = true; 5981 mOpenGlTraceApp = null; 5982 } 5983 5984 // If the app is being launched for restore or full backup, set it up specially 5985 boolean isRestrictedBackupMode = false; 5986 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5987 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5988 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5989 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5990 } 5991 5992 ensurePackageDexOpt(app.instrumentationInfo != null 5993 ? app.instrumentationInfo.packageName 5994 : app.info.packageName); 5995 if (app.instrumentationClass != null) { 5996 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5997 } 5998 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5999 + processName + " with config " + mConfiguration); 6000 ApplicationInfo appInfo = app.instrumentationInfo != null 6001 ? app.instrumentationInfo : app.info; 6002 app.compat = compatibilityInfoForPackageLocked(appInfo); 6003 if (profileFd != null) { 6004 profileFd = profileFd.dup(); 6005 } 6006 ProfilerInfo profilerInfo = profileFile == null ? null 6007 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6008 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6009 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6010 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6011 isRestrictedBackupMode || !normalMode, app.persistent, 6012 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6013 mCoreSettingsObserver.getCoreSettingsLocked()); 6014 updateLruProcessLocked(app, false, null); 6015 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6016 } catch (Exception e) { 6017 // todo: Yikes! What should we do? For now we will try to 6018 // start another process, but that could easily get us in 6019 // an infinite loop of restarting processes... 6020 Slog.w(TAG, "Exception thrown during bind!", e); 6021 6022 app.resetPackageList(mProcessStats); 6023 app.unlinkDeathRecipient(); 6024 startProcessLocked(app, "bind fail", processName); 6025 return false; 6026 } 6027 6028 // Remove this record from the list of starting applications. 6029 mPersistentStartingProcesses.remove(app); 6030 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6031 "Attach application locked removing on hold: " + app); 6032 mProcessesOnHold.remove(app); 6033 6034 boolean badApp = false; 6035 boolean didSomething = false; 6036 6037 // See if the top visible activity is waiting to run in this process... 6038 if (normalMode) { 6039 try { 6040 if (mStackSupervisor.attachApplicationLocked(app)) { 6041 didSomething = true; 6042 } 6043 } catch (Exception e) { 6044 badApp = true; 6045 } 6046 } 6047 6048 // Find any services that should be running in this process... 6049 if (!badApp) { 6050 try { 6051 didSomething |= mServices.attachApplicationLocked(app, processName); 6052 } catch (Exception e) { 6053 badApp = true; 6054 } 6055 } 6056 6057 // Check if a next-broadcast receiver is in this process... 6058 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6059 try { 6060 didSomething |= sendPendingBroadcastsLocked(app); 6061 } catch (Exception e) { 6062 // If the app died trying to launch the receiver we declare it 'bad' 6063 badApp = true; 6064 } 6065 } 6066 6067 // Check whether the next backup agent is in this process... 6068 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6069 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6070 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6071 try { 6072 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6073 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6074 mBackupTarget.backupMode); 6075 } catch (Exception e) { 6076 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6077 e.printStackTrace(); 6078 } 6079 } 6080 6081 if (badApp) { 6082 // todo: Also need to kill application to deal with all 6083 // kinds of exceptions. 6084 handleAppDiedLocked(app, false, true); 6085 return false; 6086 } 6087 6088 if (!didSomething) { 6089 updateOomAdjLocked(); 6090 } 6091 6092 return true; 6093 } 6094 6095 @Override 6096 public final void attachApplication(IApplicationThread thread) { 6097 synchronized (this) { 6098 int callingPid = Binder.getCallingPid(); 6099 final long origId = Binder.clearCallingIdentity(); 6100 attachApplicationLocked(thread, callingPid); 6101 Binder.restoreCallingIdentity(origId); 6102 } 6103 } 6104 6105 @Override 6106 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6107 final long origId = Binder.clearCallingIdentity(); 6108 synchronized (this) { 6109 ActivityStack stack = ActivityRecord.getStackLocked(token); 6110 if (stack != null) { 6111 ActivityRecord r = 6112 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6113 if (stopProfiling) { 6114 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6115 try { 6116 mProfileFd.close(); 6117 } catch (IOException e) { 6118 } 6119 clearProfilerLocked(); 6120 } 6121 } 6122 } 6123 } 6124 Binder.restoreCallingIdentity(origId); 6125 } 6126 6127 void postEnableScreenAfterBootLocked() { 6128 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6129 } 6130 6131 void enableScreenAfterBoot() { 6132 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6133 SystemClock.uptimeMillis()); 6134 mWindowManager.enableScreenAfterBoot(); 6135 6136 synchronized (this) { 6137 updateEventDispatchingLocked(); 6138 } 6139 } 6140 6141 @Override 6142 public void showBootMessage(final CharSequence msg, final boolean always) { 6143 enforceNotIsolatedCaller("showBootMessage"); 6144 mWindowManager.showBootMessage(msg, always); 6145 } 6146 6147 @Override 6148 public void keyguardWaitingForActivityDrawn() { 6149 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6150 final long token = Binder.clearCallingIdentity(); 6151 try { 6152 synchronized (this) { 6153 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6154 mWindowManager.keyguardWaitingForActivityDrawn(); 6155 } 6156 } finally { 6157 Binder.restoreCallingIdentity(token); 6158 } 6159 } 6160 6161 final void finishBooting() { 6162 // Register receivers to handle package update events 6163 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6164 6165 // Let system services know. 6166 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6167 6168 synchronized (this) { 6169 // Ensure that any processes we had put on hold are now started 6170 // up. 6171 final int NP = mProcessesOnHold.size(); 6172 if (NP > 0) { 6173 ArrayList<ProcessRecord> procs = 6174 new ArrayList<ProcessRecord>(mProcessesOnHold); 6175 for (int ip=0; ip<NP; ip++) { 6176 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6177 + procs.get(ip)); 6178 startProcessLocked(procs.get(ip), "on-hold", null); 6179 } 6180 } 6181 6182 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6183 // Start looking for apps that are abusing wake locks. 6184 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6185 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6186 // Tell anyone interested that we are done booting! 6187 SystemProperties.set("sys.boot_completed", "1"); 6188 SystemProperties.set("dev.bootcomplete", "1"); 6189 for (int i=0; i<mStartedUsers.size(); i++) { 6190 UserStartedState uss = mStartedUsers.valueAt(i); 6191 if (uss.mState == UserStartedState.STATE_BOOTING) { 6192 uss.mState = UserStartedState.STATE_RUNNING; 6193 final int userId = mStartedUsers.keyAt(i); 6194 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6195 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6196 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6197 broadcastIntentLocked(null, null, intent, null, 6198 new IIntentReceiver.Stub() { 6199 @Override 6200 public void performReceive(Intent intent, int resultCode, 6201 String data, Bundle extras, boolean ordered, 6202 boolean sticky, int sendingUser) { 6203 synchronized (ActivityManagerService.this) { 6204 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6205 true, false); 6206 } 6207 } 6208 }, 6209 0, null, null, 6210 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6211 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6212 userId); 6213 } 6214 } 6215 scheduleStartProfilesLocked(); 6216 } 6217 } 6218 } 6219 6220 final void ensureBootCompleted() { 6221 boolean booting; 6222 boolean enableScreen; 6223 synchronized (this) { 6224 booting = mBooting; 6225 mBooting = false; 6226 enableScreen = !mBooted; 6227 mBooted = true; 6228 } 6229 6230 if (booting) { 6231 finishBooting(); 6232 } 6233 6234 if (enableScreen) { 6235 enableScreenAfterBoot(); 6236 } 6237 } 6238 6239 @Override 6240 public final void activityResumed(IBinder token) { 6241 final long origId = Binder.clearCallingIdentity(); 6242 synchronized(this) { 6243 ActivityStack stack = ActivityRecord.getStackLocked(token); 6244 if (stack != null) { 6245 ActivityRecord.activityResumedLocked(token); 6246 } 6247 } 6248 Binder.restoreCallingIdentity(origId); 6249 } 6250 6251 @Override 6252 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6253 final long origId = Binder.clearCallingIdentity(); 6254 synchronized(this) { 6255 ActivityStack stack = ActivityRecord.getStackLocked(token); 6256 if (stack != null) { 6257 stack.activityPausedLocked(token, false, persistentState); 6258 } 6259 } 6260 Binder.restoreCallingIdentity(origId); 6261 } 6262 6263 @Override 6264 public final void activityStopped(IBinder token, Bundle icicle, 6265 PersistableBundle persistentState, CharSequence description) { 6266 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6267 6268 // Refuse possible leaked file descriptors 6269 if (icicle != null && icicle.hasFileDescriptors()) { 6270 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6271 } 6272 6273 final long origId = Binder.clearCallingIdentity(); 6274 6275 synchronized (this) { 6276 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6277 if (r != null) { 6278 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6279 } 6280 } 6281 6282 trimApplications(); 6283 6284 Binder.restoreCallingIdentity(origId); 6285 } 6286 6287 @Override 6288 public final void activityDestroyed(IBinder token) { 6289 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6290 synchronized (this) { 6291 ActivityStack stack = ActivityRecord.getStackLocked(token); 6292 if (stack != null) { 6293 stack.activityDestroyedLocked(token); 6294 } 6295 } 6296 } 6297 6298 @Override 6299 public final void backgroundResourcesReleased(IBinder token) { 6300 final long origId = Binder.clearCallingIdentity(); 6301 try { 6302 synchronized (this) { 6303 ActivityStack stack = ActivityRecord.getStackLocked(token); 6304 if (stack != null) { 6305 stack.backgroundResourcesReleased(token); 6306 } 6307 } 6308 } finally { 6309 Binder.restoreCallingIdentity(origId); 6310 } 6311 } 6312 6313 @Override 6314 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6315 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6316 } 6317 6318 @Override 6319 public final void notifyEnterAnimationComplete(IBinder token) { 6320 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6321 } 6322 6323 @Override 6324 public String getCallingPackage(IBinder token) { 6325 synchronized (this) { 6326 ActivityRecord r = getCallingRecordLocked(token); 6327 return r != null ? r.info.packageName : null; 6328 } 6329 } 6330 6331 @Override 6332 public ComponentName getCallingActivity(IBinder token) { 6333 synchronized (this) { 6334 ActivityRecord r = getCallingRecordLocked(token); 6335 return r != null ? r.intent.getComponent() : null; 6336 } 6337 } 6338 6339 private ActivityRecord getCallingRecordLocked(IBinder token) { 6340 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6341 if (r == null) { 6342 return null; 6343 } 6344 return r.resultTo; 6345 } 6346 6347 @Override 6348 public ComponentName getActivityClassForToken(IBinder token) { 6349 synchronized(this) { 6350 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6351 if (r == null) { 6352 return null; 6353 } 6354 return r.intent.getComponent(); 6355 } 6356 } 6357 6358 @Override 6359 public String getPackageForToken(IBinder token) { 6360 synchronized(this) { 6361 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6362 if (r == null) { 6363 return null; 6364 } 6365 return r.packageName; 6366 } 6367 } 6368 6369 @Override 6370 public IIntentSender getIntentSender(int type, 6371 String packageName, IBinder token, String resultWho, 6372 int requestCode, Intent[] intents, String[] resolvedTypes, 6373 int flags, Bundle options, int userId) { 6374 enforceNotIsolatedCaller("getIntentSender"); 6375 // Refuse possible leaked file descriptors 6376 if (intents != null) { 6377 if (intents.length < 1) { 6378 throw new IllegalArgumentException("Intents array length must be >= 1"); 6379 } 6380 for (int i=0; i<intents.length; i++) { 6381 Intent intent = intents[i]; 6382 if (intent != null) { 6383 if (intent.hasFileDescriptors()) { 6384 throw new IllegalArgumentException("File descriptors passed in Intent"); 6385 } 6386 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6387 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6388 throw new IllegalArgumentException( 6389 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6390 } 6391 intents[i] = new Intent(intent); 6392 } 6393 } 6394 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6395 throw new IllegalArgumentException( 6396 "Intent array length does not match resolvedTypes length"); 6397 } 6398 } 6399 if (options != null) { 6400 if (options.hasFileDescriptors()) { 6401 throw new IllegalArgumentException("File descriptors passed in options"); 6402 } 6403 } 6404 6405 synchronized(this) { 6406 int callingUid = Binder.getCallingUid(); 6407 int origUserId = userId; 6408 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6409 type == ActivityManager.INTENT_SENDER_BROADCAST, 6410 ALLOW_NON_FULL, "getIntentSender", null); 6411 if (origUserId == UserHandle.USER_CURRENT) { 6412 // We don't want to evaluate this until the pending intent is 6413 // actually executed. However, we do want to always do the 6414 // security checking for it above. 6415 userId = UserHandle.USER_CURRENT; 6416 } 6417 try { 6418 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6419 int uid = AppGlobals.getPackageManager() 6420 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6421 if (!UserHandle.isSameApp(callingUid, uid)) { 6422 String msg = "Permission Denial: getIntentSender() from pid=" 6423 + Binder.getCallingPid() 6424 + ", uid=" + Binder.getCallingUid() 6425 + ", (need uid=" + uid + ")" 6426 + " is not allowed to send as package " + packageName; 6427 Slog.w(TAG, msg); 6428 throw new SecurityException(msg); 6429 } 6430 } 6431 6432 return getIntentSenderLocked(type, packageName, callingUid, userId, 6433 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6434 6435 } catch (RemoteException e) { 6436 throw new SecurityException(e); 6437 } 6438 } 6439 } 6440 6441 IIntentSender getIntentSenderLocked(int type, String packageName, 6442 int callingUid, int userId, IBinder token, String resultWho, 6443 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6444 Bundle options) { 6445 if (DEBUG_MU) 6446 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6447 ActivityRecord activity = null; 6448 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6449 activity = ActivityRecord.isInStackLocked(token); 6450 if (activity == null) { 6451 return null; 6452 } 6453 if (activity.finishing) { 6454 return null; 6455 } 6456 } 6457 6458 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6459 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6460 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6461 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6462 |PendingIntent.FLAG_UPDATE_CURRENT); 6463 6464 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6465 type, packageName, activity, resultWho, 6466 requestCode, intents, resolvedTypes, flags, options, userId); 6467 WeakReference<PendingIntentRecord> ref; 6468 ref = mIntentSenderRecords.get(key); 6469 PendingIntentRecord rec = ref != null ? ref.get() : null; 6470 if (rec != null) { 6471 if (!cancelCurrent) { 6472 if (updateCurrent) { 6473 if (rec.key.requestIntent != null) { 6474 rec.key.requestIntent.replaceExtras(intents != null ? 6475 intents[intents.length - 1] : null); 6476 } 6477 if (intents != null) { 6478 intents[intents.length-1] = rec.key.requestIntent; 6479 rec.key.allIntents = intents; 6480 rec.key.allResolvedTypes = resolvedTypes; 6481 } else { 6482 rec.key.allIntents = null; 6483 rec.key.allResolvedTypes = null; 6484 } 6485 } 6486 return rec; 6487 } 6488 rec.canceled = true; 6489 mIntentSenderRecords.remove(key); 6490 } 6491 if (noCreate) { 6492 return rec; 6493 } 6494 rec = new PendingIntentRecord(this, key, callingUid); 6495 mIntentSenderRecords.put(key, rec.ref); 6496 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6497 if (activity.pendingResults == null) { 6498 activity.pendingResults 6499 = new HashSet<WeakReference<PendingIntentRecord>>(); 6500 } 6501 activity.pendingResults.add(rec.ref); 6502 } 6503 return rec; 6504 } 6505 6506 @Override 6507 public void cancelIntentSender(IIntentSender sender) { 6508 if (!(sender instanceof PendingIntentRecord)) { 6509 return; 6510 } 6511 synchronized(this) { 6512 PendingIntentRecord rec = (PendingIntentRecord)sender; 6513 try { 6514 int uid = AppGlobals.getPackageManager() 6515 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6516 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6517 String msg = "Permission Denial: cancelIntentSender() from pid=" 6518 + Binder.getCallingPid() 6519 + ", uid=" + Binder.getCallingUid() 6520 + " is not allowed to cancel packges " 6521 + rec.key.packageName; 6522 Slog.w(TAG, msg); 6523 throw new SecurityException(msg); 6524 } 6525 } catch (RemoteException e) { 6526 throw new SecurityException(e); 6527 } 6528 cancelIntentSenderLocked(rec, true); 6529 } 6530 } 6531 6532 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6533 rec.canceled = true; 6534 mIntentSenderRecords.remove(rec.key); 6535 if (cleanActivity && rec.key.activity != null) { 6536 rec.key.activity.pendingResults.remove(rec.ref); 6537 } 6538 } 6539 6540 @Override 6541 public String getPackageForIntentSender(IIntentSender pendingResult) { 6542 if (!(pendingResult instanceof PendingIntentRecord)) { 6543 return null; 6544 } 6545 try { 6546 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6547 return res.key.packageName; 6548 } catch (ClassCastException e) { 6549 } 6550 return null; 6551 } 6552 6553 @Override 6554 public int getUidForIntentSender(IIntentSender sender) { 6555 if (sender instanceof PendingIntentRecord) { 6556 try { 6557 PendingIntentRecord res = (PendingIntentRecord)sender; 6558 return res.uid; 6559 } catch (ClassCastException e) { 6560 } 6561 } 6562 return -1; 6563 } 6564 6565 @Override 6566 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6567 if (!(pendingResult instanceof PendingIntentRecord)) { 6568 return false; 6569 } 6570 try { 6571 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6572 if (res.key.allIntents == null) { 6573 return false; 6574 } 6575 for (int i=0; i<res.key.allIntents.length; i++) { 6576 Intent intent = res.key.allIntents[i]; 6577 if (intent.getPackage() != null && intent.getComponent() != null) { 6578 return false; 6579 } 6580 } 6581 return true; 6582 } catch (ClassCastException e) { 6583 } 6584 return false; 6585 } 6586 6587 @Override 6588 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6589 if (!(pendingResult instanceof PendingIntentRecord)) { 6590 return false; 6591 } 6592 try { 6593 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6594 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6595 return true; 6596 } 6597 return false; 6598 } catch (ClassCastException e) { 6599 } 6600 return false; 6601 } 6602 6603 @Override 6604 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6605 if (!(pendingResult instanceof PendingIntentRecord)) { 6606 return null; 6607 } 6608 try { 6609 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6610 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6611 } catch (ClassCastException e) { 6612 } 6613 return null; 6614 } 6615 6616 @Override 6617 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6618 if (!(pendingResult instanceof PendingIntentRecord)) { 6619 return null; 6620 } 6621 try { 6622 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6623 Intent intent = res.key.requestIntent; 6624 if (intent != null) { 6625 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6626 || res.lastTagPrefix.equals(prefix))) { 6627 return res.lastTag; 6628 } 6629 res.lastTagPrefix = prefix; 6630 StringBuilder sb = new StringBuilder(128); 6631 if (prefix != null) { 6632 sb.append(prefix); 6633 } 6634 if (intent.getAction() != null) { 6635 sb.append(intent.getAction()); 6636 } else if (intent.getComponent() != null) { 6637 intent.getComponent().appendShortString(sb); 6638 } else { 6639 sb.append("?"); 6640 } 6641 return res.lastTag = sb.toString(); 6642 } 6643 } catch (ClassCastException e) { 6644 } 6645 return null; 6646 } 6647 6648 @Override 6649 public void setProcessLimit(int max) { 6650 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6651 "setProcessLimit()"); 6652 synchronized (this) { 6653 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6654 mProcessLimitOverride = max; 6655 } 6656 trimApplications(); 6657 } 6658 6659 @Override 6660 public int getProcessLimit() { 6661 synchronized (this) { 6662 return mProcessLimitOverride; 6663 } 6664 } 6665 6666 void foregroundTokenDied(ForegroundToken token) { 6667 synchronized (ActivityManagerService.this) { 6668 synchronized (mPidsSelfLocked) { 6669 ForegroundToken cur 6670 = mForegroundProcesses.get(token.pid); 6671 if (cur != token) { 6672 return; 6673 } 6674 mForegroundProcesses.remove(token.pid); 6675 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6676 if (pr == null) { 6677 return; 6678 } 6679 pr.forcingToForeground = null; 6680 updateProcessForegroundLocked(pr, false, false); 6681 } 6682 updateOomAdjLocked(); 6683 } 6684 } 6685 6686 @Override 6687 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6688 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6689 "setProcessForeground()"); 6690 synchronized(this) { 6691 boolean changed = false; 6692 6693 synchronized (mPidsSelfLocked) { 6694 ProcessRecord pr = mPidsSelfLocked.get(pid); 6695 if (pr == null && isForeground) { 6696 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6697 return; 6698 } 6699 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6700 if (oldToken != null) { 6701 oldToken.token.unlinkToDeath(oldToken, 0); 6702 mForegroundProcesses.remove(pid); 6703 if (pr != null) { 6704 pr.forcingToForeground = null; 6705 } 6706 changed = true; 6707 } 6708 if (isForeground && token != null) { 6709 ForegroundToken newToken = new ForegroundToken() { 6710 @Override 6711 public void binderDied() { 6712 foregroundTokenDied(this); 6713 } 6714 }; 6715 newToken.pid = pid; 6716 newToken.token = token; 6717 try { 6718 token.linkToDeath(newToken, 0); 6719 mForegroundProcesses.put(pid, newToken); 6720 pr.forcingToForeground = token; 6721 changed = true; 6722 } catch (RemoteException e) { 6723 // If the process died while doing this, we will later 6724 // do the cleanup with the process death link. 6725 } 6726 } 6727 } 6728 6729 if (changed) { 6730 updateOomAdjLocked(); 6731 } 6732 } 6733 } 6734 6735 // ========================================================= 6736 // PERMISSIONS 6737 // ========================================================= 6738 6739 static class PermissionController extends IPermissionController.Stub { 6740 ActivityManagerService mActivityManagerService; 6741 PermissionController(ActivityManagerService activityManagerService) { 6742 mActivityManagerService = activityManagerService; 6743 } 6744 6745 @Override 6746 public boolean checkPermission(String permission, int pid, int uid) { 6747 return mActivityManagerService.checkPermission(permission, pid, 6748 uid) == PackageManager.PERMISSION_GRANTED; 6749 } 6750 } 6751 6752 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6753 @Override 6754 public int checkComponentPermission(String permission, int pid, int uid, 6755 int owningUid, boolean exported) { 6756 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6757 owningUid, exported); 6758 } 6759 6760 @Override 6761 public Object getAMSLock() { 6762 return ActivityManagerService.this; 6763 } 6764 } 6765 6766 /** 6767 * This can be called with or without the global lock held. 6768 */ 6769 int checkComponentPermission(String permission, int pid, int uid, 6770 int owningUid, boolean exported) { 6771 // We might be performing an operation on behalf of an indirect binder 6772 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6773 // client identity accordingly before proceeding. 6774 Identity tlsIdentity = sCallerIdentity.get(); 6775 if (tlsIdentity != null) { 6776 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6777 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6778 uid = tlsIdentity.uid; 6779 pid = tlsIdentity.pid; 6780 } 6781 6782 if (pid == MY_PID) { 6783 return PackageManager.PERMISSION_GRANTED; 6784 } 6785 6786 return ActivityManager.checkComponentPermission(permission, uid, 6787 owningUid, exported); 6788 } 6789 6790 /** 6791 * As the only public entry point for permissions checking, this method 6792 * can enforce the semantic that requesting a check on a null global 6793 * permission is automatically denied. (Internally a null permission 6794 * string is used when calling {@link #checkComponentPermission} in cases 6795 * when only uid-based security is needed.) 6796 * 6797 * This can be called with or without the global lock held. 6798 */ 6799 @Override 6800 public int checkPermission(String permission, int pid, int uid) { 6801 if (permission == null) { 6802 return PackageManager.PERMISSION_DENIED; 6803 } 6804 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6805 } 6806 6807 /** 6808 * Binder IPC calls go through the public entry point. 6809 * This can be called with or without the global lock held. 6810 */ 6811 int checkCallingPermission(String permission) { 6812 return checkPermission(permission, 6813 Binder.getCallingPid(), 6814 UserHandle.getAppId(Binder.getCallingUid())); 6815 } 6816 6817 /** 6818 * This can be called with or without the global lock held. 6819 */ 6820 void enforceCallingPermission(String permission, String func) { 6821 if (checkCallingPermission(permission) 6822 == PackageManager.PERMISSION_GRANTED) { 6823 return; 6824 } 6825 6826 String msg = "Permission Denial: " + func + " from pid=" 6827 + Binder.getCallingPid() 6828 + ", uid=" + Binder.getCallingUid() 6829 + " requires " + permission; 6830 Slog.w(TAG, msg); 6831 throw new SecurityException(msg); 6832 } 6833 6834 /** 6835 * Determine if UID is holding permissions required to access {@link Uri} in 6836 * the given {@link ProviderInfo}. Final permission checking is always done 6837 * in {@link ContentProvider}. 6838 */ 6839 private final boolean checkHoldingPermissionsLocked( 6840 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6841 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6842 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6843 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6844 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6845 != PERMISSION_GRANTED) { 6846 return false; 6847 } 6848 } 6849 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6850 } 6851 6852 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6853 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6854 if (pi.applicationInfo.uid == uid) { 6855 return true; 6856 } else if (!pi.exported) { 6857 return false; 6858 } 6859 6860 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6861 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6862 try { 6863 // check if target holds top-level <provider> permissions 6864 if (!readMet && pi.readPermission != null && considerUidPermissions 6865 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6866 readMet = true; 6867 } 6868 if (!writeMet && pi.writePermission != null && considerUidPermissions 6869 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6870 writeMet = true; 6871 } 6872 6873 // track if unprotected read/write is allowed; any denied 6874 // <path-permission> below removes this ability 6875 boolean allowDefaultRead = pi.readPermission == null; 6876 boolean allowDefaultWrite = pi.writePermission == null; 6877 6878 // check if target holds any <path-permission> that match uri 6879 final PathPermission[] pps = pi.pathPermissions; 6880 if (pps != null) { 6881 final String path = grantUri.uri.getPath(); 6882 int i = pps.length; 6883 while (i > 0 && (!readMet || !writeMet)) { 6884 i--; 6885 PathPermission pp = pps[i]; 6886 if (pp.match(path)) { 6887 if (!readMet) { 6888 final String pprperm = pp.getReadPermission(); 6889 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6890 + pprperm + " for " + pp.getPath() 6891 + ": match=" + pp.match(path) 6892 + " check=" + pm.checkUidPermission(pprperm, uid)); 6893 if (pprperm != null) { 6894 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6895 == PERMISSION_GRANTED) { 6896 readMet = true; 6897 } else { 6898 allowDefaultRead = false; 6899 } 6900 } 6901 } 6902 if (!writeMet) { 6903 final String ppwperm = pp.getWritePermission(); 6904 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6905 + ppwperm + " for " + pp.getPath() 6906 + ": match=" + pp.match(path) 6907 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6908 if (ppwperm != null) { 6909 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6910 == PERMISSION_GRANTED) { 6911 writeMet = true; 6912 } else { 6913 allowDefaultWrite = false; 6914 } 6915 } 6916 } 6917 } 6918 } 6919 } 6920 6921 // grant unprotected <provider> read/write, if not blocked by 6922 // <path-permission> above 6923 if (allowDefaultRead) readMet = true; 6924 if (allowDefaultWrite) writeMet = true; 6925 6926 } catch (RemoteException e) { 6927 return false; 6928 } 6929 6930 return readMet && writeMet; 6931 } 6932 6933 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6934 ProviderInfo pi = null; 6935 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6936 if (cpr != null) { 6937 pi = cpr.info; 6938 } else { 6939 try { 6940 pi = AppGlobals.getPackageManager().resolveContentProvider( 6941 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6942 } catch (RemoteException ex) { 6943 } 6944 } 6945 return pi; 6946 } 6947 6948 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6949 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6950 if (targetUris != null) { 6951 return targetUris.get(grantUri); 6952 } 6953 return null; 6954 } 6955 6956 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6957 String targetPkg, int targetUid, GrantUri grantUri) { 6958 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6959 if (targetUris == null) { 6960 targetUris = Maps.newArrayMap(); 6961 mGrantedUriPermissions.put(targetUid, targetUris); 6962 } 6963 6964 UriPermission perm = targetUris.get(grantUri); 6965 if (perm == null) { 6966 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6967 targetUris.put(grantUri, perm); 6968 } 6969 6970 return perm; 6971 } 6972 6973 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6974 final int modeFlags) { 6975 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6976 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6977 : UriPermission.STRENGTH_OWNED; 6978 6979 // Root gets to do everything. 6980 if (uid == 0) { 6981 return true; 6982 } 6983 6984 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6985 if (perms == null) return false; 6986 6987 // First look for exact match 6988 final UriPermission exactPerm = perms.get(grantUri); 6989 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6990 return true; 6991 } 6992 6993 // No exact match, look for prefixes 6994 final int N = perms.size(); 6995 for (int i = 0; i < N; i++) { 6996 final UriPermission perm = perms.valueAt(i); 6997 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6998 && perm.getStrength(modeFlags) >= minStrength) { 6999 return true; 7000 } 7001 } 7002 7003 return false; 7004 } 7005 7006 /** 7007 * @param uri This uri must NOT contain an embedded userId. 7008 * @param userId The userId in which the uri is to be resolved. 7009 */ 7010 @Override 7011 public int checkUriPermission(Uri uri, int pid, int uid, 7012 final int modeFlags, int userId) { 7013 enforceNotIsolatedCaller("checkUriPermission"); 7014 7015 // Another redirected-binder-call permissions check as in 7016 // {@link checkComponentPermission}. 7017 Identity tlsIdentity = sCallerIdentity.get(); 7018 if (tlsIdentity != null) { 7019 uid = tlsIdentity.uid; 7020 pid = tlsIdentity.pid; 7021 } 7022 7023 // Our own process gets to do everything. 7024 if (pid == MY_PID) { 7025 return PackageManager.PERMISSION_GRANTED; 7026 } 7027 synchronized (this) { 7028 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7029 ? PackageManager.PERMISSION_GRANTED 7030 : PackageManager.PERMISSION_DENIED; 7031 } 7032 } 7033 7034 /** 7035 * Check if the targetPkg can be granted permission to access uri by 7036 * the callingUid using the given modeFlags. Throws a security exception 7037 * if callingUid is not allowed to do this. Returns the uid of the target 7038 * if the URI permission grant should be performed; returns -1 if it is not 7039 * needed (for example targetPkg already has permission to access the URI). 7040 * If you already know the uid of the target, you can supply it in 7041 * lastTargetUid else set that to -1. 7042 */ 7043 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7044 final int modeFlags, int lastTargetUid) { 7045 if (!Intent.isAccessUriMode(modeFlags)) { 7046 return -1; 7047 } 7048 7049 if (targetPkg != null) { 7050 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7051 "Checking grant " + targetPkg + " permission to " + grantUri); 7052 } 7053 7054 final IPackageManager pm = AppGlobals.getPackageManager(); 7055 7056 // If this is not a content: uri, we can't do anything with it. 7057 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7059 "Can't grant URI permission for non-content URI: " + grantUri); 7060 return -1; 7061 } 7062 7063 final String authority = grantUri.uri.getAuthority(); 7064 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7065 if (pi == null) { 7066 Slog.w(TAG, "No content provider found for permission check: " + 7067 grantUri.uri.toSafeString()); 7068 return -1; 7069 } 7070 7071 int targetUid = lastTargetUid; 7072 if (targetUid < 0 && targetPkg != null) { 7073 try { 7074 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7075 if (targetUid < 0) { 7076 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7077 "Can't grant URI permission no uid for: " + targetPkg); 7078 return -1; 7079 } 7080 } catch (RemoteException ex) { 7081 return -1; 7082 } 7083 } 7084 7085 if (targetUid >= 0) { 7086 // First... does the target actually need this permission? 7087 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7088 // No need to grant the target this permission. 7089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7090 "Target " + targetPkg + " already has full permission to " + grantUri); 7091 return -1; 7092 } 7093 } else { 7094 // First... there is no target package, so can anyone access it? 7095 boolean allowed = pi.exported; 7096 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7097 if (pi.readPermission != null) { 7098 allowed = false; 7099 } 7100 } 7101 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7102 if (pi.writePermission != null) { 7103 allowed = false; 7104 } 7105 } 7106 if (allowed) { 7107 return -1; 7108 } 7109 } 7110 7111 /* There is a special cross user grant if: 7112 * - The target is on another user. 7113 * - Apps on the current user can access the uri without any uid permissions. 7114 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7115 * grant uri permissions. 7116 */ 7117 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7118 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7119 modeFlags, false /*without considering the uid permissions*/); 7120 7121 // Second... is the provider allowing granting of URI permissions? 7122 if (!specialCrossUserGrant) { 7123 if (!pi.grantUriPermissions) { 7124 throw new SecurityException("Provider " + pi.packageName 7125 + "/" + pi.name 7126 + " does not allow granting of Uri permissions (uri " 7127 + grantUri + ")"); 7128 } 7129 if (pi.uriPermissionPatterns != null) { 7130 final int N = pi.uriPermissionPatterns.length; 7131 boolean allowed = false; 7132 for (int i=0; i<N; i++) { 7133 if (pi.uriPermissionPatterns[i] != null 7134 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7135 allowed = true; 7136 break; 7137 } 7138 } 7139 if (!allowed) { 7140 throw new SecurityException("Provider " + pi.packageName 7141 + "/" + pi.name 7142 + " does not allow granting of permission to path of Uri " 7143 + grantUri); 7144 } 7145 } 7146 } 7147 7148 // Third... does the caller itself have permission to access 7149 // this uri? 7150 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7151 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7152 // Require they hold a strong enough Uri permission 7153 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7154 throw new SecurityException("Uid " + callingUid 7155 + " does not have permission to uri " + grantUri); 7156 } 7157 } 7158 } 7159 return targetUid; 7160 } 7161 7162 /** 7163 * @param uri This uri must NOT contain an embedded userId. 7164 * @param userId The userId in which the uri is to be resolved. 7165 */ 7166 @Override 7167 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7168 final int modeFlags, int userId) { 7169 enforceNotIsolatedCaller("checkGrantUriPermission"); 7170 synchronized(this) { 7171 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7172 new GrantUri(userId, uri, false), modeFlags, -1); 7173 } 7174 } 7175 7176 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7177 final int modeFlags, UriPermissionOwner owner) { 7178 if (!Intent.isAccessUriMode(modeFlags)) { 7179 return; 7180 } 7181 7182 // So here we are: the caller has the assumed permission 7183 // to the uri, and the target doesn't. Let's now give this to 7184 // the target. 7185 7186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7187 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7188 7189 final String authority = grantUri.uri.getAuthority(); 7190 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7191 if (pi == null) { 7192 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7193 return; 7194 } 7195 7196 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7197 grantUri.prefix = true; 7198 } 7199 final UriPermission perm = findOrCreateUriPermissionLocked( 7200 pi.packageName, targetPkg, targetUid, grantUri); 7201 perm.grantModes(modeFlags, owner); 7202 } 7203 7204 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7205 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7206 if (targetPkg == null) { 7207 throw new NullPointerException("targetPkg"); 7208 } 7209 int targetUid; 7210 final IPackageManager pm = AppGlobals.getPackageManager(); 7211 try { 7212 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7213 } catch (RemoteException ex) { 7214 return; 7215 } 7216 7217 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7218 targetUid); 7219 if (targetUid < 0) { 7220 return; 7221 } 7222 7223 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7224 owner); 7225 } 7226 7227 static class NeededUriGrants extends ArrayList<GrantUri> { 7228 final String targetPkg; 7229 final int targetUid; 7230 final int flags; 7231 7232 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7233 this.targetPkg = targetPkg; 7234 this.targetUid = targetUid; 7235 this.flags = flags; 7236 } 7237 } 7238 7239 /** 7240 * Like checkGrantUriPermissionLocked, but takes an Intent. 7241 */ 7242 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7243 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7244 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7245 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7246 + " clip=" + (intent != null ? intent.getClipData() : null) 7247 + " from " + intent + "; flags=0x" 7248 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7249 7250 if (targetPkg == null) { 7251 throw new NullPointerException("targetPkg"); 7252 } 7253 7254 if (intent == null) { 7255 return null; 7256 } 7257 Uri data = intent.getData(); 7258 ClipData clip = intent.getClipData(); 7259 if (data == null && clip == null) { 7260 return null; 7261 } 7262 // Default userId for uris in the intent (if they don't specify it themselves) 7263 int contentUserHint = intent.getContentUserHint(); 7264 if (contentUserHint == UserHandle.USER_CURRENT) { 7265 contentUserHint = UserHandle.getUserId(callingUid); 7266 } 7267 final IPackageManager pm = AppGlobals.getPackageManager(); 7268 int targetUid; 7269 if (needed != null) { 7270 targetUid = needed.targetUid; 7271 } else { 7272 try { 7273 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7274 } catch (RemoteException ex) { 7275 return null; 7276 } 7277 if (targetUid < 0) { 7278 if (DEBUG_URI_PERMISSION) { 7279 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7280 + " on user " + targetUserId); 7281 } 7282 return null; 7283 } 7284 } 7285 if (data != null) { 7286 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7287 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7288 targetUid); 7289 if (targetUid > 0) { 7290 if (needed == null) { 7291 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7292 } 7293 needed.add(grantUri); 7294 } 7295 } 7296 if (clip != null) { 7297 for (int i=0; i<clip.getItemCount(); i++) { 7298 Uri uri = clip.getItemAt(i).getUri(); 7299 if (uri != null) { 7300 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7301 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7302 targetUid); 7303 if (targetUid > 0) { 7304 if (needed == null) { 7305 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7306 } 7307 needed.add(grantUri); 7308 } 7309 } else { 7310 Intent clipIntent = clip.getItemAt(i).getIntent(); 7311 if (clipIntent != null) { 7312 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7313 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7314 if (newNeeded != null) { 7315 needed = newNeeded; 7316 } 7317 } 7318 } 7319 } 7320 } 7321 7322 return needed; 7323 } 7324 7325 /** 7326 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7327 */ 7328 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7329 UriPermissionOwner owner) { 7330 if (needed != null) { 7331 for (int i=0; i<needed.size(); i++) { 7332 GrantUri grantUri = needed.get(i); 7333 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7334 grantUri, needed.flags, owner); 7335 } 7336 } 7337 } 7338 7339 void grantUriPermissionFromIntentLocked(int callingUid, 7340 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7341 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7342 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7343 if (needed == null) { 7344 return; 7345 } 7346 7347 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7348 } 7349 7350 /** 7351 * @param uri This uri must NOT contain an embedded userId. 7352 * @param userId The userId in which the uri is to be resolved. 7353 */ 7354 @Override 7355 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7356 final int modeFlags, int userId) { 7357 enforceNotIsolatedCaller("grantUriPermission"); 7358 GrantUri grantUri = new GrantUri(userId, uri, false); 7359 synchronized(this) { 7360 final ProcessRecord r = getRecordForAppLocked(caller); 7361 if (r == null) { 7362 throw new SecurityException("Unable to find app for caller " 7363 + caller 7364 + " when granting permission to uri " + grantUri); 7365 } 7366 if (targetPkg == null) { 7367 throw new IllegalArgumentException("null target"); 7368 } 7369 if (grantUri == null) { 7370 throw new IllegalArgumentException("null uri"); 7371 } 7372 7373 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7374 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7375 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7376 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7377 7378 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7379 UserHandle.getUserId(r.uid)); 7380 } 7381 } 7382 7383 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7384 if (perm.modeFlags == 0) { 7385 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7386 perm.targetUid); 7387 if (perms != null) { 7388 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7389 "Removing " + perm.targetUid + " permission to " + perm.uri); 7390 7391 perms.remove(perm.uri); 7392 if (perms.isEmpty()) { 7393 mGrantedUriPermissions.remove(perm.targetUid); 7394 } 7395 } 7396 } 7397 } 7398 7399 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7400 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7401 7402 final IPackageManager pm = AppGlobals.getPackageManager(); 7403 final String authority = grantUri.uri.getAuthority(); 7404 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7405 if (pi == null) { 7406 Slog.w(TAG, "No content provider found for permission revoke: " 7407 + grantUri.toSafeString()); 7408 return; 7409 } 7410 7411 // Does the caller have this permission on the URI? 7412 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7413 // Right now, if you are not the original owner of the permission, 7414 // you are not allowed to revoke it. 7415 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7416 throw new SecurityException("Uid " + callingUid 7417 + " does not have permission to uri " + grantUri); 7418 //} 7419 } 7420 7421 boolean persistChanged = false; 7422 7423 // Go through all of the permissions and remove any that match. 7424 int N = mGrantedUriPermissions.size(); 7425 for (int i = 0; i < N; i++) { 7426 final int targetUid = mGrantedUriPermissions.keyAt(i); 7427 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7428 7429 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7430 final UriPermission perm = it.next(); 7431 if (perm.uri.sourceUserId == grantUri.sourceUserId 7432 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7433 if (DEBUG_URI_PERMISSION) 7434 Slog.v(TAG, 7435 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7436 persistChanged |= perm.revokeModes( 7437 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7438 if (perm.modeFlags == 0) { 7439 it.remove(); 7440 } 7441 } 7442 } 7443 7444 if (perms.isEmpty()) { 7445 mGrantedUriPermissions.remove(targetUid); 7446 N--; 7447 i--; 7448 } 7449 } 7450 7451 if (persistChanged) { 7452 schedulePersistUriGrants(); 7453 } 7454 } 7455 7456 /** 7457 * @param uri This uri must NOT contain an embedded userId. 7458 * @param userId The userId in which the uri is to be resolved. 7459 */ 7460 @Override 7461 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7462 int userId) { 7463 enforceNotIsolatedCaller("revokeUriPermission"); 7464 synchronized(this) { 7465 final ProcessRecord r = getRecordForAppLocked(caller); 7466 if (r == null) { 7467 throw new SecurityException("Unable to find app for caller " 7468 + caller 7469 + " when revoking permission to uri " + uri); 7470 } 7471 if (uri == null) { 7472 Slog.w(TAG, "revokeUriPermission: null uri"); 7473 return; 7474 } 7475 7476 if (!Intent.isAccessUriMode(modeFlags)) { 7477 return; 7478 } 7479 7480 final IPackageManager pm = AppGlobals.getPackageManager(); 7481 final String authority = uri.getAuthority(); 7482 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7483 if (pi == null) { 7484 Slog.w(TAG, "No content provider found for permission revoke: " 7485 + uri.toSafeString()); 7486 return; 7487 } 7488 7489 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7490 } 7491 } 7492 7493 /** 7494 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7495 * given package. 7496 * 7497 * @param packageName Package name to match, or {@code null} to apply to all 7498 * packages. 7499 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7500 * to all users. 7501 * @param persistable If persistable grants should be removed. 7502 */ 7503 private void removeUriPermissionsForPackageLocked( 7504 String packageName, int userHandle, boolean persistable) { 7505 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7506 throw new IllegalArgumentException("Must narrow by either package or user"); 7507 } 7508 7509 boolean persistChanged = false; 7510 7511 int N = mGrantedUriPermissions.size(); 7512 for (int i = 0; i < N; i++) { 7513 final int targetUid = mGrantedUriPermissions.keyAt(i); 7514 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7515 7516 // Only inspect grants matching user 7517 if (userHandle == UserHandle.USER_ALL 7518 || userHandle == UserHandle.getUserId(targetUid)) { 7519 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7520 final UriPermission perm = it.next(); 7521 7522 // Only inspect grants matching package 7523 if (packageName == null || perm.sourcePkg.equals(packageName) 7524 || perm.targetPkg.equals(packageName)) { 7525 persistChanged |= perm.revokeModes( 7526 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7527 7528 // Only remove when no modes remain; any persisted grants 7529 // will keep this alive. 7530 if (perm.modeFlags == 0) { 7531 it.remove(); 7532 } 7533 } 7534 } 7535 7536 if (perms.isEmpty()) { 7537 mGrantedUriPermissions.remove(targetUid); 7538 N--; 7539 i--; 7540 } 7541 } 7542 } 7543 7544 if (persistChanged) { 7545 schedulePersistUriGrants(); 7546 } 7547 } 7548 7549 @Override 7550 public IBinder newUriPermissionOwner(String name) { 7551 enforceNotIsolatedCaller("newUriPermissionOwner"); 7552 synchronized(this) { 7553 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7554 return owner.getExternalTokenLocked(); 7555 } 7556 } 7557 7558 /** 7559 * @param uri This uri must NOT contain an embedded userId. 7560 * @param sourceUserId The userId in which the uri is to be resolved. 7561 * @param targetUserId The userId of the app that receives the grant. 7562 */ 7563 @Override 7564 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7565 final int modeFlags, int sourceUserId, int targetUserId) { 7566 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7567 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7568 synchronized(this) { 7569 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7570 if (owner == null) { 7571 throw new IllegalArgumentException("Unknown owner: " + token); 7572 } 7573 if (fromUid != Binder.getCallingUid()) { 7574 if (Binder.getCallingUid() != Process.myUid()) { 7575 // Only system code can grant URI permissions on behalf 7576 // of other users. 7577 throw new SecurityException("nice try"); 7578 } 7579 } 7580 if (targetPkg == null) { 7581 throw new IllegalArgumentException("null target"); 7582 } 7583 if (uri == null) { 7584 throw new IllegalArgumentException("null uri"); 7585 } 7586 7587 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7588 modeFlags, owner, targetUserId); 7589 } 7590 } 7591 7592 /** 7593 * @param uri This uri must NOT contain an embedded userId. 7594 * @param userId The userId in which the uri is to be resolved. 7595 */ 7596 @Override 7597 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7598 synchronized(this) { 7599 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7600 if (owner == null) { 7601 throw new IllegalArgumentException("Unknown owner: " + token); 7602 } 7603 7604 if (uri == null) { 7605 owner.removeUriPermissionsLocked(mode); 7606 } else { 7607 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7608 } 7609 } 7610 } 7611 7612 private void schedulePersistUriGrants() { 7613 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7614 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7615 10 * DateUtils.SECOND_IN_MILLIS); 7616 } 7617 } 7618 7619 private void writeGrantedUriPermissions() { 7620 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7621 7622 // Snapshot permissions so we can persist without lock 7623 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7624 synchronized (this) { 7625 final int size = mGrantedUriPermissions.size(); 7626 for (int i = 0; i < size; i++) { 7627 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7628 for (UriPermission perm : perms.values()) { 7629 if (perm.persistedModeFlags != 0) { 7630 persist.add(perm.snapshot()); 7631 } 7632 } 7633 } 7634 } 7635 7636 FileOutputStream fos = null; 7637 try { 7638 fos = mGrantFile.startWrite(); 7639 7640 XmlSerializer out = new FastXmlSerializer(); 7641 out.setOutput(fos, "utf-8"); 7642 out.startDocument(null, true); 7643 out.startTag(null, TAG_URI_GRANTS); 7644 for (UriPermission.Snapshot perm : persist) { 7645 out.startTag(null, TAG_URI_GRANT); 7646 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7647 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7648 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7649 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7650 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7651 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7652 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7653 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7654 out.endTag(null, TAG_URI_GRANT); 7655 } 7656 out.endTag(null, TAG_URI_GRANTS); 7657 out.endDocument(); 7658 7659 mGrantFile.finishWrite(fos); 7660 } catch (IOException e) { 7661 if (fos != null) { 7662 mGrantFile.failWrite(fos); 7663 } 7664 } 7665 } 7666 7667 private void readGrantedUriPermissionsLocked() { 7668 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7669 7670 final long now = System.currentTimeMillis(); 7671 7672 FileInputStream fis = null; 7673 try { 7674 fis = mGrantFile.openRead(); 7675 final XmlPullParser in = Xml.newPullParser(); 7676 in.setInput(fis, null); 7677 7678 int type; 7679 while ((type = in.next()) != END_DOCUMENT) { 7680 final String tag = in.getName(); 7681 if (type == START_TAG) { 7682 if (TAG_URI_GRANT.equals(tag)) { 7683 final int sourceUserId; 7684 final int targetUserId; 7685 final int userHandle = readIntAttribute(in, 7686 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7687 if (userHandle != UserHandle.USER_NULL) { 7688 // For backwards compatibility. 7689 sourceUserId = userHandle; 7690 targetUserId = userHandle; 7691 } else { 7692 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7693 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7694 } 7695 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7696 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7697 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7698 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7699 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7700 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7701 7702 // Sanity check that provider still belongs to source package 7703 final ProviderInfo pi = getProviderInfoLocked( 7704 uri.getAuthority(), sourceUserId); 7705 if (pi != null && sourcePkg.equals(pi.packageName)) { 7706 int targetUid = -1; 7707 try { 7708 targetUid = AppGlobals.getPackageManager() 7709 .getPackageUid(targetPkg, targetUserId); 7710 } catch (RemoteException e) { 7711 } 7712 if (targetUid != -1) { 7713 final UriPermission perm = findOrCreateUriPermissionLocked( 7714 sourcePkg, targetPkg, targetUid, 7715 new GrantUri(sourceUserId, uri, prefix)); 7716 perm.initPersistedModes(modeFlags, createdTime); 7717 } 7718 } else { 7719 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7720 + " but instead found " + pi); 7721 } 7722 } 7723 } 7724 } 7725 } catch (FileNotFoundException e) { 7726 // Missing grants is okay 7727 } catch (IOException e) { 7728 Log.wtf(TAG, "Failed reading Uri grants", e); 7729 } catch (XmlPullParserException e) { 7730 Log.wtf(TAG, "Failed reading Uri grants", e); 7731 } finally { 7732 IoUtils.closeQuietly(fis); 7733 } 7734 } 7735 7736 /** 7737 * @param uri This uri must NOT contain an embedded userId. 7738 * @param userId The userId in which the uri is to be resolved. 7739 */ 7740 @Override 7741 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7742 enforceNotIsolatedCaller("takePersistableUriPermission"); 7743 7744 Preconditions.checkFlagsArgument(modeFlags, 7745 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7746 7747 synchronized (this) { 7748 final int callingUid = Binder.getCallingUid(); 7749 boolean persistChanged = false; 7750 GrantUri grantUri = new GrantUri(userId, uri, false); 7751 7752 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7753 new GrantUri(userId, uri, false)); 7754 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7755 new GrantUri(userId, uri, true)); 7756 7757 final boolean exactValid = (exactPerm != null) 7758 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7759 final boolean prefixValid = (prefixPerm != null) 7760 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7761 7762 if (!(exactValid || prefixValid)) { 7763 throw new SecurityException("No persistable permission grants found for UID " 7764 + callingUid + " and Uri " + grantUri.toSafeString()); 7765 } 7766 7767 if (exactValid) { 7768 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7769 } 7770 if (prefixValid) { 7771 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7772 } 7773 7774 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7775 7776 if (persistChanged) { 7777 schedulePersistUriGrants(); 7778 } 7779 } 7780 } 7781 7782 /** 7783 * @param uri This uri must NOT contain an embedded userId. 7784 * @param userId The userId in which the uri is to be resolved. 7785 */ 7786 @Override 7787 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7788 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7789 7790 Preconditions.checkFlagsArgument(modeFlags, 7791 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7792 7793 synchronized (this) { 7794 final int callingUid = Binder.getCallingUid(); 7795 boolean persistChanged = false; 7796 7797 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7798 new GrantUri(userId, uri, false)); 7799 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7800 new GrantUri(userId, uri, true)); 7801 if (exactPerm == null && prefixPerm == null) { 7802 throw new SecurityException("No permission grants found for UID " + callingUid 7803 + " and Uri " + uri.toSafeString()); 7804 } 7805 7806 if (exactPerm != null) { 7807 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7808 removeUriPermissionIfNeededLocked(exactPerm); 7809 } 7810 if (prefixPerm != null) { 7811 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7812 removeUriPermissionIfNeededLocked(prefixPerm); 7813 } 7814 7815 if (persistChanged) { 7816 schedulePersistUriGrants(); 7817 } 7818 } 7819 } 7820 7821 /** 7822 * Prune any older {@link UriPermission} for the given UID until outstanding 7823 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7824 * 7825 * @return if any mutations occured that require persisting. 7826 */ 7827 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7828 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7829 if (perms == null) return false; 7830 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7831 7832 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7833 for (UriPermission perm : perms.values()) { 7834 if (perm.persistedModeFlags != 0) { 7835 persisted.add(perm); 7836 } 7837 } 7838 7839 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7840 if (trimCount <= 0) return false; 7841 7842 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7843 for (int i = 0; i < trimCount; i++) { 7844 final UriPermission perm = persisted.get(i); 7845 7846 if (DEBUG_URI_PERMISSION) { 7847 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7848 } 7849 7850 perm.releasePersistableModes(~0); 7851 removeUriPermissionIfNeededLocked(perm); 7852 } 7853 7854 return true; 7855 } 7856 7857 @Override 7858 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7859 String packageName, boolean incoming) { 7860 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7861 Preconditions.checkNotNull(packageName, "packageName"); 7862 7863 final int callingUid = Binder.getCallingUid(); 7864 final IPackageManager pm = AppGlobals.getPackageManager(); 7865 try { 7866 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7867 if (packageUid != callingUid) { 7868 throw new SecurityException( 7869 "Package " + packageName + " does not belong to calling UID " + callingUid); 7870 } 7871 } catch (RemoteException e) { 7872 throw new SecurityException("Failed to verify package name ownership"); 7873 } 7874 7875 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7876 synchronized (this) { 7877 if (incoming) { 7878 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7879 callingUid); 7880 if (perms == null) { 7881 Slog.w(TAG, "No permission grants found for " + packageName); 7882 } else { 7883 for (UriPermission perm : perms.values()) { 7884 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7885 result.add(perm.buildPersistedPublicApiObject()); 7886 } 7887 } 7888 } 7889 } else { 7890 final int size = mGrantedUriPermissions.size(); 7891 for (int i = 0; i < size; i++) { 7892 final ArrayMap<GrantUri, UriPermission> perms = 7893 mGrantedUriPermissions.valueAt(i); 7894 for (UriPermission perm : perms.values()) { 7895 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7896 result.add(perm.buildPersistedPublicApiObject()); 7897 } 7898 } 7899 } 7900 } 7901 } 7902 return new ParceledListSlice<android.content.UriPermission>(result); 7903 } 7904 7905 @Override 7906 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7907 synchronized (this) { 7908 ProcessRecord app = 7909 who != null ? getRecordForAppLocked(who) : null; 7910 if (app == null) return; 7911 7912 Message msg = Message.obtain(); 7913 msg.what = WAIT_FOR_DEBUGGER_MSG; 7914 msg.obj = app; 7915 msg.arg1 = waiting ? 1 : 0; 7916 mHandler.sendMessage(msg); 7917 } 7918 } 7919 7920 @Override 7921 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7922 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7923 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7924 outInfo.availMem = Process.getFreeMemory(); 7925 outInfo.totalMem = Process.getTotalMemory(); 7926 outInfo.threshold = homeAppMem; 7927 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7928 outInfo.hiddenAppThreshold = cachedAppMem; 7929 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7930 ProcessList.SERVICE_ADJ); 7931 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7932 ProcessList.VISIBLE_APP_ADJ); 7933 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7934 ProcessList.FOREGROUND_APP_ADJ); 7935 } 7936 7937 // ========================================================= 7938 // TASK MANAGEMENT 7939 // ========================================================= 7940 7941 @Override 7942 public List<IAppTask> getAppTasks(String callingPackage) { 7943 int callingUid = Binder.getCallingUid(); 7944 long ident = Binder.clearCallingIdentity(); 7945 7946 synchronized(this) { 7947 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7948 try { 7949 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7950 7951 final int N = mRecentTasks.size(); 7952 for (int i = 0; i < N; i++) { 7953 TaskRecord tr = mRecentTasks.get(i); 7954 // Skip tasks that do not match the caller. We don't need to verify 7955 // callingPackage, because we are also limiting to callingUid and know 7956 // that will limit to the correct security sandbox. 7957 if (tr.effectiveUid != callingUid) { 7958 continue; 7959 } 7960 Intent intent = tr.getBaseIntent(); 7961 if (intent == null || 7962 !callingPackage.equals(intent.getComponent().getPackageName())) { 7963 continue; 7964 } 7965 ActivityManager.RecentTaskInfo taskInfo = 7966 createRecentTaskInfoFromTaskRecord(tr); 7967 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7968 list.add(taskImpl); 7969 } 7970 } finally { 7971 Binder.restoreCallingIdentity(ident); 7972 } 7973 return list; 7974 } 7975 } 7976 7977 @Override 7978 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7979 final int callingUid = Binder.getCallingUid(); 7980 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7981 7982 synchronized(this) { 7983 if (localLOGV) Slog.v( 7984 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7985 7986 final boolean allowed = checkCallingPermission( 7987 android.Manifest.permission.GET_TASKS) 7988 == PackageManager.PERMISSION_GRANTED; 7989 if (!allowed) { 7990 Slog.w(TAG, "getTasks: caller " + callingUid 7991 + " does not hold GET_TASKS; limiting output"); 7992 } 7993 7994 // TODO: Improve with MRU list from all ActivityStacks. 7995 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7996 } 7997 7998 return list; 7999 } 8000 8001 TaskRecord getMostRecentTask() { 8002 return mRecentTasks.get(0); 8003 } 8004 8005 /** 8006 * Creates a new RecentTaskInfo from a TaskRecord. 8007 */ 8008 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8009 // Update the task description to reflect any changes in the task stack 8010 tr.updateTaskDescription(); 8011 8012 // Compose the recent task info 8013 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8014 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8015 rti.persistentId = tr.taskId; 8016 rti.baseIntent = new Intent(tr.getBaseIntent()); 8017 rti.origActivity = tr.origActivity; 8018 rti.description = tr.lastDescription; 8019 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8020 rti.userId = tr.userId; 8021 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8022 rti.firstActiveTime = tr.firstActiveTime; 8023 rti.lastActiveTime = tr.lastActiveTime; 8024 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8025 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8026 return rti; 8027 } 8028 8029 @Override 8030 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8031 final int callingUid = Binder.getCallingUid(); 8032 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8033 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8034 8035 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8036 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8037 synchronized (this) { 8038 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8039 == PackageManager.PERMISSION_GRANTED; 8040 if (!allowed) { 8041 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8042 + " does not hold GET_TASKS; limiting output"); 8043 } 8044 final boolean detailed = checkCallingPermission( 8045 android.Manifest.permission.GET_DETAILED_TASKS) 8046 == PackageManager.PERMISSION_GRANTED; 8047 8048 final int N = mRecentTasks.size(); 8049 ArrayList<ActivityManager.RecentTaskInfo> res 8050 = new ArrayList<ActivityManager.RecentTaskInfo>( 8051 maxNum < N ? maxNum : N); 8052 8053 final Set<Integer> includedUsers; 8054 if (includeProfiles) { 8055 includedUsers = getProfileIdsLocked(userId); 8056 } else { 8057 includedUsers = new HashSet<Integer>(); 8058 } 8059 includedUsers.add(Integer.valueOf(userId)); 8060 8061 for (int i=0; i<N && maxNum > 0; i++) { 8062 TaskRecord tr = mRecentTasks.get(i); 8063 // Only add calling user or related users recent tasks 8064 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8065 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8066 continue; 8067 } 8068 8069 // Return the entry if desired by the caller. We always return 8070 // the first entry, because callers always expect this to be the 8071 // foreground app. We may filter others if the caller has 8072 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8073 // we should exclude the entry. 8074 8075 if (i == 0 8076 || withExcluded 8077 || (tr.intent == null) 8078 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8079 == 0)) { 8080 if (!allowed) { 8081 // If the caller doesn't have the GET_TASKS permission, then only 8082 // allow them to see a small subset of tasks -- their own and home. 8083 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8084 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8085 continue; 8086 } 8087 } 8088 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8089 if (tr.stack != null && tr.stack.isHomeStack()) { 8090 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8091 continue; 8092 } 8093 } 8094 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8095 // Don't include auto remove tasks that are finished or finishing. 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8097 + tr); 8098 continue; 8099 } 8100 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8101 && !tr.isAvailable) { 8102 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8103 continue; 8104 } 8105 8106 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8107 if (!detailed) { 8108 rti.baseIntent.replaceExtras((Bundle)null); 8109 } 8110 8111 res.add(rti); 8112 maxNum--; 8113 } 8114 } 8115 return res; 8116 } 8117 } 8118 8119 private TaskRecord recentTaskForIdLocked(int id) { 8120 final int N = mRecentTasks.size(); 8121 for (int i=0; i<N; i++) { 8122 TaskRecord tr = mRecentTasks.get(i); 8123 if (tr.taskId == id) { 8124 return tr; 8125 } 8126 } 8127 return null; 8128 } 8129 8130 @Override 8131 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8132 synchronized (this) { 8133 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8134 "getTaskThumbnail()"); 8135 TaskRecord tr = recentTaskForIdLocked(id); 8136 if (tr != null) { 8137 return tr.getTaskThumbnailLocked(); 8138 } 8139 } 8140 return null; 8141 } 8142 8143 @Override 8144 public int addAppTask(IBinder activityToken, Intent intent, 8145 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8146 final int callingUid = Binder.getCallingUid(); 8147 final long callingIdent = Binder.clearCallingIdentity(); 8148 8149 try { 8150 synchronized (this) { 8151 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8152 if (r == null) { 8153 throw new IllegalArgumentException("Activity does not exist; token=" 8154 + activityToken); 8155 } 8156 ComponentName comp = intent.getComponent(); 8157 if (comp == null) { 8158 throw new IllegalArgumentException("Intent " + intent 8159 + " must specify explicit component"); 8160 } 8161 if (thumbnail.getWidth() != mThumbnailWidth 8162 || thumbnail.getHeight() != mThumbnailHeight) { 8163 throw new IllegalArgumentException("Bad thumbnail size: got " 8164 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8165 + mThumbnailWidth + "x" + mThumbnailHeight); 8166 } 8167 if (intent.getSelector() != null) { 8168 intent.setSelector(null); 8169 } 8170 if (intent.getSourceBounds() != null) { 8171 intent.setSourceBounds(null); 8172 } 8173 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8174 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8175 // The caller has added this as an auto-remove task... that makes no 8176 // sense, so turn off auto-remove. 8177 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8178 } 8179 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8180 // Must be a new task. 8181 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8182 } 8183 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8184 mLastAddedTaskActivity = null; 8185 } 8186 ActivityInfo ainfo = mLastAddedTaskActivity; 8187 if (ainfo == null) { 8188 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8189 comp, 0, UserHandle.getUserId(callingUid)); 8190 if (ainfo.applicationInfo.uid != callingUid) { 8191 throw new SecurityException( 8192 "Can't add task for another application: target uid=" 8193 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8194 } 8195 } 8196 8197 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8198 intent, description); 8199 8200 int trimIdx = trimRecentsForTask(task, false); 8201 if (trimIdx >= 0) { 8202 // If this would have caused a trim, then we'll abort because that 8203 // means it would be added at the end of the list but then just removed. 8204 return -1; 8205 } 8206 8207 final int N = mRecentTasks.size(); 8208 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8209 final TaskRecord tr = mRecentTasks.remove(N - 1); 8210 tr.removedFromRecents(mTaskPersister); 8211 } 8212 8213 task.inRecents = true; 8214 mRecentTasks.add(task); 8215 r.task.stack.addTask(task, false, false); 8216 8217 task.setLastThumbnail(thumbnail); 8218 task.freeLastThumbnail(); 8219 8220 return task.taskId; 8221 } 8222 } finally { 8223 Binder.restoreCallingIdentity(callingIdent); 8224 } 8225 } 8226 8227 @Override 8228 public Point getAppTaskThumbnailSize() { 8229 synchronized (this) { 8230 return new Point(mThumbnailWidth, mThumbnailHeight); 8231 } 8232 } 8233 8234 @Override 8235 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8236 synchronized (this) { 8237 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8238 if (r != null) { 8239 r.taskDescription = td; 8240 r.task.updateTaskDescription(); 8241 } 8242 } 8243 } 8244 8245 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8246 mRecentTasks.remove(tr); 8247 tr.removedFromRecents(mTaskPersister); 8248 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8249 Intent baseIntent = new Intent( 8250 tr.intent != null ? tr.intent : tr.affinityIntent); 8251 ComponentName component = baseIntent.getComponent(); 8252 if (component == null) { 8253 Slog.w(TAG, "Now component for base intent of task: " + tr); 8254 return; 8255 } 8256 8257 // Find any running services associated with this app. 8258 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8259 8260 if (killProcesses) { 8261 // Find any running processes associated with this app. 8262 final String pkg = component.getPackageName(); 8263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8264 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8265 for (int i=0; i<pmap.size(); i++) { 8266 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8267 for (int j=0; j<uids.size(); j++) { 8268 ProcessRecord proc = uids.valueAt(j); 8269 if (proc.userId != tr.userId) { 8270 continue; 8271 } 8272 if (!proc.pkgList.containsKey(pkg)) { 8273 continue; 8274 } 8275 procs.add(proc); 8276 } 8277 } 8278 8279 // Kill the running processes. 8280 for (int i=0; i<procs.size(); i++) { 8281 ProcessRecord pr = procs.get(i); 8282 if (pr == mHomeProcess) { 8283 // Don't kill the home process along with tasks from the same package. 8284 continue; 8285 } 8286 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8287 pr.kill("remove task", true); 8288 } else { 8289 pr.waitingToKill = "remove task"; 8290 } 8291 } 8292 } 8293 } 8294 8295 /** 8296 * Removes the task with the specified task id. 8297 * 8298 * @param taskId Identifier of the task to be removed. 8299 * @param flags Additional operational flags. May be 0 or 8300 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8301 * @return Returns true if the given task was found and removed. 8302 */ 8303 private boolean removeTaskByIdLocked(int taskId, int flags) { 8304 TaskRecord tr = recentTaskForIdLocked(taskId); 8305 if (tr != null) { 8306 tr.removeTaskActivitiesLocked(); 8307 cleanUpRemovedTaskLocked(tr, flags); 8308 if (tr.isPersistable) { 8309 notifyTaskPersisterLocked(null, true); 8310 } 8311 return true; 8312 } 8313 return false; 8314 } 8315 8316 @Override 8317 public boolean removeTask(int taskId, int flags) { 8318 synchronized (this) { 8319 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8320 "removeTask()"); 8321 long ident = Binder.clearCallingIdentity(); 8322 try { 8323 return removeTaskByIdLocked(taskId, flags); 8324 } finally { 8325 Binder.restoreCallingIdentity(ident); 8326 } 8327 } 8328 } 8329 8330 /** 8331 * TODO: Add mController hook 8332 */ 8333 @Override 8334 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8335 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8336 "moveTaskToFront()"); 8337 8338 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8339 synchronized(this) { 8340 moveTaskToFrontLocked(taskId, flags, options); 8341 } 8342 } 8343 8344 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8345 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8346 Binder.getCallingUid(), "Task to front")) { 8347 ActivityOptions.abort(options); 8348 return; 8349 } 8350 final long origId = Binder.clearCallingIdentity(); 8351 try { 8352 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8353 if (task == null) { 8354 return; 8355 } 8356 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8357 mStackSupervisor.showLockTaskToast(); 8358 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8359 return; 8360 } 8361 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8362 if (prev != null && prev.isRecentsActivity()) { 8363 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8364 } 8365 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8366 } finally { 8367 Binder.restoreCallingIdentity(origId); 8368 } 8369 ActivityOptions.abort(options); 8370 } 8371 8372 @Override 8373 public void moveTaskToBack(int taskId) { 8374 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8375 "moveTaskToBack()"); 8376 8377 synchronized(this) { 8378 TaskRecord tr = recentTaskForIdLocked(taskId); 8379 if (tr != null) { 8380 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8381 ActivityStack stack = tr.stack; 8382 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8383 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8384 Binder.getCallingUid(), "Task to back")) { 8385 return; 8386 } 8387 } 8388 final long origId = Binder.clearCallingIdentity(); 8389 try { 8390 stack.moveTaskToBackLocked(taskId, null); 8391 } finally { 8392 Binder.restoreCallingIdentity(origId); 8393 } 8394 } 8395 } 8396 } 8397 8398 /** 8399 * Moves an activity, and all of the other activities within the same task, to the bottom 8400 * of the history stack. The activity's order within the task is unchanged. 8401 * 8402 * @param token A reference to the activity we wish to move 8403 * @param nonRoot If false then this only works if the activity is the root 8404 * of a task; if true it will work for any activity in a task. 8405 * @return Returns true if the move completed, false if not. 8406 */ 8407 @Override 8408 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8409 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8410 synchronized(this) { 8411 final long origId = Binder.clearCallingIdentity(); 8412 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8413 if (taskId >= 0) { 8414 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8415 } 8416 Binder.restoreCallingIdentity(origId); 8417 } 8418 return false; 8419 } 8420 8421 @Override 8422 public void moveTaskBackwards(int task) { 8423 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8424 "moveTaskBackwards()"); 8425 8426 synchronized(this) { 8427 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8428 Binder.getCallingUid(), "Task backwards")) { 8429 return; 8430 } 8431 final long origId = Binder.clearCallingIdentity(); 8432 moveTaskBackwardsLocked(task); 8433 Binder.restoreCallingIdentity(origId); 8434 } 8435 } 8436 8437 private final void moveTaskBackwardsLocked(int task) { 8438 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8439 } 8440 8441 @Override 8442 public IBinder getHomeActivityToken() throws RemoteException { 8443 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8444 "getHomeActivityToken()"); 8445 synchronized (this) { 8446 return mStackSupervisor.getHomeActivityToken(); 8447 } 8448 } 8449 8450 @Override 8451 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8452 IActivityContainerCallback callback) throws RemoteException { 8453 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8454 "createActivityContainer()"); 8455 synchronized (this) { 8456 if (parentActivityToken == null) { 8457 throw new IllegalArgumentException("parent token must not be null"); 8458 } 8459 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8460 if (r == null) { 8461 return null; 8462 } 8463 if (callback == null) { 8464 throw new IllegalArgumentException("callback must not be null"); 8465 } 8466 return mStackSupervisor.createActivityContainer(r, callback); 8467 } 8468 } 8469 8470 @Override 8471 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8472 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8473 "deleteActivityContainer()"); 8474 synchronized (this) { 8475 mStackSupervisor.deleteActivityContainer(container); 8476 } 8477 } 8478 8479 @Override 8480 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8481 throws RemoteException { 8482 synchronized (this) { 8483 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8484 if (stack != null) { 8485 return stack.mActivityContainer; 8486 } 8487 return null; 8488 } 8489 } 8490 8491 @Override 8492 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8493 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8494 "moveTaskToStack()"); 8495 if (stackId == HOME_STACK_ID) { 8496 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8497 new RuntimeException("here").fillInStackTrace()); 8498 } 8499 synchronized (this) { 8500 long ident = Binder.clearCallingIdentity(); 8501 try { 8502 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8503 + stackId + " toTop=" + toTop); 8504 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8505 } finally { 8506 Binder.restoreCallingIdentity(ident); 8507 } 8508 } 8509 } 8510 8511 @Override 8512 public void resizeStack(int stackBoxId, Rect bounds) { 8513 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8514 "resizeStackBox()"); 8515 long ident = Binder.clearCallingIdentity(); 8516 try { 8517 mWindowManager.resizeStack(stackBoxId, bounds); 8518 } finally { 8519 Binder.restoreCallingIdentity(ident); 8520 } 8521 } 8522 8523 @Override 8524 public List<StackInfo> getAllStackInfos() { 8525 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8526 "getAllStackInfos()"); 8527 long ident = Binder.clearCallingIdentity(); 8528 try { 8529 synchronized (this) { 8530 return mStackSupervisor.getAllStackInfosLocked(); 8531 } 8532 } finally { 8533 Binder.restoreCallingIdentity(ident); 8534 } 8535 } 8536 8537 @Override 8538 public StackInfo getStackInfo(int stackId) { 8539 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8540 "getStackInfo()"); 8541 long ident = Binder.clearCallingIdentity(); 8542 try { 8543 synchronized (this) { 8544 return mStackSupervisor.getStackInfoLocked(stackId); 8545 } 8546 } finally { 8547 Binder.restoreCallingIdentity(ident); 8548 } 8549 } 8550 8551 @Override 8552 public boolean isInHomeStack(int taskId) { 8553 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8554 "getStackInfo()"); 8555 long ident = Binder.clearCallingIdentity(); 8556 try { 8557 synchronized (this) { 8558 TaskRecord tr = recentTaskForIdLocked(taskId); 8559 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8560 } 8561 } finally { 8562 Binder.restoreCallingIdentity(ident); 8563 } 8564 } 8565 8566 @Override 8567 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8568 synchronized(this) { 8569 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8570 } 8571 } 8572 8573 private boolean isLockTaskAuthorized(String pkg) { 8574 final DevicePolicyManager dpm = (DevicePolicyManager) 8575 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8576 try { 8577 int uid = mContext.getPackageManager().getPackageUid(pkg, 8578 Binder.getCallingUserHandle().getIdentifier()); 8579 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8580 } catch (NameNotFoundException e) { 8581 return false; 8582 } 8583 } 8584 8585 void startLockTaskMode(TaskRecord task) { 8586 final String pkg; 8587 synchronized (this) { 8588 pkg = task.intent.getComponent().getPackageName(); 8589 } 8590 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8591 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8592 final TaskRecord taskRecord = task; 8593 mHandler.post(new Runnable() { 8594 @Override 8595 public void run() { 8596 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8597 } 8598 }); 8599 return; 8600 } 8601 long ident = Binder.clearCallingIdentity(); 8602 try { 8603 synchronized (this) { 8604 // Since we lost lock on task, make sure it is still there. 8605 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8606 if (task != null) { 8607 if (!isSystemInitiated 8608 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8609 throw new IllegalArgumentException("Invalid task, not in foreground"); 8610 } 8611 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8612 } 8613 } 8614 } finally { 8615 Binder.restoreCallingIdentity(ident); 8616 } 8617 } 8618 8619 @Override 8620 public void startLockTaskMode(int taskId) { 8621 final TaskRecord task; 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8626 } 8627 } finally { 8628 Binder.restoreCallingIdentity(ident); 8629 } 8630 if (task != null) { 8631 startLockTaskMode(task); 8632 } 8633 } 8634 8635 @Override 8636 public void startLockTaskMode(IBinder token) { 8637 final TaskRecord task; 8638 long ident = Binder.clearCallingIdentity(); 8639 try { 8640 synchronized (this) { 8641 final ActivityRecord r = ActivityRecord.forToken(token); 8642 if (r == null) { 8643 return; 8644 } 8645 task = r.task; 8646 } 8647 } finally { 8648 Binder.restoreCallingIdentity(ident); 8649 } 8650 if (task != null) { 8651 startLockTaskMode(task); 8652 } 8653 } 8654 8655 @Override 8656 public void startLockTaskModeOnCurrent() throws RemoteException { 8657 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8658 ActivityRecord r = null; 8659 synchronized (this) { 8660 r = mStackSupervisor.topRunningActivityLocked(); 8661 } 8662 startLockTaskMode(r.task); 8663 } 8664 8665 @Override 8666 public void stopLockTaskMode() { 8667 // Verify that the user matches the package of the intent for the TaskRecord 8668 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8669 // and stopLockTaskMode. 8670 final int callingUid = Binder.getCallingUid(); 8671 if (callingUid != Process.SYSTEM_UID) { 8672 try { 8673 String pkg = 8674 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8675 int uid = mContext.getPackageManager().getPackageUid(pkg, 8676 Binder.getCallingUserHandle().getIdentifier()); 8677 if (uid != callingUid) { 8678 throw new SecurityException("Invalid uid, expected " + uid); 8679 } 8680 } catch (NameNotFoundException e) { 8681 Log.d(TAG, "stopLockTaskMode " + e); 8682 return; 8683 } 8684 } 8685 long ident = Binder.clearCallingIdentity(); 8686 try { 8687 Log.d(TAG, "stopLockTaskMode"); 8688 // Stop lock task 8689 synchronized (this) { 8690 mStackSupervisor.setLockTaskModeLocked(null, false); 8691 } 8692 } finally { 8693 Binder.restoreCallingIdentity(ident); 8694 } 8695 } 8696 8697 @Override 8698 public void stopLockTaskModeOnCurrent() throws RemoteException { 8699 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8700 long ident = Binder.clearCallingIdentity(); 8701 try { 8702 stopLockTaskMode(); 8703 } finally { 8704 Binder.restoreCallingIdentity(ident); 8705 } 8706 } 8707 8708 @Override 8709 public boolean isInLockTaskMode() { 8710 synchronized (this) { 8711 return mStackSupervisor.isInLockTaskMode(); 8712 } 8713 } 8714 8715 // ========================================================= 8716 // CONTENT PROVIDERS 8717 // ========================================================= 8718 8719 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8720 List<ProviderInfo> providers = null; 8721 try { 8722 providers = AppGlobals.getPackageManager(). 8723 queryContentProviders(app.processName, app.uid, 8724 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8725 } catch (RemoteException ex) { 8726 } 8727 if (DEBUG_MU) 8728 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8729 int userId = app.userId; 8730 if (providers != null) { 8731 int N = providers.size(); 8732 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8733 for (int i=0; i<N; i++) { 8734 ProviderInfo cpi = 8735 (ProviderInfo)providers.get(i); 8736 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8737 cpi.name, cpi.flags); 8738 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8739 // This is a singleton provider, but a user besides the 8740 // default user is asking to initialize a process it runs 8741 // in... well, no, it doesn't actually run in this process, 8742 // it runs in the process of the default user. Get rid of it. 8743 providers.remove(i); 8744 N--; 8745 i--; 8746 continue; 8747 } 8748 8749 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8750 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8751 if (cpr == null) { 8752 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8753 mProviderMap.putProviderByClass(comp, cpr); 8754 } 8755 if (DEBUG_MU) 8756 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8757 app.pubProviders.put(cpi.name, cpr); 8758 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8759 // Don't add this if it is a platform component that is marked 8760 // to run in multiple processes, because this is actually 8761 // part of the framework so doesn't make sense to track as a 8762 // separate apk in the process. 8763 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8764 mProcessStats); 8765 } 8766 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8767 } 8768 } 8769 return providers; 8770 } 8771 8772 /** 8773 * Check if {@link ProcessRecord} has a possible chance at accessing the 8774 * given {@link ProviderInfo}. Final permission checking is always done 8775 * in {@link ContentProvider}. 8776 */ 8777 private final String checkContentProviderPermissionLocked( 8778 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8779 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8780 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8781 boolean checkedGrants = false; 8782 if (checkUser) { 8783 // Looking for cross-user grants before enforcing the typical cross-users permissions 8784 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8785 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8786 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8787 return null; 8788 } 8789 checkedGrants = true; 8790 } 8791 userId = handleIncomingUser(callingPid, callingUid, userId, 8792 false, ALLOW_NON_FULL, 8793 "checkContentProviderPermissionLocked " + cpi.authority, null); 8794 if (userId != tmpTargetUserId) { 8795 // When we actually went to determine the final targer user ID, this ended 8796 // up different than our initial check for the authority. This is because 8797 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8798 // SELF. So we need to re-check the grants again. 8799 checkedGrants = false; 8800 } 8801 } 8802 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8803 cpi.applicationInfo.uid, cpi.exported) 8804 == PackageManager.PERMISSION_GRANTED) { 8805 return null; 8806 } 8807 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8808 cpi.applicationInfo.uid, cpi.exported) 8809 == PackageManager.PERMISSION_GRANTED) { 8810 return null; 8811 } 8812 8813 PathPermission[] pps = cpi.pathPermissions; 8814 if (pps != null) { 8815 int i = pps.length; 8816 while (i > 0) { 8817 i--; 8818 PathPermission pp = pps[i]; 8819 String pprperm = pp.getReadPermission(); 8820 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8821 cpi.applicationInfo.uid, cpi.exported) 8822 == PackageManager.PERMISSION_GRANTED) { 8823 return null; 8824 } 8825 String ppwperm = pp.getWritePermission(); 8826 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8827 cpi.applicationInfo.uid, cpi.exported) 8828 == PackageManager.PERMISSION_GRANTED) { 8829 return null; 8830 } 8831 } 8832 } 8833 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8834 return null; 8835 } 8836 8837 String msg; 8838 if (!cpi.exported) { 8839 msg = "Permission Denial: opening provider " + cpi.name 8840 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8841 + ", uid=" + callingUid + ") that is not exported from uid " 8842 + cpi.applicationInfo.uid; 8843 } else { 8844 msg = "Permission Denial: opening provider " + cpi.name 8845 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8846 + ", uid=" + callingUid + ") requires " 8847 + cpi.readPermission + " or " + cpi.writePermission; 8848 } 8849 Slog.w(TAG, msg); 8850 return msg; 8851 } 8852 8853 /** 8854 * Returns if the ContentProvider has granted a uri to callingUid 8855 */ 8856 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8858 if (perms != null) { 8859 for (int i=perms.size()-1; i>=0; i--) { 8860 GrantUri grantUri = perms.keyAt(i); 8861 if (grantUri.sourceUserId == userId || !checkUser) { 8862 if (matchesProvider(grantUri.uri, cpi)) { 8863 return true; 8864 } 8865 } 8866 } 8867 } 8868 return false; 8869 } 8870 8871 /** 8872 * Returns true if the uri authority is one of the authorities specified in the provider. 8873 */ 8874 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8875 String uriAuth = uri.getAuthority(); 8876 String cpiAuth = cpi.authority; 8877 if (cpiAuth.indexOf(';') == -1) { 8878 return cpiAuth.equals(uriAuth); 8879 } 8880 String[] cpiAuths = cpiAuth.split(";"); 8881 int length = cpiAuths.length; 8882 for (int i = 0; i < length; i++) { 8883 if (cpiAuths[i].equals(uriAuth)) return true; 8884 } 8885 return false; 8886 } 8887 8888 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8889 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8890 if (r != null) { 8891 for (int i=0; i<r.conProviders.size(); i++) { 8892 ContentProviderConnection conn = r.conProviders.get(i); 8893 if (conn.provider == cpr) { 8894 if (DEBUG_PROVIDER) Slog.v(TAG, 8895 "Adding provider requested by " 8896 + r.processName + " from process " 8897 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8898 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8899 if (stable) { 8900 conn.stableCount++; 8901 conn.numStableIncs++; 8902 } else { 8903 conn.unstableCount++; 8904 conn.numUnstableIncs++; 8905 } 8906 return conn; 8907 } 8908 } 8909 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8910 if (stable) { 8911 conn.stableCount = 1; 8912 conn.numStableIncs = 1; 8913 } else { 8914 conn.unstableCount = 1; 8915 conn.numUnstableIncs = 1; 8916 } 8917 cpr.connections.add(conn); 8918 r.conProviders.add(conn); 8919 return conn; 8920 } 8921 cpr.addExternalProcessHandleLocked(externalProcessToken); 8922 return null; 8923 } 8924 8925 boolean decProviderCountLocked(ContentProviderConnection conn, 8926 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8927 if (conn != null) { 8928 cpr = conn.provider; 8929 if (DEBUG_PROVIDER) Slog.v(TAG, 8930 "Removing provider requested by " 8931 + conn.client.processName + " from process " 8932 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8933 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8934 if (stable) { 8935 conn.stableCount--; 8936 } else { 8937 conn.unstableCount--; 8938 } 8939 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8940 cpr.connections.remove(conn); 8941 conn.client.conProviders.remove(conn); 8942 return true; 8943 } 8944 return false; 8945 } 8946 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8947 return false; 8948 } 8949 8950 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8951 String name, IBinder token, boolean stable, int userId) { 8952 ContentProviderRecord cpr; 8953 ContentProviderConnection conn = null; 8954 ProviderInfo cpi = null; 8955 8956 synchronized(this) { 8957 ProcessRecord r = null; 8958 if (caller != null) { 8959 r = getRecordForAppLocked(caller); 8960 if (r == null) { 8961 throw new SecurityException( 8962 "Unable to find app for caller " + caller 8963 + " (pid=" + Binder.getCallingPid() 8964 + ") when getting content provider " + name); 8965 } 8966 } 8967 8968 boolean checkCrossUser = true; 8969 8970 // First check if this content provider has been published... 8971 cpr = mProviderMap.getProviderByName(name, userId); 8972 // If that didn't work, check if it exists for user 0 and then 8973 // verify that it's a singleton provider before using it. 8974 if (cpr == null && userId != UserHandle.USER_OWNER) { 8975 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8976 if (cpr != null) { 8977 cpi = cpr.info; 8978 if (isSingleton(cpi.processName, cpi.applicationInfo, 8979 cpi.name, cpi.flags) 8980 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8981 userId = UserHandle.USER_OWNER; 8982 checkCrossUser = false; 8983 } else { 8984 cpr = null; 8985 cpi = null; 8986 } 8987 } 8988 } 8989 8990 boolean providerRunning = cpr != null; 8991 if (providerRunning) { 8992 cpi = cpr.info; 8993 String msg; 8994 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8995 != null) { 8996 throw new SecurityException(msg); 8997 } 8998 8999 if (r != null && cpr.canRunHere(r)) { 9000 // This provider has been published or is in the process 9001 // of being published... but it is also allowed to run 9002 // in the caller's process, so don't make a connection 9003 // and just let the caller instantiate its own instance. 9004 ContentProviderHolder holder = cpr.newHolder(null); 9005 // don't give caller the provider object, it needs 9006 // to make its own. 9007 holder.provider = null; 9008 return holder; 9009 } 9010 9011 final long origId = Binder.clearCallingIdentity(); 9012 9013 // In this case the provider instance already exists, so we can 9014 // return it right away. 9015 conn = incProviderCountLocked(r, cpr, token, stable); 9016 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9017 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9018 // If this is a perceptible app accessing the provider, 9019 // make sure to count it as being accessed and thus 9020 // back up on the LRU list. This is good because 9021 // content providers are often expensive to start. 9022 updateLruProcessLocked(cpr.proc, false, null); 9023 } 9024 } 9025 9026 if (cpr.proc != null) { 9027 if (false) { 9028 if (cpr.name.flattenToShortString().equals( 9029 "com.android.providers.calendar/.CalendarProvider2")) { 9030 Slog.v(TAG, "****************** KILLING " 9031 + cpr.name.flattenToShortString()); 9032 Process.killProcess(cpr.proc.pid); 9033 } 9034 } 9035 boolean success = updateOomAdjLocked(cpr.proc); 9036 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9037 // NOTE: there is still a race here where a signal could be 9038 // pending on the process even though we managed to update its 9039 // adj level. Not sure what to do about this, but at least 9040 // the race is now smaller. 9041 if (!success) { 9042 // Uh oh... it looks like the provider's process 9043 // has been killed on us. We need to wait for a new 9044 // process to be started, and make sure its death 9045 // doesn't kill our process. 9046 Slog.i(TAG, 9047 "Existing provider " + cpr.name.flattenToShortString() 9048 + " is crashing; detaching " + r); 9049 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9050 appDiedLocked(cpr.proc); 9051 if (!lastRef) { 9052 // This wasn't the last ref our process had on 9053 // the provider... we have now been killed, bail. 9054 return null; 9055 } 9056 providerRunning = false; 9057 conn = null; 9058 } 9059 } 9060 9061 Binder.restoreCallingIdentity(origId); 9062 } 9063 9064 boolean singleton; 9065 if (!providerRunning) { 9066 try { 9067 cpi = AppGlobals.getPackageManager(). 9068 resolveContentProvider(name, 9069 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9070 } catch (RemoteException ex) { 9071 } 9072 if (cpi == null) { 9073 return null; 9074 } 9075 // If the provider is a singleton AND 9076 // (it's a call within the same user || the provider is a 9077 // privileged app) 9078 // Then allow connecting to the singleton provider 9079 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9080 cpi.name, cpi.flags) 9081 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9082 if (singleton) { 9083 userId = UserHandle.USER_OWNER; 9084 } 9085 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9086 9087 String msg; 9088 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9089 != null) { 9090 throw new SecurityException(msg); 9091 } 9092 9093 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9094 && !cpi.processName.equals("system")) { 9095 // If this content provider does not run in the system 9096 // process, and the system is not yet ready to run other 9097 // processes, then fail fast instead of hanging. 9098 throw new IllegalArgumentException( 9099 "Attempt to launch content provider before system ready"); 9100 } 9101 9102 // Make sure that the user who owns this provider is started. If not, 9103 // we don't want to allow it to run. 9104 if (mStartedUsers.get(userId) == null) { 9105 Slog.w(TAG, "Unable to launch app " 9106 + cpi.applicationInfo.packageName + "/" 9107 + cpi.applicationInfo.uid + " for provider " 9108 + name + ": user " + userId + " is stopped"); 9109 return null; 9110 } 9111 9112 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9113 cpr = mProviderMap.getProviderByClass(comp, userId); 9114 final boolean firstClass = cpr == null; 9115 if (firstClass) { 9116 try { 9117 ApplicationInfo ai = 9118 AppGlobals.getPackageManager(). 9119 getApplicationInfo( 9120 cpi.applicationInfo.packageName, 9121 STOCK_PM_FLAGS, userId); 9122 if (ai == null) { 9123 Slog.w(TAG, "No package info for content provider " 9124 + cpi.name); 9125 return null; 9126 } 9127 ai = getAppInfoForUser(ai, userId); 9128 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9129 } catch (RemoteException ex) { 9130 // pm is in same process, this will never happen. 9131 } 9132 } 9133 9134 if (r != null && cpr.canRunHere(r)) { 9135 // If this is a multiprocess provider, then just return its 9136 // info and allow the caller to instantiate it. Only do 9137 // this if the provider is the same user as the caller's 9138 // process, or can run as root (so can be in any process). 9139 return cpr.newHolder(null); 9140 } 9141 9142 if (DEBUG_PROVIDER) { 9143 RuntimeException e = new RuntimeException("here"); 9144 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9145 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9146 } 9147 9148 // This is single process, and our app is now connecting to it. 9149 // See if we are already in the process of launching this 9150 // provider. 9151 final int N = mLaunchingProviders.size(); 9152 int i; 9153 for (i=0; i<N; i++) { 9154 if (mLaunchingProviders.get(i) == cpr) { 9155 break; 9156 } 9157 } 9158 9159 // If the provider is not already being launched, then get it 9160 // started. 9161 if (i >= N) { 9162 final long origId = Binder.clearCallingIdentity(); 9163 9164 try { 9165 // Content provider is now in use, its package can't be stopped. 9166 try { 9167 AppGlobals.getPackageManager().setPackageStoppedState( 9168 cpr.appInfo.packageName, false, userId); 9169 } catch (RemoteException e) { 9170 } catch (IllegalArgumentException e) { 9171 Slog.w(TAG, "Failed trying to unstop package " 9172 + cpr.appInfo.packageName + ": " + e); 9173 } 9174 9175 // Use existing process if already started 9176 ProcessRecord proc = getProcessRecordLocked( 9177 cpi.processName, cpr.appInfo.uid, false); 9178 if (proc != null && proc.thread != null) { 9179 if (DEBUG_PROVIDER) { 9180 Slog.d(TAG, "Installing in existing process " + proc); 9181 } 9182 proc.pubProviders.put(cpi.name, cpr); 9183 try { 9184 proc.thread.scheduleInstallProvider(cpi); 9185 } catch (RemoteException e) { 9186 } 9187 } else { 9188 proc = startProcessLocked(cpi.processName, 9189 cpr.appInfo, false, 0, "content provider", 9190 new ComponentName(cpi.applicationInfo.packageName, 9191 cpi.name), false, false, false); 9192 if (proc == null) { 9193 Slog.w(TAG, "Unable to launch app " 9194 + cpi.applicationInfo.packageName + "/" 9195 + cpi.applicationInfo.uid + " for provider " 9196 + name + ": process is bad"); 9197 return null; 9198 } 9199 } 9200 cpr.launchingApp = proc; 9201 mLaunchingProviders.add(cpr); 9202 } finally { 9203 Binder.restoreCallingIdentity(origId); 9204 } 9205 } 9206 9207 // Make sure the provider is published (the same provider class 9208 // may be published under multiple names). 9209 if (firstClass) { 9210 mProviderMap.putProviderByClass(comp, cpr); 9211 } 9212 9213 mProviderMap.putProviderByName(name, cpr); 9214 conn = incProviderCountLocked(r, cpr, token, stable); 9215 if (conn != null) { 9216 conn.waiting = true; 9217 } 9218 } 9219 } 9220 9221 // Wait for the provider to be published... 9222 synchronized (cpr) { 9223 while (cpr.provider == null) { 9224 if (cpr.launchingApp == null) { 9225 Slog.w(TAG, "Unable to launch app " 9226 + cpi.applicationInfo.packageName + "/" 9227 + cpi.applicationInfo.uid + " for provider " 9228 + name + ": launching app became null"); 9229 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9230 UserHandle.getUserId(cpi.applicationInfo.uid), 9231 cpi.applicationInfo.packageName, 9232 cpi.applicationInfo.uid, name); 9233 return null; 9234 } 9235 try { 9236 if (DEBUG_MU) { 9237 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9238 + cpr.launchingApp); 9239 } 9240 if (conn != null) { 9241 conn.waiting = true; 9242 } 9243 cpr.wait(); 9244 } catch (InterruptedException ex) { 9245 } finally { 9246 if (conn != null) { 9247 conn.waiting = false; 9248 } 9249 } 9250 } 9251 } 9252 return cpr != null ? cpr.newHolder(conn) : null; 9253 } 9254 9255 @Override 9256 public final ContentProviderHolder getContentProvider( 9257 IApplicationThread caller, String name, int userId, boolean stable) { 9258 enforceNotIsolatedCaller("getContentProvider"); 9259 if (caller == null) { 9260 String msg = "null IApplicationThread when getting content provider " 9261 + name; 9262 Slog.w(TAG, msg); 9263 throw new SecurityException(msg); 9264 } 9265 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9266 // with cross-user grant. 9267 return getContentProviderImpl(caller, name, null, stable, userId); 9268 } 9269 9270 public ContentProviderHolder getContentProviderExternal( 9271 String name, int userId, IBinder token) { 9272 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9273 "Do not have permission in call getContentProviderExternal()"); 9274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9275 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9276 return getContentProviderExternalUnchecked(name, token, userId); 9277 } 9278 9279 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9280 IBinder token, int userId) { 9281 return getContentProviderImpl(null, name, token, true, userId); 9282 } 9283 9284 /** 9285 * Drop a content provider from a ProcessRecord's bookkeeping 9286 */ 9287 public void removeContentProvider(IBinder connection, boolean stable) { 9288 enforceNotIsolatedCaller("removeContentProvider"); 9289 long ident = Binder.clearCallingIdentity(); 9290 try { 9291 synchronized (this) { 9292 ContentProviderConnection conn; 9293 try { 9294 conn = (ContentProviderConnection)connection; 9295 } catch (ClassCastException e) { 9296 String msg ="removeContentProvider: " + connection 9297 + " not a ContentProviderConnection"; 9298 Slog.w(TAG, msg); 9299 throw new IllegalArgumentException(msg); 9300 } 9301 if (conn == null) { 9302 throw new NullPointerException("connection is null"); 9303 } 9304 if (decProviderCountLocked(conn, null, null, stable)) { 9305 updateOomAdjLocked(); 9306 } 9307 } 9308 } finally { 9309 Binder.restoreCallingIdentity(ident); 9310 } 9311 } 9312 9313 public void removeContentProviderExternal(String name, IBinder token) { 9314 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9315 "Do not have permission in call removeContentProviderExternal()"); 9316 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9317 } 9318 9319 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9320 synchronized (this) { 9321 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9322 if(cpr == null) { 9323 //remove from mProvidersByClass 9324 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9325 return; 9326 } 9327 9328 //update content provider record entry info 9329 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9330 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9331 if (localCpr.hasExternalProcessHandles()) { 9332 if (localCpr.removeExternalProcessHandleLocked(token)) { 9333 updateOomAdjLocked(); 9334 } else { 9335 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9336 + " with no external reference for token: " 9337 + token + "."); 9338 } 9339 } else { 9340 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9341 + " with no external references."); 9342 } 9343 } 9344 } 9345 9346 public final void publishContentProviders(IApplicationThread caller, 9347 List<ContentProviderHolder> providers) { 9348 if (providers == null) { 9349 return; 9350 } 9351 9352 enforceNotIsolatedCaller("publishContentProviders"); 9353 synchronized (this) { 9354 final ProcessRecord r = getRecordForAppLocked(caller); 9355 if (DEBUG_MU) 9356 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9357 if (r == null) { 9358 throw new SecurityException( 9359 "Unable to find app for caller " + caller 9360 + " (pid=" + Binder.getCallingPid() 9361 + ") when publishing content providers"); 9362 } 9363 9364 final long origId = Binder.clearCallingIdentity(); 9365 9366 final int N = providers.size(); 9367 for (int i=0; i<N; i++) { 9368 ContentProviderHolder src = providers.get(i); 9369 if (src == null || src.info == null || src.provider == null) { 9370 continue; 9371 } 9372 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9373 if (DEBUG_MU) 9374 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9375 if (dst != null) { 9376 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9377 mProviderMap.putProviderByClass(comp, dst); 9378 String names[] = dst.info.authority.split(";"); 9379 for (int j = 0; j < names.length; j++) { 9380 mProviderMap.putProviderByName(names[j], dst); 9381 } 9382 9383 int NL = mLaunchingProviders.size(); 9384 int j; 9385 for (j=0; j<NL; j++) { 9386 if (mLaunchingProviders.get(j) == dst) { 9387 mLaunchingProviders.remove(j); 9388 j--; 9389 NL--; 9390 } 9391 } 9392 synchronized (dst) { 9393 dst.provider = src.provider; 9394 dst.proc = r; 9395 dst.notifyAll(); 9396 } 9397 updateOomAdjLocked(r); 9398 } 9399 } 9400 9401 Binder.restoreCallingIdentity(origId); 9402 } 9403 } 9404 9405 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9406 ContentProviderConnection conn; 9407 try { 9408 conn = (ContentProviderConnection)connection; 9409 } catch (ClassCastException e) { 9410 String msg ="refContentProvider: " + connection 9411 + " not a ContentProviderConnection"; 9412 Slog.w(TAG, msg); 9413 throw new IllegalArgumentException(msg); 9414 } 9415 if (conn == null) { 9416 throw new NullPointerException("connection is null"); 9417 } 9418 9419 synchronized (this) { 9420 if (stable > 0) { 9421 conn.numStableIncs += stable; 9422 } 9423 stable = conn.stableCount + stable; 9424 if (stable < 0) { 9425 throw new IllegalStateException("stableCount < 0: " + stable); 9426 } 9427 9428 if (unstable > 0) { 9429 conn.numUnstableIncs += unstable; 9430 } 9431 unstable = conn.unstableCount + unstable; 9432 if (unstable < 0) { 9433 throw new IllegalStateException("unstableCount < 0: " + unstable); 9434 } 9435 9436 if ((stable+unstable) <= 0) { 9437 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9438 + stable + " unstable=" + unstable); 9439 } 9440 conn.stableCount = stable; 9441 conn.unstableCount = unstable; 9442 return !conn.dead; 9443 } 9444 } 9445 9446 public void unstableProviderDied(IBinder connection) { 9447 ContentProviderConnection conn; 9448 try { 9449 conn = (ContentProviderConnection)connection; 9450 } catch (ClassCastException e) { 9451 String msg ="refContentProvider: " + connection 9452 + " not a ContentProviderConnection"; 9453 Slog.w(TAG, msg); 9454 throw new IllegalArgumentException(msg); 9455 } 9456 if (conn == null) { 9457 throw new NullPointerException("connection is null"); 9458 } 9459 9460 // Safely retrieve the content provider associated with the connection. 9461 IContentProvider provider; 9462 synchronized (this) { 9463 provider = conn.provider.provider; 9464 } 9465 9466 if (provider == null) { 9467 // Um, yeah, we're way ahead of you. 9468 return; 9469 } 9470 9471 // Make sure the caller is being honest with us. 9472 if (provider.asBinder().pingBinder()) { 9473 // Er, no, still looks good to us. 9474 synchronized (this) { 9475 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9476 + " says " + conn + " died, but we don't agree"); 9477 return; 9478 } 9479 } 9480 9481 // Well look at that! It's dead! 9482 synchronized (this) { 9483 if (conn.provider.provider != provider) { 9484 // But something changed... good enough. 9485 return; 9486 } 9487 9488 ProcessRecord proc = conn.provider.proc; 9489 if (proc == null || proc.thread == null) { 9490 // Seems like the process is already cleaned up. 9491 return; 9492 } 9493 9494 // As far as we're concerned, this is just like receiving a 9495 // death notification... just a bit prematurely. 9496 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9497 + ") early provider death"); 9498 final long ident = Binder.clearCallingIdentity(); 9499 try { 9500 appDiedLocked(proc); 9501 } finally { 9502 Binder.restoreCallingIdentity(ident); 9503 } 9504 } 9505 } 9506 9507 @Override 9508 public void appNotRespondingViaProvider(IBinder connection) { 9509 enforceCallingPermission( 9510 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9511 9512 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9513 if (conn == null) { 9514 Slog.w(TAG, "ContentProviderConnection is null"); 9515 return; 9516 } 9517 9518 final ProcessRecord host = conn.provider.proc; 9519 if (host == null) { 9520 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9521 return; 9522 } 9523 9524 final long token = Binder.clearCallingIdentity(); 9525 try { 9526 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9527 } finally { 9528 Binder.restoreCallingIdentity(token); 9529 } 9530 } 9531 9532 public final void installSystemProviders() { 9533 List<ProviderInfo> providers; 9534 synchronized (this) { 9535 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9536 providers = generateApplicationProvidersLocked(app); 9537 if (providers != null) { 9538 for (int i=providers.size()-1; i>=0; i--) { 9539 ProviderInfo pi = (ProviderInfo)providers.get(i); 9540 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9541 Slog.w(TAG, "Not installing system proc provider " + pi.name 9542 + ": not system .apk"); 9543 providers.remove(i); 9544 } 9545 } 9546 } 9547 } 9548 if (providers != null) { 9549 mSystemThread.installSystemProviders(providers); 9550 } 9551 9552 mCoreSettingsObserver = new CoreSettingsObserver(this); 9553 9554 //mUsageStatsService.monitorPackages(); 9555 } 9556 9557 /** 9558 * Allows apps to retrieve the MIME type of a URI. 9559 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9560 * users, then it does not need permission to access the ContentProvider. 9561 * Either, it needs cross-user uri grants. 9562 * 9563 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9564 * 9565 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9566 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9567 */ 9568 public String getProviderMimeType(Uri uri, int userId) { 9569 enforceNotIsolatedCaller("getProviderMimeType"); 9570 final String name = uri.getAuthority(); 9571 int callingUid = Binder.getCallingUid(); 9572 int callingPid = Binder.getCallingPid(); 9573 long ident = 0; 9574 boolean clearedIdentity = false; 9575 userId = unsafeConvertIncomingUser(userId); 9576 if (UserHandle.getUserId(callingUid) != userId) { 9577 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9578 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9579 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9580 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9581 clearedIdentity = true; 9582 ident = Binder.clearCallingIdentity(); 9583 } 9584 } 9585 ContentProviderHolder holder = null; 9586 try { 9587 holder = getContentProviderExternalUnchecked(name, null, userId); 9588 if (holder != null) { 9589 return holder.provider.getType(uri); 9590 } 9591 } catch (RemoteException e) { 9592 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9593 return null; 9594 } finally { 9595 // We need to clear the identity to call removeContentProviderExternalUnchecked 9596 if (!clearedIdentity) { 9597 ident = Binder.clearCallingIdentity(); 9598 } 9599 try { 9600 if (holder != null) { 9601 removeContentProviderExternalUnchecked(name, null, userId); 9602 } 9603 } finally { 9604 Binder.restoreCallingIdentity(ident); 9605 } 9606 } 9607 9608 return null; 9609 } 9610 9611 // ========================================================= 9612 // GLOBAL MANAGEMENT 9613 // ========================================================= 9614 9615 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9616 boolean isolated, int isolatedUid) { 9617 String proc = customProcess != null ? customProcess : info.processName; 9618 BatteryStatsImpl.Uid.Proc ps = null; 9619 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9620 int uid = info.uid; 9621 if (isolated) { 9622 if (isolatedUid == 0) { 9623 int userId = UserHandle.getUserId(uid); 9624 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9625 while (true) { 9626 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9627 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9628 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9629 } 9630 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9631 mNextIsolatedProcessUid++; 9632 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9633 // No process for this uid, use it. 9634 break; 9635 } 9636 stepsLeft--; 9637 if (stepsLeft <= 0) { 9638 return null; 9639 } 9640 } 9641 } else { 9642 // Special case for startIsolatedProcess (internal only), where 9643 // the uid of the isolated process is specified by the caller. 9644 uid = isolatedUid; 9645 } 9646 } 9647 return new ProcessRecord(stats, info, proc, uid); 9648 } 9649 9650 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9651 String abiOverride) { 9652 ProcessRecord app; 9653 if (!isolated) { 9654 app = getProcessRecordLocked(info.processName, info.uid, true); 9655 } else { 9656 app = null; 9657 } 9658 9659 if (app == null) { 9660 app = newProcessRecordLocked(info, null, isolated, 0); 9661 mProcessNames.put(info.processName, app.uid, app); 9662 if (isolated) { 9663 mIsolatedProcesses.put(app.uid, app); 9664 } 9665 updateLruProcessLocked(app, false, null); 9666 updateOomAdjLocked(); 9667 } 9668 9669 // This package really, really can not be stopped. 9670 try { 9671 AppGlobals.getPackageManager().setPackageStoppedState( 9672 info.packageName, false, UserHandle.getUserId(app.uid)); 9673 } catch (RemoteException e) { 9674 } catch (IllegalArgumentException e) { 9675 Slog.w(TAG, "Failed trying to unstop package " 9676 + info.packageName + ": " + e); 9677 } 9678 9679 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9680 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9681 app.persistent = true; 9682 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9683 } 9684 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9685 mPersistentStartingProcesses.add(app); 9686 startProcessLocked(app, "added application", app.processName, abiOverride, 9687 null /* entryPoint */, null /* entryPointArgs */); 9688 } 9689 9690 return app; 9691 } 9692 9693 public void unhandledBack() { 9694 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9695 "unhandledBack()"); 9696 9697 synchronized(this) { 9698 final long origId = Binder.clearCallingIdentity(); 9699 try { 9700 getFocusedStack().unhandledBackLocked(); 9701 } finally { 9702 Binder.restoreCallingIdentity(origId); 9703 } 9704 } 9705 } 9706 9707 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9708 enforceNotIsolatedCaller("openContentUri"); 9709 final int userId = UserHandle.getCallingUserId(); 9710 String name = uri.getAuthority(); 9711 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9712 ParcelFileDescriptor pfd = null; 9713 if (cph != null) { 9714 // We record the binder invoker's uid in thread-local storage before 9715 // going to the content provider to open the file. Later, in the code 9716 // that handles all permissions checks, we look for this uid and use 9717 // that rather than the Activity Manager's own uid. The effect is that 9718 // we do the check against the caller's permissions even though it looks 9719 // to the content provider like the Activity Manager itself is making 9720 // the request. 9721 sCallerIdentity.set(new Identity( 9722 Binder.getCallingPid(), Binder.getCallingUid())); 9723 try { 9724 pfd = cph.provider.openFile(null, uri, "r", null); 9725 } catch (FileNotFoundException e) { 9726 // do nothing; pfd will be returned null 9727 } finally { 9728 // Ensure that whatever happens, we clean up the identity state 9729 sCallerIdentity.remove(); 9730 } 9731 9732 // We've got the fd now, so we're done with the provider. 9733 removeContentProviderExternalUnchecked(name, null, userId); 9734 } else { 9735 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9736 } 9737 return pfd; 9738 } 9739 9740 // Actually is sleeping or shutting down or whatever else in the future 9741 // is an inactive state. 9742 public boolean isSleepingOrShuttingDown() { 9743 return mSleeping || mShuttingDown; 9744 } 9745 9746 public boolean isSleeping() { 9747 return mSleeping; 9748 } 9749 9750 void goingToSleep() { 9751 synchronized(this) { 9752 mWentToSleep = true; 9753 updateEventDispatchingLocked(); 9754 goToSleepIfNeededLocked(); 9755 } 9756 } 9757 9758 void finishRunningVoiceLocked() { 9759 if (mRunningVoice) { 9760 mRunningVoice = false; 9761 goToSleepIfNeededLocked(); 9762 } 9763 } 9764 9765 void goToSleepIfNeededLocked() { 9766 if (mWentToSleep && !mRunningVoice) { 9767 if (!mSleeping) { 9768 mSleeping = true; 9769 mStackSupervisor.goingToSleepLocked(); 9770 9771 // Initialize the wake times of all processes. 9772 checkExcessivePowerUsageLocked(false); 9773 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9774 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9775 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9776 } 9777 } 9778 } 9779 9780 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9781 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9782 // Never persist the home stack. 9783 return; 9784 } 9785 mTaskPersister.wakeup(task, flush); 9786 } 9787 9788 @Override 9789 public boolean shutdown(int timeout) { 9790 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9791 != PackageManager.PERMISSION_GRANTED) { 9792 throw new SecurityException("Requires permission " 9793 + android.Manifest.permission.SHUTDOWN); 9794 } 9795 9796 boolean timedout = false; 9797 9798 synchronized(this) { 9799 mShuttingDown = true; 9800 updateEventDispatchingLocked(); 9801 timedout = mStackSupervisor.shutdownLocked(timeout); 9802 } 9803 9804 mAppOpsService.shutdown(); 9805 if (mUsageStatsService != null) { 9806 mUsageStatsService.prepareShutdown(); 9807 } 9808 mBatteryStatsService.shutdown(); 9809 synchronized (this) { 9810 mProcessStats.shutdownLocked(); 9811 } 9812 notifyTaskPersisterLocked(null, true); 9813 9814 return timedout; 9815 } 9816 9817 public final void activitySlept(IBinder token) { 9818 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9819 9820 final long origId = Binder.clearCallingIdentity(); 9821 9822 synchronized (this) { 9823 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9824 if (r != null) { 9825 mStackSupervisor.activitySleptLocked(r); 9826 } 9827 } 9828 9829 Binder.restoreCallingIdentity(origId); 9830 } 9831 9832 void logLockScreen(String msg) { 9833 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9834 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9835 mWentToSleep + " mSleeping=" + mSleeping); 9836 } 9837 9838 private void comeOutOfSleepIfNeededLocked() { 9839 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9840 if (mSleeping) { 9841 mSleeping = false; 9842 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9843 } 9844 } 9845 } 9846 9847 void wakingUp() { 9848 synchronized(this) { 9849 mWentToSleep = false; 9850 updateEventDispatchingLocked(); 9851 comeOutOfSleepIfNeededLocked(); 9852 } 9853 } 9854 9855 void startRunningVoiceLocked() { 9856 if (!mRunningVoice) { 9857 mRunningVoice = true; 9858 comeOutOfSleepIfNeededLocked(); 9859 } 9860 } 9861 9862 private void updateEventDispatchingLocked() { 9863 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9864 } 9865 9866 public void setLockScreenShown(boolean shown) { 9867 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9868 != PackageManager.PERMISSION_GRANTED) { 9869 throw new SecurityException("Requires permission " 9870 + android.Manifest.permission.DEVICE_POWER); 9871 } 9872 9873 synchronized(this) { 9874 long ident = Binder.clearCallingIdentity(); 9875 try { 9876 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9877 mLockScreenShown = shown; 9878 comeOutOfSleepIfNeededLocked(); 9879 } finally { 9880 Binder.restoreCallingIdentity(ident); 9881 } 9882 } 9883 } 9884 9885 @Override 9886 public void stopAppSwitches() { 9887 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9888 != PackageManager.PERMISSION_GRANTED) { 9889 throw new SecurityException("Requires permission " 9890 + android.Manifest.permission.STOP_APP_SWITCHES); 9891 } 9892 9893 synchronized(this) { 9894 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9895 + APP_SWITCH_DELAY_TIME; 9896 mDidAppSwitch = false; 9897 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9898 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9899 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9900 } 9901 } 9902 9903 public void resumeAppSwitches() { 9904 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9905 != PackageManager.PERMISSION_GRANTED) { 9906 throw new SecurityException("Requires permission " 9907 + android.Manifest.permission.STOP_APP_SWITCHES); 9908 } 9909 9910 synchronized(this) { 9911 // Note that we don't execute any pending app switches... we will 9912 // let those wait until either the timeout, or the next start 9913 // activity request. 9914 mAppSwitchesAllowedTime = 0; 9915 } 9916 } 9917 9918 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9919 String name) { 9920 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9921 return true; 9922 } 9923 9924 final int perm = checkComponentPermission( 9925 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9926 callingUid, -1, true); 9927 if (perm == PackageManager.PERMISSION_GRANTED) { 9928 return true; 9929 } 9930 9931 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9932 return false; 9933 } 9934 9935 public void setDebugApp(String packageName, boolean waitForDebugger, 9936 boolean persistent) { 9937 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9938 "setDebugApp()"); 9939 9940 long ident = Binder.clearCallingIdentity(); 9941 try { 9942 // Note that this is not really thread safe if there are multiple 9943 // callers into it at the same time, but that's not a situation we 9944 // care about. 9945 if (persistent) { 9946 final ContentResolver resolver = mContext.getContentResolver(); 9947 Settings.Global.putString( 9948 resolver, Settings.Global.DEBUG_APP, 9949 packageName); 9950 Settings.Global.putInt( 9951 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9952 waitForDebugger ? 1 : 0); 9953 } 9954 9955 synchronized (this) { 9956 if (!persistent) { 9957 mOrigDebugApp = mDebugApp; 9958 mOrigWaitForDebugger = mWaitForDebugger; 9959 } 9960 mDebugApp = packageName; 9961 mWaitForDebugger = waitForDebugger; 9962 mDebugTransient = !persistent; 9963 if (packageName != null) { 9964 forceStopPackageLocked(packageName, -1, false, false, true, true, 9965 false, UserHandle.USER_ALL, "set debug app"); 9966 } 9967 } 9968 } finally { 9969 Binder.restoreCallingIdentity(ident); 9970 } 9971 } 9972 9973 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9974 synchronized (this) { 9975 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9976 if (!isDebuggable) { 9977 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9978 throw new SecurityException("Process not debuggable: " + app.packageName); 9979 } 9980 } 9981 9982 mOpenGlTraceApp = processName; 9983 } 9984 } 9985 9986 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 9987 synchronized (this) { 9988 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9989 if (!isDebuggable) { 9990 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9991 throw new SecurityException("Process not debuggable: " + app.packageName); 9992 } 9993 } 9994 mProfileApp = processName; 9995 mProfileFile = profilerInfo.profileFile; 9996 if (mProfileFd != null) { 9997 try { 9998 mProfileFd.close(); 9999 } catch (IOException e) { 10000 } 10001 mProfileFd = null; 10002 } 10003 mProfileFd = profilerInfo.profileFd; 10004 mSamplingInterval = profilerInfo.samplingInterval; 10005 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10006 mProfileType = 0; 10007 } 10008 } 10009 10010 @Override 10011 public void setAlwaysFinish(boolean enabled) { 10012 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10013 "setAlwaysFinish()"); 10014 10015 Settings.Global.putInt( 10016 mContext.getContentResolver(), 10017 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10018 10019 synchronized (this) { 10020 mAlwaysFinishActivities = enabled; 10021 } 10022 } 10023 10024 @Override 10025 public void setActivityController(IActivityController controller) { 10026 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10027 "setActivityController()"); 10028 synchronized (this) { 10029 mController = controller; 10030 Watchdog.getInstance().setActivityController(controller); 10031 } 10032 } 10033 10034 @Override 10035 public void setUserIsMonkey(boolean userIsMonkey) { 10036 synchronized (this) { 10037 synchronized (mPidsSelfLocked) { 10038 final int callingPid = Binder.getCallingPid(); 10039 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10040 if (precessRecord == null) { 10041 throw new SecurityException("Unknown process: " + callingPid); 10042 } 10043 if (precessRecord.instrumentationUiAutomationConnection == null) { 10044 throw new SecurityException("Only an instrumentation process " 10045 + "with a UiAutomation can call setUserIsMonkey"); 10046 } 10047 } 10048 mUserIsMonkey = userIsMonkey; 10049 } 10050 } 10051 10052 @Override 10053 public boolean isUserAMonkey() { 10054 synchronized (this) { 10055 // If there is a controller also implies the user is a monkey. 10056 return (mUserIsMonkey || mController != null); 10057 } 10058 } 10059 10060 public void requestBugReport() { 10061 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10062 SystemProperties.set("ctl.start", "bugreport"); 10063 } 10064 10065 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10066 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10067 } 10068 10069 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10070 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10071 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10072 } 10073 return KEY_DISPATCHING_TIMEOUT; 10074 } 10075 10076 @Override 10077 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10078 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10079 != PackageManager.PERMISSION_GRANTED) { 10080 throw new SecurityException("Requires permission " 10081 + android.Manifest.permission.FILTER_EVENTS); 10082 } 10083 ProcessRecord proc; 10084 long timeout; 10085 synchronized (this) { 10086 synchronized (mPidsSelfLocked) { 10087 proc = mPidsSelfLocked.get(pid); 10088 } 10089 timeout = getInputDispatchingTimeoutLocked(proc); 10090 } 10091 10092 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10093 return -1; 10094 } 10095 10096 return timeout; 10097 } 10098 10099 /** 10100 * Handle input dispatching timeouts. 10101 * Returns whether input dispatching should be aborted or not. 10102 */ 10103 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10104 final ActivityRecord activity, final ActivityRecord parent, 10105 final boolean aboveSystem, String reason) { 10106 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10107 != PackageManager.PERMISSION_GRANTED) { 10108 throw new SecurityException("Requires permission " 10109 + android.Manifest.permission.FILTER_EVENTS); 10110 } 10111 10112 final String annotation; 10113 if (reason == null) { 10114 annotation = "Input dispatching timed out"; 10115 } else { 10116 annotation = "Input dispatching timed out (" + reason + ")"; 10117 } 10118 10119 if (proc != null) { 10120 synchronized (this) { 10121 if (proc.debugging) { 10122 return false; 10123 } 10124 10125 if (mDidDexOpt) { 10126 // Give more time since we were dexopting. 10127 mDidDexOpt = false; 10128 return false; 10129 } 10130 10131 if (proc.instrumentationClass != null) { 10132 Bundle info = new Bundle(); 10133 info.putString("shortMsg", "keyDispatchingTimedOut"); 10134 info.putString("longMsg", annotation); 10135 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10136 return true; 10137 } 10138 } 10139 mHandler.post(new Runnable() { 10140 @Override 10141 public void run() { 10142 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10143 } 10144 }); 10145 } 10146 10147 return true; 10148 } 10149 10150 public Bundle getAssistContextExtras(int requestType) { 10151 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10152 "getAssistContextExtras()"); 10153 PendingAssistExtras pae; 10154 Bundle extras = new Bundle(); 10155 synchronized (this) { 10156 ActivityRecord activity = getFocusedStack().mResumedActivity; 10157 if (activity == null) { 10158 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10159 return null; 10160 } 10161 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10162 if (activity.app == null || activity.app.thread == null) { 10163 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10164 return extras; 10165 } 10166 if (activity.app.pid == Binder.getCallingPid()) { 10167 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10168 return extras; 10169 } 10170 pae = new PendingAssistExtras(activity); 10171 try { 10172 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10173 requestType); 10174 mPendingAssistExtras.add(pae); 10175 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10176 } catch (RemoteException e) { 10177 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10178 return extras; 10179 } 10180 } 10181 synchronized (pae) { 10182 while (!pae.haveResult) { 10183 try { 10184 pae.wait(); 10185 } catch (InterruptedException e) { 10186 } 10187 } 10188 if (pae.result != null) { 10189 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10190 } 10191 } 10192 synchronized (this) { 10193 mPendingAssistExtras.remove(pae); 10194 mHandler.removeCallbacks(pae); 10195 } 10196 return extras; 10197 } 10198 10199 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10200 PendingAssistExtras pae = (PendingAssistExtras)token; 10201 synchronized (pae) { 10202 pae.result = extras; 10203 pae.haveResult = true; 10204 pae.notifyAll(); 10205 } 10206 } 10207 10208 public void registerProcessObserver(IProcessObserver observer) { 10209 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10210 "registerProcessObserver()"); 10211 synchronized (this) { 10212 mProcessObservers.register(observer); 10213 } 10214 } 10215 10216 @Override 10217 public void unregisterProcessObserver(IProcessObserver observer) { 10218 synchronized (this) { 10219 mProcessObservers.unregister(observer); 10220 } 10221 } 10222 10223 @Override 10224 public boolean convertFromTranslucent(IBinder token) { 10225 final long origId = Binder.clearCallingIdentity(); 10226 try { 10227 synchronized (this) { 10228 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10229 if (r == null) { 10230 return false; 10231 } 10232 if (r.changeWindowTranslucency(true)) { 10233 mWindowManager.setAppFullscreen(token, true); 10234 r.task.stack.releaseBackgroundResources(); 10235 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10236 return true; 10237 } 10238 return false; 10239 } 10240 } finally { 10241 Binder.restoreCallingIdentity(origId); 10242 } 10243 } 10244 10245 @Override 10246 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10247 final long origId = Binder.clearCallingIdentity(); 10248 try { 10249 synchronized (this) { 10250 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10251 if (r == null) { 10252 return false; 10253 } 10254 int index = r.task.mActivities.lastIndexOf(r); 10255 if (index > 0) { 10256 ActivityRecord under = r.task.mActivities.get(index - 1); 10257 under.returningOptions = options; 10258 } 10259 if (r.changeWindowTranslucency(false)) { 10260 r.task.stack.convertToTranslucent(r); 10261 mWindowManager.setAppFullscreen(token, false); 10262 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10263 return true; 10264 } else { 10265 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10266 return false; 10267 } 10268 } 10269 } finally { 10270 Binder.restoreCallingIdentity(origId); 10271 } 10272 } 10273 10274 @Override 10275 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10276 final long origId = Binder.clearCallingIdentity(); 10277 try { 10278 synchronized (this) { 10279 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10280 if (r != null) { 10281 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10282 } 10283 } 10284 return false; 10285 } finally { 10286 Binder.restoreCallingIdentity(origId); 10287 } 10288 } 10289 10290 @Override 10291 public boolean isBackgroundVisibleBehind(IBinder token) { 10292 final long origId = Binder.clearCallingIdentity(); 10293 try { 10294 synchronized (this) { 10295 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10296 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10297 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10298 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10299 return visible; 10300 } 10301 } finally { 10302 Binder.restoreCallingIdentity(origId); 10303 } 10304 } 10305 10306 @Override 10307 public ActivityOptions getActivityOptions(IBinder token) { 10308 final long origId = Binder.clearCallingIdentity(); 10309 try { 10310 synchronized (this) { 10311 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10312 if (r != null) { 10313 final ActivityOptions activityOptions = r.pendingOptions; 10314 r.pendingOptions = null; 10315 return activityOptions; 10316 } 10317 return null; 10318 } 10319 } finally { 10320 Binder.restoreCallingIdentity(origId); 10321 } 10322 } 10323 10324 @Override 10325 public void setImmersive(IBinder token, boolean immersive) { 10326 synchronized(this) { 10327 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10328 if (r == null) { 10329 throw new IllegalArgumentException(); 10330 } 10331 r.immersive = immersive; 10332 10333 // update associated state if we're frontmost 10334 if (r == mFocusedActivity) { 10335 if (DEBUG_IMMERSIVE) { 10336 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10337 } 10338 applyUpdateLockStateLocked(r); 10339 } 10340 } 10341 } 10342 10343 @Override 10344 public boolean isImmersive(IBinder token) { 10345 synchronized (this) { 10346 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10347 if (r == null) { 10348 throw new IllegalArgumentException(); 10349 } 10350 return r.immersive; 10351 } 10352 } 10353 10354 public boolean isTopActivityImmersive() { 10355 enforceNotIsolatedCaller("startActivity"); 10356 synchronized (this) { 10357 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10358 return (r != null) ? r.immersive : false; 10359 } 10360 } 10361 10362 @Override 10363 public boolean isTopOfTask(IBinder token) { 10364 synchronized (this) { 10365 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10366 if (r == null) { 10367 throw new IllegalArgumentException(); 10368 } 10369 return r.task.getTopActivity() == r; 10370 } 10371 } 10372 10373 public final void enterSafeMode() { 10374 synchronized(this) { 10375 // It only makes sense to do this before the system is ready 10376 // and started launching other packages. 10377 if (!mSystemReady) { 10378 try { 10379 AppGlobals.getPackageManager().enterSafeMode(); 10380 } catch (RemoteException e) { 10381 } 10382 } 10383 10384 mSafeMode = true; 10385 } 10386 } 10387 10388 public final void showSafeModeOverlay() { 10389 View v = LayoutInflater.from(mContext).inflate( 10390 com.android.internal.R.layout.safe_mode, null); 10391 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10392 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10393 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10394 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10395 lp.gravity = Gravity.BOTTOM | Gravity.START; 10396 lp.format = v.getBackground().getOpacity(); 10397 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10398 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10399 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10400 ((WindowManager)mContext.getSystemService( 10401 Context.WINDOW_SERVICE)).addView(v, lp); 10402 } 10403 10404 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10405 if (!(sender instanceof PendingIntentRecord)) { 10406 return; 10407 } 10408 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10409 synchronized (stats) { 10410 if (mBatteryStatsService.isOnBattery()) { 10411 mBatteryStatsService.enforceCallingPermission(); 10412 PendingIntentRecord rec = (PendingIntentRecord)sender; 10413 int MY_UID = Binder.getCallingUid(); 10414 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10415 BatteryStatsImpl.Uid.Pkg pkg = 10416 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10417 sourcePkg != null ? sourcePkg : rec.key.packageName); 10418 pkg.incWakeupsLocked(); 10419 } 10420 } 10421 } 10422 10423 public boolean killPids(int[] pids, String pReason, boolean secure) { 10424 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10425 throw new SecurityException("killPids only available to the system"); 10426 } 10427 String reason = (pReason == null) ? "Unknown" : pReason; 10428 // XXX Note: don't acquire main activity lock here, because the window 10429 // manager calls in with its locks held. 10430 10431 boolean killed = false; 10432 synchronized (mPidsSelfLocked) { 10433 int[] types = new int[pids.length]; 10434 int worstType = 0; 10435 for (int i=0; i<pids.length; i++) { 10436 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10437 if (proc != null) { 10438 int type = proc.setAdj; 10439 types[i] = type; 10440 if (type > worstType) { 10441 worstType = type; 10442 } 10443 } 10444 } 10445 10446 // If the worst oom_adj is somewhere in the cached proc LRU range, 10447 // then constrain it so we will kill all cached procs. 10448 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10449 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10450 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10451 } 10452 10453 // If this is not a secure call, don't let it kill processes that 10454 // are important. 10455 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10456 worstType = ProcessList.SERVICE_ADJ; 10457 } 10458 10459 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10460 for (int i=0; i<pids.length; i++) { 10461 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10462 if (proc == null) { 10463 continue; 10464 } 10465 int adj = proc.setAdj; 10466 if (adj >= worstType && !proc.killedByAm) { 10467 proc.kill(reason, true); 10468 killed = true; 10469 } 10470 } 10471 } 10472 return killed; 10473 } 10474 10475 @Override 10476 public void killUid(int uid, String reason) { 10477 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10478 throw new SecurityException("killUid only available to the system"); 10479 } 10480 synchronized (this) { 10481 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10482 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10483 reason != null ? reason : "kill uid"); 10484 } 10485 } 10486 10487 @Override 10488 public boolean killProcessesBelowForeground(String reason) { 10489 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10490 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10491 } 10492 10493 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10494 } 10495 10496 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10497 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10498 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10499 } 10500 10501 boolean killed = false; 10502 synchronized (mPidsSelfLocked) { 10503 final int size = mPidsSelfLocked.size(); 10504 for (int i = 0; i < size; i++) { 10505 final int pid = mPidsSelfLocked.keyAt(i); 10506 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10507 if (proc == null) continue; 10508 10509 final int adj = proc.setAdj; 10510 if (adj > belowAdj && !proc.killedByAm) { 10511 proc.kill(reason, true); 10512 killed = true; 10513 } 10514 } 10515 } 10516 return killed; 10517 } 10518 10519 @Override 10520 public void hang(final IBinder who, boolean allowRestart) { 10521 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10522 != PackageManager.PERMISSION_GRANTED) { 10523 throw new SecurityException("Requires permission " 10524 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10525 } 10526 10527 final IBinder.DeathRecipient death = new DeathRecipient() { 10528 @Override 10529 public void binderDied() { 10530 synchronized (this) { 10531 notifyAll(); 10532 } 10533 } 10534 }; 10535 10536 try { 10537 who.linkToDeath(death, 0); 10538 } catch (RemoteException e) { 10539 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10540 return; 10541 } 10542 10543 synchronized (this) { 10544 Watchdog.getInstance().setAllowRestart(allowRestart); 10545 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10546 synchronized (death) { 10547 while (who.isBinderAlive()) { 10548 try { 10549 death.wait(); 10550 } catch (InterruptedException e) { 10551 } 10552 } 10553 } 10554 Watchdog.getInstance().setAllowRestart(true); 10555 } 10556 } 10557 10558 @Override 10559 public void restart() { 10560 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10561 != PackageManager.PERMISSION_GRANTED) { 10562 throw new SecurityException("Requires permission " 10563 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10564 } 10565 10566 Log.i(TAG, "Sending shutdown broadcast..."); 10567 10568 BroadcastReceiver br = new BroadcastReceiver() { 10569 @Override public void onReceive(Context context, Intent intent) { 10570 // Now the broadcast is done, finish up the low-level shutdown. 10571 Log.i(TAG, "Shutting down activity manager..."); 10572 shutdown(10000); 10573 Log.i(TAG, "Shutdown complete, restarting!"); 10574 Process.killProcess(Process.myPid()); 10575 System.exit(10); 10576 } 10577 }; 10578 10579 // First send the high-level shut down broadcast. 10580 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10581 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10582 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10583 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10584 mContext.sendOrderedBroadcastAsUser(intent, 10585 UserHandle.ALL, null, br, mHandler, 0, null, null); 10586 */ 10587 br.onReceive(mContext, intent); 10588 } 10589 10590 private long getLowRamTimeSinceIdle(long now) { 10591 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10592 } 10593 10594 @Override 10595 public void performIdleMaintenance() { 10596 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10597 != PackageManager.PERMISSION_GRANTED) { 10598 throw new SecurityException("Requires permission " 10599 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10600 } 10601 10602 synchronized (this) { 10603 final long now = SystemClock.uptimeMillis(); 10604 final long timeSinceLastIdle = now - mLastIdleTime; 10605 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10606 mLastIdleTime = now; 10607 mLowRamTimeSinceLastIdle = 0; 10608 if (mLowRamStartTime != 0) { 10609 mLowRamStartTime = now; 10610 } 10611 10612 StringBuilder sb = new StringBuilder(128); 10613 sb.append("Idle maintenance over "); 10614 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10615 sb.append(" low RAM for "); 10616 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10617 Slog.i(TAG, sb.toString()); 10618 10619 // If at least 1/3 of our time since the last idle period has been spent 10620 // with RAM low, then we want to kill processes. 10621 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10622 10623 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10624 ProcessRecord proc = mLruProcesses.get(i); 10625 if (proc.notCachedSinceIdle) { 10626 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10627 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10628 if (doKilling && proc.initialIdlePss != 0 10629 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10630 proc.kill("idle maint (pss " + proc.lastPss 10631 + " from " + proc.initialIdlePss + ")", true); 10632 } 10633 } 10634 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10635 proc.notCachedSinceIdle = true; 10636 proc.initialIdlePss = 0; 10637 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10638 isSleeping(), now); 10639 } 10640 } 10641 10642 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10643 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10644 } 10645 } 10646 10647 private void retrieveSettings() { 10648 final ContentResolver resolver = mContext.getContentResolver(); 10649 String debugApp = Settings.Global.getString( 10650 resolver, Settings.Global.DEBUG_APP); 10651 boolean waitForDebugger = Settings.Global.getInt( 10652 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10653 boolean alwaysFinishActivities = Settings.Global.getInt( 10654 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10655 boolean forceRtl = Settings.Global.getInt( 10656 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10657 // Transfer any global setting for forcing RTL layout, into a System Property 10658 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10659 10660 Configuration configuration = new Configuration(); 10661 Settings.System.getConfiguration(resolver, configuration); 10662 if (forceRtl) { 10663 // This will take care of setting the correct layout direction flags 10664 configuration.setLayoutDirection(configuration.locale); 10665 } 10666 10667 synchronized (this) { 10668 mDebugApp = mOrigDebugApp = debugApp; 10669 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10670 mAlwaysFinishActivities = alwaysFinishActivities; 10671 // This happens before any activities are started, so we can 10672 // change mConfiguration in-place. 10673 updateConfigurationLocked(configuration, null, false, true); 10674 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10675 } 10676 } 10677 10678 public boolean testIsSystemReady() { 10679 // no need to synchronize(this) just to read & return the value 10680 return mSystemReady; 10681 } 10682 10683 private static File getCalledPreBootReceiversFile() { 10684 File dataDir = Environment.getDataDirectory(); 10685 File systemDir = new File(dataDir, "system"); 10686 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10687 return fname; 10688 } 10689 10690 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10691 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10692 File file = getCalledPreBootReceiversFile(); 10693 FileInputStream fis = null; 10694 try { 10695 fis = new FileInputStream(file); 10696 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10697 int fvers = dis.readInt(); 10698 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10699 String vers = dis.readUTF(); 10700 String codename = dis.readUTF(); 10701 String build = dis.readUTF(); 10702 if (android.os.Build.VERSION.RELEASE.equals(vers) 10703 && android.os.Build.VERSION.CODENAME.equals(codename) 10704 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10705 int num = dis.readInt(); 10706 while (num > 0) { 10707 num--; 10708 String pkg = dis.readUTF(); 10709 String cls = dis.readUTF(); 10710 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10711 } 10712 } 10713 } 10714 } catch (FileNotFoundException e) { 10715 } catch (IOException e) { 10716 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10717 } finally { 10718 if (fis != null) { 10719 try { 10720 fis.close(); 10721 } catch (IOException e) { 10722 } 10723 } 10724 } 10725 return lastDoneReceivers; 10726 } 10727 10728 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10729 File file = getCalledPreBootReceiversFile(); 10730 FileOutputStream fos = null; 10731 DataOutputStream dos = null; 10732 try { 10733 fos = new FileOutputStream(file); 10734 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10735 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10736 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10737 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10738 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10739 dos.writeInt(list.size()); 10740 for (int i=0; i<list.size(); i++) { 10741 dos.writeUTF(list.get(i).getPackageName()); 10742 dos.writeUTF(list.get(i).getClassName()); 10743 } 10744 } catch (IOException e) { 10745 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10746 file.delete(); 10747 } finally { 10748 FileUtils.sync(fos); 10749 if (dos != null) { 10750 try { 10751 dos.close(); 10752 } catch (IOException e) { 10753 // TODO Auto-generated catch block 10754 e.printStackTrace(); 10755 } 10756 } 10757 } 10758 } 10759 10760 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10761 ArrayList<ComponentName> doneReceivers, int userId) { 10762 boolean waitingUpdate = false; 10763 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10764 List<ResolveInfo> ris = null; 10765 try { 10766 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10767 intent, null, 0, userId); 10768 } catch (RemoteException e) { 10769 } 10770 if (ris != null) { 10771 for (int i=ris.size()-1; i>=0; i--) { 10772 if ((ris.get(i).activityInfo.applicationInfo.flags 10773 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10774 ris.remove(i); 10775 } 10776 } 10777 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10778 10779 // For User 0, load the version number. When delivering to a new user, deliver 10780 // to all receivers. 10781 if (userId == UserHandle.USER_OWNER) { 10782 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10783 for (int i=0; i<ris.size(); i++) { 10784 ActivityInfo ai = ris.get(i).activityInfo; 10785 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10786 if (lastDoneReceivers.contains(comp)) { 10787 // We already did the pre boot receiver for this app with the current 10788 // platform version, so don't do it again... 10789 ris.remove(i); 10790 i--; 10791 // ...however, do keep it as one that has been done, so we don't 10792 // forget about it when rewriting the file of last done receivers. 10793 doneReceivers.add(comp); 10794 } 10795 } 10796 } 10797 10798 // If primary user, send broadcast to all available users, else just to userId 10799 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10800 : new int[] { userId }; 10801 for (int i = 0; i < ris.size(); i++) { 10802 ActivityInfo ai = ris.get(i).activityInfo; 10803 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10804 doneReceivers.add(comp); 10805 intent.setComponent(comp); 10806 for (int j=0; j<users.length; j++) { 10807 IIntentReceiver finisher = null; 10808 // On last receiver and user, set up a completion callback 10809 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10810 finisher = new IIntentReceiver.Stub() { 10811 public void performReceive(Intent intent, int resultCode, 10812 String data, Bundle extras, boolean ordered, 10813 boolean sticky, int sendingUser) { 10814 // The raw IIntentReceiver interface is called 10815 // with the AM lock held, so redispatch to 10816 // execute our code without the lock. 10817 mHandler.post(onFinishCallback); 10818 } 10819 }; 10820 } 10821 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10822 + " for user " + users[j]); 10823 broadcastIntentLocked(null, null, intent, null, finisher, 10824 0, null, null, null, AppOpsManager.OP_NONE, 10825 true, false, MY_PID, Process.SYSTEM_UID, 10826 users[j]); 10827 if (finisher != null) { 10828 waitingUpdate = true; 10829 } 10830 } 10831 } 10832 } 10833 10834 return waitingUpdate; 10835 } 10836 10837 public void systemReady(final Runnable goingCallback) { 10838 synchronized(this) { 10839 if (mSystemReady) { 10840 // If we're done calling all the receivers, run the next "boot phase" passed in 10841 // by the SystemServer 10842 if (goingCallback != null) { 10843 goingCallback.run(); 10844 } 10845 return; 10846 } 10847 10848 // Make sure we have the current profile info, since it is needed for 10849 // security checks. 10850 updateCurrentProfileIdsLocked(); 10851 10852 if (mRecentTasks == null) { 10853 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10854 if (!mRecentTasks.isEmpty()) { 10855 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10856 } 10857 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10858 mTaskPersister.startPersisting(); 10859 } 10860 10861 // Check to see if there are any update receivers to run. 10862 if (!mDidUpdate) { 10863 if (mWaitingUpdate) { 10864 return; 10865 } 10866 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10867 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10868 public void run() { 10869 synchronized (ActivityManagerService.this) { 10870 mDidUpdate = true; 10871 } 10872 writeLastDonePreBootReceivers(doneReceivers); 10873 showBootMessage(mContext.getText( 10874 R.string.android_upgrading_complete), 10875 false); 10876 systemReady(goingCallback); 10877 } 10878 }, doneReceivers, UserHandle.USER_OWNER); 10879 10880 if (mWaitingUpdate) { 10881 return; 10882 } 10883 mDidUpdate = true; 10884 } 10885 10886 mAppOpsService.systemReady(); 10887 mSystemReady = true; 10888 } 10889 10890 ArrayList<ProcessRecord> procsToKill = null; 10891 synchronized(mPidsSelfLocked) { 10892 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10893 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10894 if (!isAllowedWhileBooting(proc.info)){ 10895 if (procsToKill == null) { 10896 procsToKill = new ArrayList<ProcessRecord>(); 10897 } 10898 procsToKill.add(proc); 10899 } 10900 } 10901 } 10902 10903 synchronized(this) { 10904 if (procsToKill != null) { 10905 for (int i=procsToKill.size()-1; i>=0; i--) { 10906 ProcessRecord proc = procsToKill.get(i); 10907 Slog.i(TAG, "Removing system update proc: " + proc); 10908 removeProcessLocked(proc, true, false, "system update done"); 10909 } 10910 } 10911 10912 // Now that we have cleaned up any update processes, we 10913 // are ready to start launching real processes and know that 10914 // we won't trample on them any more. 10915 mProcessesReady = true; 10916 } 10917 10918 Slog.i(TAG, "System now ready"); 10919 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10920 SystemClock.uptimeMillis()); 10921 10922 synchronized(this) { 10923 // Make sure we have no pre-ready processes sitting around. 10924 10925 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10926 ResolveInfo ri = mContext.getPackageManager() 10927 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10928 STOCK_PM_FLAGS); 10929 CharSequence errorMsg = null; 10930 if (ri != null) { 10931 ActivityInfo ai = ri.activityInfo; 10932 ApplicationInfo app = ai.applicationInfo; 10933 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10934 mTopAction = Intent.ACTION_FACTORY_TEST; 10935 mTopData = null; 10936 mTopComponent = new ComponentName(app.packageName, 10937 ai.name); 10938 } else { 10939 errorMsg = mContext.getResources().getText( 10940 com.android.internal.R.string.factorytest_not_system); 10941 } 10942 } else { 10943 errorMsg = mContext.getResources().getText( 10944 com.android.internal.R.string.factorytest_no_action); 10945 } 10946 if (errorMsg != null) { 10947 mTopAction = null; 10948 mTopData = null; 10949 mTopComponent = null; 10950 Message msg = Message.obtain(); 10951 msg.what = SHOW_FACTORY_ERROR_MSG; 10952 msg.getData().putCharSequence("msg", errorMsg); 10953 mHandler.sendMessage(msg); 10954 } 10955 } 10956 } 10957 10958 retrieveSettings(); 10959 10960 synchronized (this) { 10961 readGrantedUriPermissionsLocked(); 10962 } 10963 10964 if (goingCallback != null) goingCallback.run(); 10965 10966 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10967 Integer.toString(mCurrentUserId), mCurrentUserId); 10968 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10969 Integer.toString(mCurrentUserId), mCurrentUserId); 10970 mSystemServiceManager.startUser(mCurrentUserId); 10971 10972 synchronized (this) { 10973 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10974 try { 10975 List apps = AppGlobals.getPackageManager(). 10976 getPersistentApplications(STOCK_PM_FLAGS); 10977 if (apps != null) { 10978 int N = apps.size(); 10979 int i; 10980 for (i=0; i<N; i++) { 10981 ApplicationInfo info 10982 = (ApplicationInfo)apps.get(i); 10983 if (info != null && 10984 !info.packageName.equals("android")) { 10985 addAppLocked(info, false, null /* ABI override */); 10986 } 10987 } 10988 } 10989 } catch (RemoteException ex) { 10990 // pm is in same process, this will never happen. 10991 } 10992 } 10993 10994 // Start up initial activity. 10995 mBooting = true; 10996 10997 try { 10998 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10999 Message msg = Message.obtain(); 11000 msg.what = SHOW_UID_ERROR_MSG; 11001 mHandler.sendMessage(msg); 11002 } 11003 } catch (RemoteException e) { 11004 } 11005 11006 long ident = Binder.clearCallingIdentity(); 11007 try { 11008 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11009 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11010 | Intent.FLAG_RECEIVER_FOREGROUND); 11011 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11012 broadcastIntentLocked(null, null, intent, 11013 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11014 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11015 intent = new Intent(Intent.ACTION_USER_STARTING); 11016 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11017 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11018 broadcastIntentLocked(null, null, intent, 11019 null, new IIntentReceiver.Stub() { 11020 @Override 11021 public void performReceive(Intent intent, int resultCode, String data, 11022 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11023 throws RemoteException { 11024 } 11025 }, 0, null, null, 11026 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11027 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11028 } catch (Throwable t) { 11029 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11030 } finally { 11031 Binder.restoreCallingIdentity(ident); 11032 } 11033 mStackSupervisor.resumeTopActivitiesLocked(); 11034 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11035 } 11036 } 11037 11038 private boolean makeAppCrashingLocked(ProcessRecord app, 11039 String shortMsg, String longMsg, String stackTrace) { 11040 app.crashing = true; 11041 app.crashingReport = generateProcessError(app, 11042 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11043 startAppProblemLocked(app); 11044 app.stopFreezingAllLocked(); 11045 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11046 } 11047 11048 private void makeAppNotRespondingLocked(ProcessRecord app, 11049 String activity, String shortMsg, String longMsg) { 11050 app.notResponding = true; 11051 app.notRespondingReport = generateProcessError(app, 11052 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11053 activity, shortMsg, longMsg, null); 11054 startAppProblemLocked(app); 11055 app.stopFreezingAllLocked(); 11056 } 11057 11058 /** 11059 * Generate a process error record, suitable for attachment to a ProcessRecord. 11060 * 11061 * @param app The ProcessRecord in which the error occurred. 11062 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11063 * ActivityManager.AppErrorStateInfo 11064 * @param activity The activity associated with the crash, if known. 11065 * @param shortMsg Short message describing the crash. 11066 * @param longMsg Long message describing the crash. 11067 * @param stackTrace Full crash stack trace, may be null. 11068 * 11069 * @return Returns a fully-formed AppErrorStateInfo record. 11070 */ 11071 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11072 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11073 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11074 11075 report.condition = condition; 11076 report.processName = app.processName; 11077 report.pid = app.pid; 11078 report.uid = app.info.uid; 11079 report.tag = activity; 11080 report.shortMsg = shortMsg; 11081 report.longMsg = longMsg; 11082 report.stackTrace = stackTrace; 11083 11084 return report; 11085 } 11086 11087 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11088 synchronized (this) { 11089 app.crashing = false; 11090 app.crashingReport = null; 11091 app.notResponding = false; 11092 app.notRespondingReport = null; 11093 if (app.anrDialog == fromDialog) { 11094 app.anrDialog = null; 11095 } 11096 if (app.waitDialog == fromDialog) { 11097 app.waitDialog = null; 11098 } 11099 if (app.pid > 0 && app.pid != MY_PID) { 11100 handleAppCrashLocked(app, null, null, null); 11101 app.kill("user request after error", true); 11102 } 11103 } 11104 } 11105 11106 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11107 String stackTrace) { 11108 long now = SystemClock.uptimeMillis(); 11109 11110 Long crashTime; 11111 if (!app.isolated) { 11112 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11113 } else { 11114 crashTime = null; 11115 } 11116 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11117 // This process loses! 11118 Slog.w(TAG, "Process " + app.info.processName 11119 + " has crashed too many times: killing!"); 11120 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11121 app.userId, app.info.processName, app.uid); 11122 mStackSupervisor.handleAppCrashLocked(app); 11123 if (!app.persistent) { 11124 // We don't want to start this process again until the user 11125 // explicitly does so... but for persistent process, we really 11126 // need to keep it running. If a persistent process is actually 11127 // repeatedly crashing, then badness for everyone. 11128 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11129 app.info.processName); 11130 if (!app.isolated) { 11131 // XXX We don't have a way to mark isolated processes 11132 // as bad, since they don't have a peristent identity. 11133 mBadProcesses.put(app.info.processName, app.uid, 11134 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11135 mProcessCrashTimes.remove(app.info.processName, app.uid); 11136 } 11137 app.bad = true; 11138 app.removed = true; 11139 // Don't let services in this process be restarted and potentially 11140 // annoy the user repeatedly. Unless it is persistent, since those 11141 // processes run critical code. 11142 removeProcessLocked(app, false, false, "crash"); 11143 mStackSupervisor.resumeTopActivitiesLocked(); 11144 return false; 11145 } 11146 mStackSupervisor.resumeTopActivitiesLocked(); 11147 } else { 11148 mStackSupervisor.finishTopRunningActivityLocked(app); 11149 } 11150 11151 // Bump up the crash count of any services currently running in the proc. 11152 for (int i=app.services.size()-1; i>=0; i--) { 11153 // Any services running in the application need to be placed 11154 // back in the pending list. 11155 ServiceRecord sr = app.services.valueAt(i); 11156 sr.crashCount++; 11157 } 11158 11159 // If the crashing process is what we consider to be the "home process" and it has been 11160 // replaced by a third-party app, clear the package preferred activities from packages 11161 // with a home activity running in the process to prevent a repeatedly crashing app 11162 // from blocking the user to manually clear the list. 11163 final ArrayList<ActivityRecord> activities = app.activities; 11164 if (app == mHomeProcess && activities.size() > 0 11165 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11166 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11167 final ActivityRecord r = activities.get(activityNdx); 11168 if (r.isHomeActivity()) { 11169 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11170 try { 11171 ActivityThread.getPackageManager() 11172 .clearPackagePreferredActivities(r.packageName); 11173 } catch (RemoteException c) { 11174 // pm is in same process, this will never happen. 11175 } 11176 } 11177 } 11178 } 11179 11180 if (!app.isolated) { 11181 // XXX Can't keep track of crash times for isolated processes, 11182 // because they don't have a perisistent identity. 11183 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11184 } 11185 11186 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11187 return true; 11188 } 11189 11190 void startAppProblemLocked(ProcessRecord app) { 11191 // If this app is not running under the current user, then we 11192 // can't give it a report button because that would require 11193 // launching the report UI under a different user. 11194 app.errorReportReceiver = null; 11195 11196 for (int userId : mCurrentProfileIds) { 11197 if (app.userId == userId) { 11198 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11199 mContext, app.info.packageName, app.info.flags); 11200 } 11201 } 11202 skipCurrentReceiverLocked(app); 11203 } 11204 11205 void skipCurrentReceiverLocked(ProcessRecord app) { 11206 for (BroadcastQueue queue : mBroadcastQueues) { 11207 queue.skipCurrentReceiverLocked(app); 11208 } 11209 } 11210 11211 /** 11212 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11213 * The application process will exit immediately after this call returns. 11214 * @param app object of the crashing app, null for the system server 11215 * @param crashInfo describing the exception 11216 */ 11217 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11218 ProcessRecord r = findAppProcess(app, "Crash"); 11219 final String processName = app == null ? "system_server" 11220 : (r == null ? "unknown" : r.processName); 11221 11222 handleApplicationCrashInner("crash", r, processName, crashInfo); 11223 } 11224 11225 /* Native crash reporting uses this inner version because it needs to be somewhat 11226 * decoupled from the AM-managed cleanup lifecycle 11227 */ 11228 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11229 ApplicationErrorReport.CrashInfo crashInfo) { 11230 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11231 UserHandle.getUserId(Binder.getCallingUid()), processName, 11232 r == null ? -1 : r.info.flags, 11233 crashInfo.exceptionClassName, 11234 crashInfo.exceptionMessage, 11235 crashInfo.throwFileName, 11236 crashInfo.throwLineNumber); 11237 11238 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11239 11240 crashApplication(r, crashInfo); 11241 } 11242 11243 public void handleApplicationStrictModeViolation( 11244 IBinder app, 11245 int violationMask, 11246 StrictMode.ViolationInfo info) { 11247 ProcessRecord r = findAppProcess(app, "StrictMode"); 11248 if (r == null) { 11249 return; 11250 } 11251 11252 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11253 Integer stackFingerprint = info.hashCode(); 11254 boolean logIt = true; 11255 synchronized (mAlreadyLoggedViolatedStacks) { 11256 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11257 logIt = false; 11258 // TODO: sub-sample into EventLog for these, with 11259 // the info.durationMillis? Then we'd get 11260 // the relative pain numbers, without logging all 11261 // the stack traces repeatedly. We'd want to do 11262 // likewise in the client code, which also does 11263 // dup suppression, before the Binder call. 11264 } else { 11265 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11266 mAlreadyLoggedViolatedStacks.clear(); 11267 } 11268 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11269 } 11270 } 11271 if (logIt) { 11272 logStrictModeViolationToDropBox(r, info); 11273 } 11274 } 11275 11276 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11277 AppErrorResult result = new AppErrorResult(); 11278 synchronized (this) { 11279 final long origId = Binder.clearCallingIdentity(); 11280 11281 Message msg = Message.obtain(); 11282 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11283 HashMap<String, Object> data = new HashMap<String, Object>(); 11284 data.put("result", result); 11285 data.put("app", r); 11286 data.put("violationMask", violationMask); 11287 data.put("info", info); 11288 msg.obj = data; 11289 mHandler.sendMessage(msg); 11290 11291 Binder.restoreCallingIdentity(origId); 11292 } 11293 int res = result.get(); 11294 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11295 } 11296 } 11297 11298 // Depending on the policy in effect, there could be a bunch of 11299 // these in quick succession so we try to batch these together to 11300 // minimize disk writes, number of dropbox entries, and maximize 11301 // compression, by having more fewer, larger records. 11302 private void logStrictModeViolationToDropBox( 11303 ProcessRecord process, 11304 StrictMode.ViolationInfo info) { 11305 if (info == null) { 11306 return; 11307 } 11308 final boolean isSystemApp = process == null || 11309 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11310 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11311 final String processName = process == null ? "unknown" : process.processName; 11312 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11313 final DropBoxManager dbox = (DropBoxManager) 11314 mContext.getSystemService(Context.DROPBOX_SERVICE); 11315 11316 // Exit early if the dropbox isn't configured to accept this report type. 11317 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11318 11319 boolean bufferWasEmpty; 11320 boolean needsFlush; 11321 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11322 synchronized (sb) { 11323 bufferWasEmpty = sb.length() == 0; 11324 appendDropBoxProcessHeaders(process, processName, sb); 11325 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11326 sb.append("System-App: ").append(isSystemApp).append("\n"); 11327 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11328 if (info.violationNumThisLoop != 0) { 11329 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11330 } 11331 if (info.numAnimationsRunning != 0) { 11332 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11333 } 11334 if (info.broadcastIntentAction != null) { 11335 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11336 } 11337 if (info.durationMillis != -1) { 11338 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11339 } 11340 if (info.numInstances != -1) { 11341 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11342 } 11343 if (info.tags != null) { 11344 for (String tag : info.tags) { 11345 sb.append("Span-Tag: ").append(tag).append("\n"); 11346 } 11347 } 11348 sb.append("\n"); 11349 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11350 sb.append(info.crashInfo.stackTrace); 11351 } 11352 sb.append("\n"); 11353 11354 // Only buffer up to ~64k. Various logging bits truncate 11355 // things at 128k. 11356 needsFlush = (sb.length() > 64 * 1024); 11357 } 11358 11359 // Flush immediately if the buffer's grown too large, or this 11360 // is a non-system app. Non-system apps are isolated with a 11361 // different tag & policy and not batched. 11362 // 11363 // Batching is useful during internal testing with 11364 // StrictMode settings turned up high. Without batching, 11365 // thousands of separate files could be created on boot. 11366 if (!isSystemApp || needsFlush) { 11367 new Thread("Error dump: " + dropboxTag) { 11368 @Override 11369 public void run() { 11370 String report; 11371 synchronized (sb) { 11372 report = sb.toString(); 11373 sb.delete(0, sb.length()); 11374 sb.trimToSize(); 11375 } 11376 if (report.length() != 0) { 11377 dbox.addText(dropboxTag, report); 11378 } 11379 } 11380 }.start(); 11381 return; 11382 } 11383 11384 // System app batching: 11385 if (!bufferWasEmpty) { 11386 // An existing dropbox-writing thread is outstanding, so 11387 // we don't need to start it up. The existing thread will 11388 // catch the buffer appends we just did. 11389 return; 11390 } 11391 11392 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11393 // (After this point, we shouldn't access AMS internal data structures.) 11394 new Thread("Error dump: " + dropboxTag) { 11395 @Override 11396 public void run() { 11397 // 5 second sleep to let stacks arrive and be batched together 11398 try { 11399 Thread.sleep(5000); // 5 seconds 11400 } catch (InterruptedException e) {} 11401 11402 String errorReport; 11403 synchronized (mStrictModeBuffer) { 11404 errorReport = mStrictModeBuffer.toString(); 11405 if (errorReport.length() == 0) { 11406 return; 11407 } 11408 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11409 mStrictModeBuffer.trimToSize(); 11410 } 11411 dbox.addText(dropboxTag, errorReport); 11412 } 11413 }.start(); 11414 } 11415 11416 /** 11417 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11418 * @param app object of the crashing app, null for the system server 11419 * @param tag reported by the caller 11420 * @param system whether this wtf is coming from the system 11421 * @param crashInfo describing the context of the error 11422 * @return true if the process should exit immediately (WTF is fatal) 11423 */ 11424 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11425 final ApplicationErrorReport.CrashInfo crashInfo) { 11426 final ProcessRecord r = findAppProcess(app, "WTF"); 11427 final String processName = app == null ? "system_server" 11428 : (r == null ? "unknown" : r.processName); 11429 11430 EventLog.writeEvent(EventLogTags.AM_WTF, 11431 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11432 processName, 11433 r == null ? -1 : r.info.flags, 11434 tag, crashInfo.exceptionMessage); 11435 11436 if (system) { 11437 // If this is coming from the system, we could very well have low-level 11438 // system locks held, so we want to do this all asynchronously. And we 11439 // never want this to become fatal, so there is that too. 11440 mHandler.post(new Runnable() { 11441 @Override public void run() { 11442 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11443 crashInfo); 11444 } 11445 }); 11446 return false; 11447 } 11448 11449 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11450 11451 if (r != null && r.pid != Process.myPid() && 11452 Settings.Global.getInt(mContext.getContentResolver(), 11453 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11454 crashApplication(r, crashInfo); 11455 return true; 11456 } else { 11457 return false; 11458 } 11459 } 11460 11461 /** 11462 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11463 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11464 */ 11465 private ProcessRecord findAppProcess(IBinder app, String reason) { 11466 if (app == null) { 11467 return null; 11468 } 11469 11470 synchronized (this) { 11471 final int NP = mProcessNames.getMap().size(); 11472 for (int ip=0; ip<NP; ip++) { 11473 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11474 final int NA = apps.size(); 11475 for (int ia=0; ia<NA; ia++) { 11476 ProcessRecord p = apps.valueAt(ia); 11477 if (p.thread != null && p.thread.asBinder() == app) { 11478 return p; 11479 } 11480 } 11481 } 11482 11483 Slog.w(TAG, "Can't find mystery application for " + reason 11484 + " from pid=" + Binder.getCallingPid() 11485 + " uid=" + Binder.getCallingUid() + ": " + app); 11486 return null; 11487 } 11488 } 11489 11490 /** 11491 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11492 * to append various headers to the dropbox log text. 11493 */ 11494 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11495 StringBuilder sb) { 11496 // Watchdog thread ends up invoking this function (with 11497 // a null ProcessRecord) to add the stack file to dropbox. 11498 // Do not acquire a lock on this (am) in such cases, as it 11499 // could cause a potential deadlock, if and when watchdog 11500 // is invoked due to unavailability of lock on am and it 11501 // would prevent watchdog from killing system_server. 11502 if (process == null) { 11503 sb.append("Process: ").append(processName).append("\n"); 11504 return; 11505 } 11506 // Note: ProcessRecord 'process' is guarded by the service 11507 // instance. (notably process.pkgList, which could otherwise change 11508 // concurrently during execution of this method) 11509 synchronized (this) { 11510 sb.append("Process: ").append(processName).append("\n"); 11511 int flags = process.info.flags; 11512 IPackageManager pm = AppGlobals.getPackageManager(); 11513 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11514 for (int ip=0; ip<process.pkgList.size(); ip++) { 11515 String pkg = process.pkgList.keyAt(ip); 11516 sb.append("Package: ").append(pkg); 11517 try { 11518 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11519 if (pi != null) { 11520 sb.append(" v").append(pi.versionCode); 11521 if (pi.versionName != null) { 11522 sb.append(" (").append(pi.versionName).append(")"); 11523 } 11524 } 11525 } catch (RemoteException e) { 11526 Slog.e(TAG, "Error getting package info: " + pkg, e); 11527 } 11528 sb.append("\n"); 11529 } 11530 } 11531 } 11532 11533 private static String processClass(ProcessRecord process) { 11534 if (process == null || process.pid == MY_PID) { 11535 return "system_server"; 11536 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11537 return "system_app"; 11538 } else { 11539 return "data_app"; 11540 } 11541 } 11542 11543 /** 11544 * Write a description of an error (crash, WTF, ANR) to the drop box. 11545 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11546 * @param process which caused the error, null means the system server 11547 * @param activity which triggered the error, null if unknown 11548 * @param parent activity related to the error, null if unknown 11549 * @param subject line related to the error, null if absent 11550 * @param report in long form describing the error, null if absent 11551 * @param logFile to include in the report, null if none 11552 * @param crashInfo giving an application stack trace, null if absent 11553 */ 11554 public void addErrorToDropBox(String eventType, 11555 ProcessRecord process, String processName, ActivityRecord activity, 11556 ActivityRecord parent, String subject, 11557 final String report, final File logFile, 11558 final ApplicationErrorReport.CrashInfo crashInfo) { 11559 // NOTE -- this must never acquire the ActivityManagerService lock, 11560 // otherwise the watchdog may be prevented from resetting the system. 11561 11562 final String dropboxTag = processClass(process) + "_" + eventType; 11563 final DropBoxManager dbox = (DropBoxManager) 11564 mContext.getSystemService(Context.DROPBOX_SERVICE); 11565 11566 // Exit early if the dropbox isn't configured to accept this report type. 11567 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11568 11569 final StringBuilder sb = new StringBuilder(1024); 11570 appendDropBoxProcessHeaders(process, processName, sb); 11571 if (activity != null) { 11572 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11573 } 11574 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11575 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11576 } 11577 if (parent != null && parent != activity) { 11578 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11579 } 11580 if (subject != null) { 11581 sb.append("Subject: ").append(subject).append("\n"); 11582 } 11583 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11584 if (Debug.isDebuggerConnected()) { 11585 sb.append("Debugger: Connected\n"); 11586 } 11587 sb.append("\n"); 11588 11589 // Do the rest in a worker thread to avoid blocking the caller on I/O 11590 // (After this point, we shouldn't access AMS internal data structures.) 11591 Thread worker = new Thread("Error dump: " + dropboxTag) { 11592 @Override 11593 public void run() { 11594 if (report != null) { 11595 sb.append(report); 11596 } 11597 if (logFile != null) { 11598 try { 11599 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11600 "\n\n[[TRUNCATED]]")); 11601 } catch (IOException e) { 11602 Slog.e(TAG, "Error reading " + logFile, e); 11603 } 11604 } 11605 if (crashInfo != null && crashInfo.stackTrace != null) { 11606 sb.append(crashInfo.stackTrace); 11607 } 11608 11609 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11610 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11611 if (lines > 0) { 11612 sb.append("\n"); 11613 11614 // Merge several logcat streams, and take the last N lines 11615 InputStreamReader input = null; 11616 try { 11617 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11618 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11619 "-b", "crash", 11620 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11621 11622 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11623 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11624 input = new InputStreamReader(logcat.getInputStream()); 11625 11626 int num; 11627 char[] buf = new char[8192]; 11628 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11629 } catch (IOException e) { 11630 Slog.e(TAG, "Error running logcat", e); 11631 } finally { 11632 if (input != null) try { input.close(); } catch (IOException e) {} 11633 } 11634 } 11635 11636 dbox.addText(dropboxTag, sb.toString()); 11637 } 11638 }; 11639 11640 if (process == null) { 11641 // If process is null, we are being called from some internal code 11642 // and may be about to die -- run this synchronously. 11643 worker.run(); 11644 } else { 11645 worker.start(); 11646 } 11647 } 11648 11649 /** 11650 * Bring up the "unexpected error" dialog box for a crashing app. 11651 * Deal with edge cases (intercepts from instrumented applications, 11652 * ActivityController, error intent receivers, that sort of thing). 11653 * @param r the application crashing 11654 * @param crashInfo describing the failure 11655 */ 11656 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11657 long timeMillis = System.currentTimeMillis(); 11658 String shortMsg = crashInfo.exceptionClassName; 11659 String longMsg = crashInfo.exceptionMessage; 11660 String stackTrace = crashInfo.stackTrace; 11661 if (shortMsg != null && longMsg != null) { 11662 longMsg = shortMsg + ": " + longMsg; 11663 } else if (shortMsg != null) { 11664 longMsg = shortMsg; 11665 } 11666 11667 AppErrorResult result = new AppErrorResult(); 11668 synchronized (this) { 11669 if (mController != null) { 11670 try { 11671 String name = r != null ? r.processName : null; 11672 int pid = r != null ? r.pid : Binder.getCallingPid(); 11673 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11674 if (!mController.appCrashed(name, pid, 11675 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11676 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11677 && "Native crash".equals(crashInfo.exceptionClassName)) { 11678 Slog.w(TAG, "Skip killing native crashed app " + name 11679 + "(" + pid + ") during testing"); 11680 } else { 11681 Slog.w(TAG, "Force-killing crashed app " + name 11682 + " at watcher's request"); 11683 if (r != null) { 11684 r.kill("crash", true); 11685 } else { 11686 // Huh. 11687 Process.killProcess(pid); 11688 Process.killProcessGroup(uid, pid); 11689 } 11690 } 11691 return; 11692 } 11693 } catch (RemoteException e) { 11694 mController = null; 11695 Watchdog.getInstance().setActivityController(null); 11696 } 11697 } 11698 11699 final long origId = Binder.clearCallingIdentity(); 11700 11701 // If this process is running instrumentation, finish it. 11702 if (r != null && r.instrumentationClass != null) { 11703 Slog.w(TAG, "Error in app " + r.processName 11704 + " running instrumentation " + r.instrumentationClass + ":"); 11705 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11706 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11707 Bundle info = new Bundle(); 11708 info.putString("shortMsg", shortMsg); 11709 info.putString("longMsg", longMsg); 11710 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11711 Binder.restoreCallingIdentity(origId); 11712 return; 11713 } 11714 11715 // If we can't identify the process or it's already exceeded its crash quota, 11716 // quit right away without showing a crash dialog. 11717 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11718 Binder.restoreCallingIdentity(origId); 11719 return; 11720 } 11721 11722 Message msg = Message.obtain(); 11723 msg.what = SHOW_ERROR_MSG; 11724 HashMap data = new HashMap(); 11725 data.put("result", result); 11726 data.put("app", r); 11727 msg.obj = data; 11728 mHandler.sendMessage(msg); 11729 11730 Binder.restoreCallingIdentity(origId); 11731 } 11732 11733 int res = result.get(); 11734 11735 Intent appErrorIntent = null; 11736 synchronized (this) { 11737 if (r != null && !r.isolated) { 11738 // XXX Can't keep track of crash time for isolated processes, 11739 // since they don't have a persistent identity. 11740 mProcessCrashTimes.put(r.info.processName, r.uid, 11741 SystemClock.uptimeMillis()); 11742 } 11743 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11744 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11745 } 11746 } 11747 11748 if (appErrorIntent != null) { 11749 try { 11750 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11751 } catch (ActivityNotFoundException e) { 11752 Slog.w(TAG, "bug report receiver dissappeared", e); 11753 } 11754 } 11755 } 11756 11757 Intent createAppErrorIntentLocked(ProcessRecord r, 11758 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11759 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11760 if (report == null) { 11761 return null; 11762 } 11763 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11764 result.setComponent(r.errorReportReceiver); 11765 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11766 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11767 return result; 11768 } 11769 11770 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11771 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11772 if (r.errorReportReceiver == null) { 11773 return null; 11774 } 11775 11776 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11777 return null; 11778 } 11779 11780 ApplicationErrorReport report = new ApplicationErrorReport(); 11781 report.packageName = r.info.packageName; 11782 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11783 report.processName = r.processName; 11784 report.time = timeMillis; 11785 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11786 11787 if (r.crashing || r.forceCrashReport) { 11788 report.type = ApplicationErrorReport.TYPE_CRASH; 11789 report.crashInfo = crashInfo; 11790 } else if (r.notResponding) { 11791 report.type = ApplicationErrorReport.TYPE_ANR; 11792 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11793 11794 report.anrInfo.activity = r.notRespondingReport.tag; 11795 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11796 report.anrInfo.info = r.notRespondingReport.longMsg; 11797 } 11798 11799 return report; 11800 } 11801 11802 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11803 enforceNotIsolatedCaller("getProcessesInErrorState"); 11804 // assume our apps are happy - lazy create the list 11805 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11806 11807 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11808 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11809 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11810 11811 synchronized (this) { 11812 11813 // iterate across all processes 11814 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11815 ProcessRecord app = mLruProcesses.get(i); 11816 if (!allUsers && app.userId != userId) { 11817 continue; 11818 } 11819 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11820 // This one's in trouble, so we'll generate a report for it 11821 // crashes are higher priority (in case there's a crash *and* an anr) 11822 ActivityManager.ProcessErrorStateInfo report = null; 11823 if (app.crashing) { 11824 report = app.crashingReport; 11825 } else if (app.notResponding) { 11826 report = app.notRespondingReport; 11827 } 11828 11829 if (report != null) { 11830 if (errList == null) { 11831 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11832 } 11833 errList.add(report); 11834 } else { 11835 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11836 " crashing = " + app.crashing + 11837 " notResponding = " + app.notResponding); 11838 } 11839 } 11840 } 11841 } 11842 11843 return errList; 11844 } 11845 11846 static int procStateToImportance(int procState, int memAdj, 11847 ActivityManager.RunningAppProcessInfo currApp) { 11848 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11849 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11850 currApp.lru = memAdj; 11851 } else { 11852 currApp.lru = 0; 11853 } 11854 return imp; 11855 } 11856 11857 private void fillInProcMemInfo(ProcessRecord app, 11858 ActivityManager.RunningAppProcessInfo outInfo) { 11859 outInfo.pid = app.pid; 11860 outInfo.uid = app.info.uid; 11861 if (mHeavyWeightProcess == app) { 11862 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11863 } 11864 if (app.persistent) { 11865 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11866 } 11867 if (app.activities.size() > 0) { 11868 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11869 } 11870 outInfo.lastTrimLevel = app.trimMemoryLevel; 11871 int adj = app.curAdj; 11872 int procState = app.curProcState; 11873 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11874 outInfo.importanceReasonCode = app.adjTypeCode; 11875 outInfo.processState = app.curProcState; 11876 } 11877 11878 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11879 enforceNotIsolatedCaller("getRunningAppProcesses"); 11880 // Lazy instantiation of list 11881 List<ActivityManager.RunningAppProcessInfo> runList = null; 11882 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11883 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11884 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11885 synchronized (this) { 11886 // Iterate across all processes 11887 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11888 ProcessRecord app = mLruProcesses.get(i); 11889 if (!allUsers && app.userId != userId) { 11890 continue; 11891 } 11892 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11893 // Generate process state info for running application 11894 ActivityManager.RunningAppProcessInfo currApp = 11895 new ActivityManager.RunningAppProcessInfo(app.processName, 11896 app.pid, app.getPackageList()); 11897 fillInProcMemInfo(app, currApp); 11898 if (app.adjSource instanceof ProcessRecord) { 11899 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11900 currApp.importanceReasonImportance = 11901 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11902 app.adjSourceProcState); 11903 } else if (app.adjSource instanceof ActivityRecord) { 11904 ActivityRecord r = (ActivityRecord)app.adjSource; 11905 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11906 } 11907 if (app.adjTarget instanceof ComponentName) { 11908 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11909 } 11910 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11911 // + " lru=" + currApp.lru); 11912 if (runList == null) { 11913 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11914 } 11915 runList.add(currApp); 11916 } 11917 } 11918 } 11919 return runList; 11920 } 11921 11922 public List<ApplicationInfo> getRunningExternalApplications() { 11923 enforceNotIsolatedCaller("getRunningExternalApplications"); 11924 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11925 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11926 if (runningApps != null && runningApps.size() > 0) { 11927 Set<String> extList = new HashSet<String>(); 11928 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11929 if (app.pkgList != null) { 11930 for (String pkg : app.pkgList) { 11931 extList.add(pkg); 11932 } 11933 } 11934 } 11935 IPackageManager pm = AppGlobals.getPackageManager(); 11936 for (String pkg : extList) { 11937 try { 11938 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11939 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11940 retList.add(info); 11941 } 11942 } catch (RemoteException e) { 11943 } 11944 } 11945 } 11946 return retList; 11947 } 11948 11949 @Override 11950 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11951 enforceNotIsolatedCaller("getMyMemoryState"); 11952 synchronized (this) { 11953 ProcessRecord proc; 11954 synchronized (mPidsSelfLocked) { 11955 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11956 } 11957 fillInProcMemInfo(proc, outInfo); 11958 } 11959 } 11960 11961 @Override 11962 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11963 if (checkCallingPermission(android.Manifest.permission.DUMP) 11964 != PackageManager.PERMISSION_GRANTED) { 11965 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11966 + Binder.getCallingPid() 11967 + ", uid=" + Binder.getCallingUid() 11968 + " without permission " 11969 + android.Manifest.permission.DUMP); 11970 return; 11971 } 11972 11973 boolean dumpAll = false; 11974 boolean dumpClient = false; 11975 String dumpPackage = null; 11976 11977 int opti = 0; 11978 while (opti < args.length) { 11979 String opt = args[opti]; 11980 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11981 break; 11982 } 11983 opti++; 11984 if ("-a".equals(opt)) { 11985 dumpAll = true; 11986 } else if ("-c".equals(opt)) { 11987 dumpClient = true; 11988 } else if ("-h".equals(opt)) { 11989 pw.println("Activity manager dump options:"); 11990 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11991 pw.println(" cmd may be one of:"); 11992 pw.println(" a[ctivities]: activity stack state"); 11993 pw.println(" r[recents]: recent activities state"); 11994 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11995 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11996 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11997 pw.println(" o[om]: out of memory management"); 11998 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11999 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12000 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12001 pw.println(" service [COMP_SPEC]: service client-side state"); 12002 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12003 pw.println(" all: dump all activities"); 12004 pw.println(" top: dump the top activity"); 12005 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12006 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12007 pw.println(" a partial substring in a component name, a"); 12008 pw.println(" hex object identifier."); 12009 pw.println(" -a: include all available server state."); 12010 pw.println(" -c: include client state."); 12011 return; 12012 } else { 12013 pw.println("Unknown argument: " + opt + "; use -h for help"); 12014 } 12015 } 12016 12017 long origId = Binder.clearCallingIdentity(); 12018 boolean more = false; 12019 // Is the caller requesting to dump a particular piece of data? 12020 if (opti < args.length) { 12021 String cmd = args[opti]; 12022 opti++; 12023 if ("activities".equals(cmd) || "a".equals(cmd)) { 12024 synchronized (this) { 12025 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12026 } 12027 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12028 synchronized (this) { 12029 dumpRecentsLocked(fd, pw, args, opti, true, null); 12030 } 12031 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12032 String[] newArgs; 12033 String name; 12034 if (opti >= args.length) { 12035 name = null; 12036 newArgs = EMPTY_STRING_ARRAY; 12037 } else { 12038 name = args[opti]; 12039 opti++; 12040 newArgs = new String[args.length - opti]; 12041 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12042 args.length - opti); 12043 } 12044 synchronized (this) { 12045 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12046 } 12047 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12048 String[] newArgs; 12049 String name; 12050 if (opti >= args.length) { 12051 name = null; 12052 newArgs = EMPTY_STRING_ARRAY; 12053 } else { 12054 name = args[opti]; 12055 opti++; 12056 newArgs = new String[args.length - opti]; 12057 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12058 args.length - opti); 12059 } 12060 synchronized (this) { 12061 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12062 } 12063 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12064 String[] newArgs; 12065 String name; 12066 if (opti >= args.length) { 12067 name = null; 12068 newArgs = EMPTY_STRING_ARRAY; 12069 } else { 12070 name = args[opti]; 12071 opti++; 12072 newArgs = new String[args.length - opti]; 12073 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12074 args.length - opti); 12075 } 12076 synchronized (this) { 12077 dumpProcessesLocked(fd, pw, args, opti, true, name); 12078 } 12079 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12080 synchronized (this) { 12081 dumpOomLocked(fd, pw, args, opti, true); 12082 } 12083 } else if ("provider".equals(cmd)) { 12084 String[] newArgs; 12085 String name; 12086 if (opti >= args.length) { 12087 name = null; 12088 newArgs = EMPTY_STRING_ARRAY; 12089 } else { 12090 name = args[opti]; 12091 opti++; 12092 newArgs = new String[args.length - opti]; 12093 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12094 } 12095 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12096 pw.println("No providers match: " + name); 12097 pw.println("Use -h for help."); 12098 } 12099 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12100 synchronized (this) { 12101 dumpProvidersLocked(fd, pw, args, opti, true, null); 12102 } 12103 } else if ("service".equals(cmd)) { 12104 String[] newArgs; 12105 String name; 12106 if (opti >= args.length) { 12107 name = null; 12108 newArgs = EMPTY_STRING_ARRAY; 12109 } else { 12110 name = args[opti]; 12111 opti++; 12112 newArgs = new String[args.length - opti]; 12113 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12114 args.length - opti); 12115 } 12116 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12117 pw.println("No services match: " + name); 12118 pw.println("Use -h for help."); 12119 } 12120 } else if ("package".equals(cmd)) { 12121 String[] newArgs; 12122 if (opti >= args.length) { 12123 pw.println("package: no package name specified"); 12124 pw.println("Use -h for help."); 12125 } else { 12126 dumpPackage = args[opti]; 12127 opti++; 12128 newArgs = new String[args.length - opti]; 12129 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12130 args.length - opti); 12131 args = newArgs; 12132 opti = 0; 12133 more = true; 12134 } 12135 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12136 synchronized (this) { 12137 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12138 } 12139 } else { 12140 // Dumping a single activity? 12141 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12142 pw.println("Bad activity command, or no activities match: " + cmd); 12143 pw.println("Use -h for help."); 12144 } 12145 } 12146 if (!more) { 12147 Binder.restoreCallingIdentity(origId); 12148 return; 12149 } 12150 } 12151 12152 // No piece of data specified, dump everything. 12153 synchronized (this) { 12154 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12155 pw.println(); 12156 if (dumpAll) { 12157 pw.println("-------------------------------------------------------------------------------"); 12158 } 12159 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12160 pw.println(); 12161 if (dumpAll) { 12162 pw.println("-------------------------------------------------------------------------------"); 12163 } 12164 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12165 pw.println(); 12166 if (dumpAll) { 12167 pw.println("-------------------------------------------------------------------------------"); 12168 } 12169 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12170 pw.println(); 12171 if (dumpAll) { 12172 pw.println("-------------------------------------------------------------------------------"); 12173 } 12174 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12175 pw.println(); 12176 if (dumpAll) { 12177 pw.println("-------------------------------------------------------------------------------"); 12178 } 12179 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12180 pw.println(); 12181 if (dumpAll) { 12182 pw.println("-------------------------------------------------------------------------------"); 12183 } 12184 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12185 } 12186 Binder.restoreCallingIdentity(origId); 12187 } 12188 12189 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12190 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12191 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12192 12193 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12194 dumpPackage); 12195 boolean needSep = printedAnything; 12196 12197 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12198 dumpPackage, needSep, " mFocusedActivity: "); 12199 if (printed) { 12200 printedAnything = true; 12201 needSep = false; 12202 } 12203 12204 if (dumpPackage == null) { 12205 if (needSep) { 12206 pw.println(); 12207 } 12208 needSep = true; 12209 printedAnything = true; 12210 mStackSupervisor.dump(pw, " "); 12211 } 12212 12213 if (!printedAnything) { 12214 pw.println(" (nothing)"); 12215 } 12216 } 12217 12218 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12219 int opti, boolean dumpAll, String dumpPackage) { 12220 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12221 12222 boolean printedAnything = false; 12223 12224 if (mRecentTasks.size() > 0) { 12225 boolean printedHeader = false; 12226 12227 final int N = mRecentTasks.size(); 12228 for (int i=0; i<N; i++) { 12229 TaskRecord tr = mRecentTasks.get(i); 12230 if (dumpPackage != null) { 12231 if (tr.realActivity == null || 12232 !dumpPackage.equals(tr.realActivity)) { 12233 continue; 12234 } 12235 } 12236 if (!printedHeader) { 12237 pw.println(" Recent tasks:"); 12238 printedHeader = true; 12239 printedAnything = true; 12240 } 12241 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12242 pw.println(tr); 12243 if (dumpAll) { 12244 mRecentTasks.get(i).dump(pw, " "); 12245 } 12246 } 12247 } 12248 12249 if (!printedAnything) { 12250 pw.println(" (nothing)"); 12251 } 12252 } 12253 12254 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12255 int opti, boolean dumpAll, String dumpPackage) { 12256 boolean needSep = false; 12257 boolean printedAnything = false; 12258 int numPers = 0; 12259 12260 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12261 12262 if (dumpAll) { 12263 final int NP = mProcessNames.getMap().size(); 12264 for (int ip=0; ip<NP; ip++) { 12265 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12266 final int NA = procs.size(); 12267 for (int ia=0; ia<NA; ia++) { 12268 ProcessRecord r = procs.valueAt(ia); 12269 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12270 continue; 12271 } 12272 if (!needSep) { 12273 pw.println(" All known processes:"); 12274 needSep = true; 12275 printedAnything = true; 12276 } 12277 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12278 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12279 pw.print(" "); pw.println(r); 12280 r.dump(pw, " "); 12281 if (r.persistent) { 12282 numPers++; 12283 } 12284 } 12285 } 12286 } 12287 12288 if (mIsolatedProcesses.size() > 0) { 12289 boolean printed = false; 12290 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12291 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12292 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12293 continue; 12294 } 12295 if (!printed) { 12296 if (needSep) { 12297 pw.println(); 12298 } 12299 pw.println(" Isolated process list (sorted by uid):"); 12300 printedAnything = true; 12301 printed = true; 12302 needSep = true; 12303 } 12304 pw.println(String.format("%sIsolated #%2d: %s", 12305 " ", i, r.toString())); 12306 } 12307 } 12308 12309 if (mLruProcesses.size() > 0) { 12310 if (needSep) { 12311 pw.println(); 12312 } 12313 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12314 pw.print(" total, non-act at "); 12315 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12316 pw.print(", non-svc at "); 12317 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12318 pw.println("):"); 12319 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12320 needSep = true; 12321 printedAnything = true; 12322 } 12323 12324 if (dumpAll || dumpPackage != null) { 12325 synchronized (mPidsSelfLocked) { 12326 boolean printed = false; 12327 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12328 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12329 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12330 continue; 12331 } 12332 if (!printed) { 12333 if (needSep) pw.println(); 12334 needSep = true; 12335 pw.println(" PID mappings:"); 12336 printed = true; 12337 printedAnything = true; 12338 } 12339 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12340 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12341 } 12342 } 12343 } 12344 12345 if (mForegroundProcesses.size() > 0) { 12346 synchronized (mPidsSelfLocked) { 12347 boolean printed = false; 12348 for (int i=0; i<mForegroundProcesses.size(); i++) { 12349 ProcessRecord r = mPidsSelfLocked.get( 12350 mForegroundProcesses.valueAt(i).pid); 12351 if (dumpPackage != null && (r == null 12352 || !r.pkgList.containsKey(dumpPackage))) { 12353 continue; 12354 } 12355 if (!printed) { 12356 if (needSep) pw.println(); 12357 needSep = true; 12358 pw.println(" Foreground Processes:"); 12359 printed = true; 12360 printedAnything = true; 12361 } 12362 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12363 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12364 } 12365 } 12366 } 12367 12368 if (mPersistentStartingProcesses.size() > 0) { 12369 if (needSep) pw.println(); 12370 needSep = true; 12371 printedAnything = true; 12372 pw.println(" Persisent processes that are starting:"); 12373 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12374 "Starting Norm", "Restarting PERS", dumpPackage); 12375 } 12376 12377 if (mRemovedProcesses.size() > 0) { 12378 if (needSep) pw.println(); 12379 needSep = true; 12380 printedAnything = true; 12381 pw.println(" Processes that are being removed:"); 12382 dumpProcessList(pw, this, mRemovedProcesses, " ", 12383 "Removed Norm", "Removed PERS", dumpPackage); 12384 } 12385 12386 if (mProcessesOnHold.size() > 0) { 12387 if (needSep) pw.println(); 12388 needSep = true; 12389 printedAnything = true; 12390 pw.println(" Processes that are on old until the system is ready:"); 12391 dumpProcessList(pw, this, mProcessesOnHold, " ", 12392 "OnHold Norm", "OnHold PERS", dumpPackage); 12393 } 12394 12395 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12396 12397 if (mProcessCrashTimes.getMap().size() > 0) { 12398 boolean printed = false; 12399 long now = SystemClock.uptimeMillis(); 12400 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12401 final int NP = pmap.size(); 12402 for (int ip=0; ip<NP; ip++) { 12403 String pname = pmap.keyAt(ip); 12404 SparseArray<Long> uids = pmap.valueAt(ip); 12405 final int N = uids.size(); 12406 for (int i=0; i<N; i++) { 12407 int puid = uids.keyAt(i); 12408 ProcessRecord r = mProcessNames.get(pname, puid); 12409 if (dumpPackage != null && (r == null 12410 || !r.pkgList.containsKey(dumpPackage))) { 12411 continue; 12412 } 12413 if (!printed) { 12414 if (needSep) pw.println(); 12415 needSep = true; 12416 pw.println(" Time since processes crashed:"); 12417 printed = true; 12418 printedAnything = true; 12419 } 12420 pw.print(" Process "); pw.print(pname); 12421 pw.print(" uid "); pw.print(puid); 12422 pw.print(": last crashed "); 12423 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12424 pw.println(" ago"); 12425 } 12426 } 12427 } 12428 12429 if (mBadProcesses.getMap().size() > 0) { 12430 boolean printed = false; 12431 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12432 final int NP = pmap.size(); 12433 for (int ip=0; ip<NP; ip++) { 12434 String pname = pmap.keyAt(ip); 12435 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12436 final int N = uids.size(); 12437 for (int i=0; i<N; i++) { 12438 int puid = uids.keyAt(i); 12439 ProcessRecord r = mProcessNames.get(pname, puid); 12440 if (dumpPackage != null && (r == null 12441 || !r.pkgList.containsKey(dumpPackage))) { 12442 continue; 12443 } 12444 if (!printed) { 12445 if (needSep) pw.println(); 12446 needSep = true; 12447 pw.println(" Bad processes:"); 12448 printedAnything = true; 12449 } 12450 BadProcessInfo info = uids.valueAt(i); 12451 pw.print(" Bad process "); pw.print(pname); 12452 pw.print(" uid "); pw.print(puid); 12453 pw.print(": crashed at time "); pw.println(info.time); 12454 if (info.shortMsg != null) { 12455 pw.print(" Short msg: "); pw.println(info.shortMsg); 12456 } 12457 if (info.longMsg != null) { 12458 pw.print(" Long msg: "); pw.println(info.longMsg); 12459 } 12460 if (info.stack != null) { 12461 pw.println(" Stack:"); 12462 int lastPos = 0; 12463 for (int pos=0; pos<info.stack.length(); pos++) { 12464 if (info.stack.charAt(pos) == '\n') { 12465 pw.print(" "); 12466 pw.write(info.stack, lastPos, pos-lastPos); 12467 pw.println(); 12468 lastPos = pos+1; 12469 } 12470 } 12471 if (lastPos < info.stack.length()) { 12472 pw.print(" "); 12473 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12474 pw.println(); 12475 } 12476 } 12477 } 12478 } 12479 } 12480 12481 if (dumpPackage == null) { 12482 pw.println(); 12483 needSep = false; 12484 pw.println(" mStartedUsers:"); 12485 for (int i=0; i<mStartedUsers.size(); i++) { 12486 UserStartedState uss = mStartedUsers.valueAt(i); 12487 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12488 pw.print(": "); uss.dump("", pw); 12489 } 12490 pw.print(" mStartedUserArray: ["); 12491 for (int i=0; i<mStartedUserArray.length; i++) { 12492 if (i > 0) pw.print(", "); 12493 pw.print(mStartedUserArray[i]); 12494 } 12495 pw.println("]"); 12496 pw.print(" mUserLru: ["); 12497 for (int i=0; i<mUserLru.size(); i++) { 12498 if (i > 0) pw.print(", "); 12499 pw.print(mUserLru.get(i)); 12500 } 12501 pw.println("]"); 12502 if (dumpAll) { 12503 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12504 } 12505 synchronized (mUserProfileGroupIdsSelfLocked) { 12506 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12507 pw.println(" mUserProfileGroupIds:"); 12508 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12509 pw.print(" User #"); 12510 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12511 pw.print(" -> profile #"); 12512 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12513 } 12514 } 12515 } 12516 } 12517 if (mHomeProcess != null && (dumpPackage == null 12518 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12519 if (needSep) { 12520 pw.println(); 12521 needSep = false; 12522 } 12523 pw.println(" mHomeProcess: " + mHomeProcess); 12524 } 12525 if (mPreviousProcess != null && (dumpPackage == null 12526 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12527 if (needSep) { 12528 pw.println(); 12529 needSep = false; 12530 } 12531 pw.println(" mPreviousProcess: " + mPreviousProcess); 12532 } 12533 if (dumpAll) { 12534 StringBuilder sb = new StringBuilder(128); 12535 sb.append(" mPreviousProcessVisibleTime: "); 12536 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12537 pw.println(sb); 12538 } 12539 if (mHeavyWeightProcess != null && (dumpPackage == null 12540 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12541 if (needSep) { 12542 pw.println(); 12543 needSep = false; 12544 } 12545 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12546 } 12547 if (dumpPackage == null) { 12548 pw.println(" mConfiguration: " + mConfiguration); 12549 } 12550 if (dumpAll) { 12551 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12552 if (mCompatModePackages.getPackages().size() > 0) { 12553 boolean printed = false; 12554 for (Map.Entry<String, Integer> entry 12555 : mCompatModePackages.getPackages().entrySet()) { 12556 String pkg = entry.getKey(); 12557 int mode = entry.getValue(); 12558 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12559 continue; 12560 } 12561 if (!printed) { 12562 pw.println(" mScreenCompatPackages:"); 12563 printed = true; 12564 } 12565 pw.print(" "); pw.print(pkg); pw.print(": "); 12566 pw.print(mode); pw.println(); 12567 } 12568 } 12569 } 12570 if (dumpPackage == null) { 12571 if (mSleeping || mWentToSleep || mLockScreenShown) { 12572 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12573 + " mLockScreenShown " + mLockScreenShown); 12574 } 12575 if (mShuttingDown || mRunningVoice) { 12576 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12577 } 12578 } 12579 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12580 || mOrigWaitForDebugger) { 12581 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12582 || dumpPackage.equals(mOrigDebugApp)) { 12583 if (needSep) { 12584 pw.println(); 12585 needSep = false; 12586 } 12587 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12588 + " mDebugTransient=" + mDebugTransient 12589 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12590 } 12591 } 12592 if (mOpenGlTraceApp != null) { 12593 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12594 if (needSep) { 12595 pw.println(); 12596 needSep = false; 12597 } 12598 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12599 } 12600 } 12601 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12602 || mProfileFd != null) { 12603 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12604 if (needSep) { 12605 pw.println(); 12606 needSep = false; 12607 } 12608 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12609 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12610 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12611 + mAutoStopProfiler); 12612 pw.println(" mProfileType=" + mProfileType); 12613 } 12614 } 12615 if (dumpPackage == null) { 12616 if (mAlwaysFinishActivities || mController != null) { 12617 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12618 + " mController=" + mController); 12619 } 12620 if (dumpAll) { 12621 pw.println(" Total persistent processes: " + numPers); 12622 pw.println(" mProcessesReady=" + mProcessesReady 12623 + " mSystemReady=" + mSystemReady); 12624 pw.println(" mBooting=" + mBooting 12625 + " mBooted=" + mBooted 12626 + " mFactoryTest=" + mFactoryTest); 12627 pw.print(" mLastPowerCheckRealtime="); 12628 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12629 pw.println(""); 12630 pw.print(" mLastPowerCheckUptime="); 12631 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12632 pw.println(""); 12633 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12634 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12635 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12636 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12637 + " (" + mLruProcesses.size() + " total)" 12638 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12639 + " mNumServiceProcs=" + mNumServiceProcs 12640 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12641 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12642 + " mLastMemoryLevel" + mLastMemoryLevel 12643 + " mLastNumProcesses" + mLastNumProcesses); 12644 long now = SystemClock.uptimeMillis(); 12645 pw.print(" mLastIdleTime="); 12646 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12647 pw.print(" mLowRamSinceLastIdle="); 12648 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12649 pw.println(); 12650 } 12651 } 12652 12653 if (!printedAnything) { 12654 pw.println(" (nothing)"); 12655 } 12656 } 12657 12658 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12659 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12660 if (mProcessesToGc.size() > 0) { 12661 boolean printed = false; 12662 long now = SystemClock.uptimeMillis(); 12663 for (int i=0; i<mProcessesToGc.size(); i++) { 12664 ProcessRecord proc = mProcessesToGc.get(i); 12665 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12666 continue; 12667 } 12668 if (!printed) { 12669 if (needSep) pw.println(); 12670 needSep = true; 12671 pw.println(" Processes that are waiting to GC:"); 12672 printed = true; 12673 } 12674 pw.print(" Process "); pw.println(proc); 12675 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12676 pw.print(", last gced="); 12677 pw.print(now-proc.lastRequestedGc); 12678 pw.print(" ms ago, last lowMem="); 12679 pw.print(now-proc.lastLowMemory); 12680 pw.println(" ms ago"); 12681 12682 } 12683 } 12684 return needSep; 12685 } 12686 12687 void printOomLevel(PrintWriter pw, String name, int adj) { 12688 pw.print(" "); 12689 if (adj >= 0) { 12690 pw.print(' '); 12691 if (adj < 10) pw.print(' '); 12692 } else { 12693 if (adj > -10) pw.print(' '); 12694 } 12695 pw.print(adj); 12696 pw.print(": "); 12697 pw.print(name); 12698 pw.print(" ("); 12699 pw.print(mProcessList.getMemLevel(adj)/1024); 12700 pw.println(" kB)"); 12701 } 12702 12703 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12704 int opti, boolean dumpAll) { 12705 boolean needSep = false; 12706 12707 if (mLruProcesses.size() > 0) { 12708 if (needSep) pw.println(); 12709 needSep = true; 12710 pw.println(" OOM levels:"); 12711 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12712 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12713 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12714 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12715 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12716 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12717 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12718 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12719 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12720 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12721 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12722 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12723 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12724 12725 if (needSep) pw.println(); 12726 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12727 pw.print(" total, non-act at "); 12728 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12729 pw.print(", non-svc at "); 12730 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12731 pw.println("):"); 12732 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12733 needSep = true; 12734 } 12735 12736 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12737 12738 pw.println(); 12739 pw.println(" mHomeProcess: " + mHomeProcess); 12740 pw.println(" mPreviousProcess: " + mPreviousProcess); 12741 if (mHeavyWeightProcess != null) { 12742 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12743 } 12744 12745 return true; 12746 } 12747 12748 /** 12749 * There are three ways to call this: 12750 * - no provider specified: dump all the providers 12751 * - a flattened component name that matched an existing provider was specified as the 12752 * first arg: dump that one provider 12753 * - the first arg isn't the flattened component name of an existing provider: 12754 * dump all providers whose component contains the first arg as a substring 12755 */ 12756 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12757 int opti, boolean dumpAll) { 12758 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12759 } 12760 12761 static class ItemMatcher { 12762 ArrayList<ComponentName> components; 12763 ArrayList<String> strings; 12764 ArrayList<Integer> objects; 12765 boolean all; 12766 12767 ItemMatcher() { 12768 all = true; 12769 } 12770 12771 void build(String name) { 12772 ComponentName componentName = ComponentName.unflattenFromString(name); 12773 if (componentName != null) { 12774 if (components == null) { 12775 components = new ArrayList<ComponentName>(); 12776 } 12777 components.add(componentName); 12778 all = false; 12779 } else { 12780 int objectId = 0; 12781 // Not a '/' separated full component name; maybe an object ID? 12782 try { 12783 objectId = Integer.parseInt(name, 16); 12784 if (objects == null) { 12785 objects = new ArrayList<Integer>(); 12786 } 12787 objects.add(objectId); 12788 all = false; 12789 } catch (RuntimeException e) { 12790 // Not an integer; just do string match. 12791 if (strings == null) { 12792 strings = new ArrayList<String>(); 12793 } 12794 strings.add(name); 12795 all = false; 12796 } 12797 } 12798 } 12799 12800 int build(String[] args, int opti) { 12801 for (; opti<args.length; opti++) { 12802 String name = args[opti]; 12803 if ("--".equals(name)) { 12804 return opti+1; 12805 } 12806 build(name); 12807 } 12808 return opti; 12809 } 12810 12811 boolean match(Object object, ComponentName comp) { 12812 if (all) { 12813 return true; 12814 } 12815 if (components != null) { 12816 for (int i=0; i<components.size(); i++) { 12817 if (components.get(i).equals(comp)) { 12818 return true; 12819 } 12820 } 12821 } 12822 if (objects != null) { 12823 for (int i=0; i<objects.size(); i++) { 12824 if (System.identityHashCode(object) == objects.get(i)) { 12825 return true; 12826 } 12827 } 12828 } 12829 if (strings != null) { 12830 String flat = comp.flattenToString(); 12831 for (int i=0; i<strings.size(); i++) { 12832 if (flat.contains(strings.get(i))) { 12833 return true; 12834 } 12835 } 12836 } 12837 return false; 12838 } 12839 } 12840 12841 /** 12842 * There are three things that cmd can be: 12843 * - a flattened component name that matches an existing activity 12844 * - the cmd arg isn't the flattened component name of an existing activity: 12845 * dump all activity whose component contains the cmd as a substring 12846 * - A hex number of the ActivityRecord object instance. 12847 */ 12848 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12849 int opti, boolean dumpAll) { 12850 ArrayList<ActivityRecord> activities; 12851 12852 synchronized (this) { 12853 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12854 } 12855 12856 if (activities.size() <= 0) { 12857 return false; 12858 } 12859 12860 String[] newArgs = new String[args.length - opti]; 12861 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12862 12863 TaskRecord lastTask = null; 12864 boolean needSep = false; 12865 for (int i=activities.size()-1; i>=0; i--) { 12866 ActivityRecord r = activities.get(i); 12867 if (needSep) { 12868 pw.println(); 12869 } 12870 needSep = true; 12871 synchronized (this) { 12872 if (lastTask != r.task) { 12873 lastTask = r.task; 12874 pw.print("TASK "); pw.print(lastTask.affinity); 12875 pw.print(" id="); pw.println(lastTask.taskId); 12876 if (dumpAll) { 12877 lastTask.dump(pw, " "); 12878 } 12879 } 12880 } 12881 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12882 } 12883 return true; 12884 } 12885 12886 /** 12887 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12888 * there is a thread associated with the activity. 12889 */ 12890 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12891 final ActivityRecord r, String[] args, boolean dumpAll) { 12892 String innerPrefix = prefix + " "; 12893 synchronized (this) { 12894 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12895 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12896 pw.print(" pid="); 12897 if (r.app != null) pw.println(r.app.pid); 12898 else pw.println("(not running)"); 12899 if (dumpAll) { 12900 r.dump(pw, innerPrefix); 12901 } 12902 } 12903 if (r.app != null && r.app.thread != null) { 12904 // flush anything that is already in the PrintWriter since the thread is going 12905 // to write to the file descriptor directly 12906 pw.flush(); 12907 try { 12908 TransferPipe tp = new TransferPipe(); 12909 try { 12910 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12911 r.appToken, innerPrefix, args); 12912 tp.go(fd); 12913 } finally { 12914 tp.kill(); 12915 } 12916 } catch (IOException e) { 12917 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12918 } catch (RemoteException e) { 12919 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12920 } 12921 } 12922 } 12923 12924 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12925 int opti, boolean dumpAll, String dumpPackage) { 12926 boolean needSep = false; 12927 boolean onlyHistory = false; 12928 boolean printedAnything = false; 12929 12930 if ("history".equals(dumpPackage)) { 12931 if (opti < args.length && "-s".equals(args[opti])) { 12932 dumpAll = false; 12933 } 12934 onlyHistory = true; 12935 dumpPackage = null; 12936 } 12937 12938 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12939 if (!onlyHistory && dumpAll) { 12940 if (mRegisteredReceivers.size() > 0) { 12941 boolean printed = false; 12942 Iterator it = mRegisteredReceivers.values().iterator(); 12943 while (it.hasNext()) { 12944 ReceiverList r = (ReceiverList)it.next(); 12945 if (dumpPackage != null && (r.app == null || 12946 !dumpPackage.equals(r.app.info.packageName))) { 12947 continue; 12948 } 12949 if (!printed) { 12950 pw.println(" Registered Receivers:"); 12951 needSep = true; 12952 printed = true; 12953 printedAnything = true; 12954 } 12955 pw.print(" * "); pw.println(r); 12956 r.dump(pw, " "); 12957 } 12958 } 12959 12960 if (mReceiverResolver.dump(pw, needSep ? 12961 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12962 " ", dumpPackage, false)) { 12963 needSep = true; 12964 printedAnything = true; 12965 } 12966 } 12967 12968 for (BroadcastQueue q : mBroadcastQueues) { 12969 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12970 printedAnything |= needSep; 12971 } 12972 12973 needSep = true; 12974 12975 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12976 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12977 if (needSep) { 12978 pw.println(); 12979 } 12980 needSep = true; 12981 printedAnything = true; 12982 pw.print(" Sticky broadcasts for user "); 12983 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12984 StringBuilder sb = new StringBuilder(128); 12985 for (Map.Entry<String, ArrayList<Intent>> ent 12986 : mStickyBroadcasts.valueAt(user).entrySet()) { 12987 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12988 if (dumpAll) { 12989 pw.println(":"); 12990 ArrayList<Intent> intents = ent.getValue(); 12991 final int N = intents.size(); 12992 for (int i=0; i<N; i++) { 12993 sb.setLength(0); 12994 sb.append(" Intent: "); 12995 intents.get(i).toShortString(sb, false, true, false, false); 12996 pw.println(sb.toString()); 12997 Bundle bundle = intents.get(i).getExtras(); 12998 if (bundle != null) { 12999 pw.print(" "); 13000 pw.println(bundle.toString()); 13001 } 13002 } 13003 } else { 13004 pw.println(""); 13005 } 13006 } 13007 } 13008 } 13009 13010 if (!onlyHistory && dumpAll) { 13011 pw.println(); 13012 for (BroadcastQueue queue : mBroadcastQueues) { 13013 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13014 + queue.mBroadcastsScheduled); 13015 } 13016 pw.println(" mHandler:"); 13017 mHandler.dump(new PrintWriterPrinter(pw), " "); 13018 needSep = true; 13019 printedAnything = true; 13020 } 13021 13022 if (!printedAnything) { 13023 pw.println(" (nothing)"); 13024 } 13025 } 13026 13027 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13028 int opti, boolean dumpAll, String dumpPackage) { 13029 boolean needSep; 13030 boolean printedAnything = false; 13031 13032 ItemMatcher matcher = new ItemMatcher(); 13033 matcher.build(args, opti); 13034 13035 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13036 13037 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13038 printedAnything |= needSep; 13039 13040 if (mLaunchingProviders.size() > 0) { 13041 boolean printed = false; 13042 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13043 ContentProviderRecord r = mLaunchingProviders.get(i); 13044 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13045 continue; 13046 } 13047 if (!printed) { 13048 if (needSep) pw.println(); 13049 needSep = true; 13050 pw.println(" Launching content providers:"); 13051 printed = true; 13052 printedAnything = true; 13053 } 13054 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13055 pw.println(r); 13056 } 13057 } 13058 13059 if (mGrantedUriPermissions.size() > 0) { 13060 boolean printed = false; 13061 int dumpUid = -2; 13062 if (dumpPackage != null) { 13063 try { 13064 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13065 } catch (NameNotFoundException e) { 13066 dumpUid = -1; 13067 } 13068 } 13069 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13070 int uid = mGrantedUriPermissions.keyAt(i); 13071 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13072 continue; 13073 } 13074 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13075 if (!printed) { 13076 if (needSep) pw.println(); 13077 needSep = true; 13078 pw.println(" Granted Uri Permissions:"); 13079 printed = true; 13080 printedAnything = true; 13081 } 13082 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13083 for (UriPermission perm : perms.values()) { 13084 pw.print(" "); pw.println(perm); 13085 if (dumpAll) { 13086 perm.dump(pw, " "); 13087 } 13088 } 13089 } 13090 } 13091 13092 if (!printedAnything) { 13093 pw.println(" (nothing)"); 13094 } 13095 } 13096 13097 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13098 int opti, boolean dumpAll, String dumpPackage) { 13099 boolean printed = false; 13100 13101 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13102 13103 if (mIntentSenderRecords.size() > 0) { 13104 Iterator<WeakReference<PendingIntentRecord>> it 13105 = mIntentSenderRecords.values().iterator(); 13106 while (it.hasNext()) { 13107 WeakReference<PendingIntentRecord> ref = it.next(); 13108 PendingIntentRecord rec = ref != null ? ref.get(): null; 13109 if (dumpPackage != null && (rec == null 13110 || !dumpPackage.equals(rec.key.packageName))) { 13111 continue; 13112 } 13113 printed = true; 13114 if (rec != null) { 13115 pw.print(" * "); pw.println(rec); 13116 if (dumpAll) { 13117 rec.dump(pw, " "); 13118 } 13119 } else { 13120 pw.print(" * "); pw.println(ref); 13121 } 13122 } 13123 } 13124 13125 if (!printed) { 13126 pw.println(" (nothing)"); 13127 } 13128 } 13129 13130 private static final int dumpProcessList(PrintWriter pw, 13131 ActivityManagerService service, List list, 13132 String prefix, String normalLabel, String persistentLabel, 13133 String dumpPackage) { 13134 int numPers = 0; 13135 final int N = list.size()-1; 13136 for (int i=N; i>=0; i--) { 13137 ProcessRecord r = (ProcessRecord)list.get(i); 13138 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13139 continue; 13140 } 13141 pw.println(String.format("%s%s #%2d: %s", 13142 prefix, (r.persistent ? persistentLabel : normalLabel), 13143 i, r.toString())); 13144 if (r.persistent) { 13145 numPers++; 13146 } 13147 } 13148 return numPers; 13149 } 13150 13151 private static final boolean dumpProcessOomList(PrintWriter pw, 13152 ActivityManagerService service, List<ProcessRecord> origList, 13153 String prefix, String normalLabel, String persistentLabel, 13154 boolean inclDetails, String dumpPackage) { 13155 13156 ArrayList<Pair<ProcessRecord, Integer>> list 13157 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13158 for (int i=0; i<origList.size(); i++) { 13159 ProcessRecord r = origList.get(i); 13160 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13161 continue; 13162 } 13163 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13164 } 13165 13166 if (list.size() <= 0) { 13167 return false; 13168 } 13169 13170 Comparator<Pair<ProcessRecord, Integer>> comparator 13171 = new Comparator<Pair<ProcessRecord, Integer>>() { 13172 @Override 13173 public int compare(Pair<ProcessRecord, Integer> object1, 13174 Pair<ProcessRecord, Integer> object2) { 13175 if (object1.first.setAdj != object2.first.setAdj) { 13176 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13177 } 13178 if (object1.second.intValue() != object2.second.intValue()) { 13179 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13180 } 13181 return 0; 13182 } 13183 }; 13184 13185 Collections.sort(list, comparator); 13186 13187 final long curRealtime = SystemClock.elapsedRealtime(); 13188 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13189 final long curUptime = SystemClock.uptimeMillis(); 13190 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13191 13192 for (int i=list.size()-1; i>=0; i--) { 13193 ProcessRecord r = list.get(i).first; 13194 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13195 char schedGroup; 13196 switch (r.setSchedGroup) { 13197 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13198 schedGroup = 'B'; 13199 break; 13200 case Process.THREAD_GROUP_DEFAULT: 13201 schedGroup = 'F'; 13202 break; 13203 default: 13204 schedGroup = '?'; 13205 break; 13206 } 13207 char foreground; 13208 if (r.foregroundActivities) { 13209 foreground = 'A'; 13210 } else if (r.foregroundServices) { 13211 foreground = 'S'; 13212 } else { 13213 foreground = ' '; 13214 } 13215 String procState = ProcessList.makeProcStateString(r.curProcState); 13216 pw.print(prefix); 13217 pw.print(r.persistent ? persistentLabel : normalLabel); 13218 pw.print(" #"); 13219 int num = (origList.size()-1)-list.get(i).second; 13220 if (num < 10) pw.print(' '); 13221 pw.print(num); 13222 pw.print(": "); 13223 pw.print(oomAdj); 13224 pw.print(' '); 13225 pw.print(schedGroup); 13226 pw.print('/'); 13227 pw.print(foreground); 13228 pw.print('/'); 13229 pw.print(procState); 13230 pw.print(" trm:"); 13231 if (r.trimMemoryLevel < 10) pw.print(' '); 13232 pw.print(r.trimMemoryLevel); 13233 pw.print(' '); 13234 pw.print(r.toShortString()); 13235 pw.print(" ("); 13236 pw.print(r.adjType); 13237 pw.println(')'); 13238 if (r.adjSource != null || r.adjTarget != null) { 13239 pw.print(prefix); 13240 pw.print(" "); 13241 if (r.adjTarget instanceof ComponentName) { 13242 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13243 } else if (r.adjTarget != null) { 13244 pw.print(r.adjTarget.toString()); 13245 } else { 13246 pw.print("{null}"); 13247 } 13248 pw.print("<="); 13249 if (r.adjSource instanceof ProcessRecord) { 13250 pw.print("Proc{"); 13251 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13252 pw.println("}"); 13253 } else if (r.adjSource != null) { 13254 pw.println(r.adjSource.toString()); 13255 } else { 13256 pw.println("{null}"); 13257 } 13258 } 13259 if (inclDetails) { 13260 pw.print(prefix); 13261 pw.print(" "); 13262 pw.print("oom: max="); pw.print(r.maxAdj); 13263 pw.print(" curRaw="); pw.print(r.curRawAdj); 13264 pw.print(" setRaw="); pw.print(r.setRawAdj); 13265 pw.print(" cur="); pw.print(r.curAdj); 13266 pw.print(" set="); pw.println(r.setAdj); 13267 pw.print(prefix); 13268 pw.print(" "); 13269 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13270 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13271 pw.print(" lastPss="); pw.print(r.lastPss); 13272 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13273 pw.print(prefix); 13274 pw.print(" "); 13275 pw.print("cached="); pw.print(r.cached); 13276 pw.print(" empty="); pw.print(r.empty); 13277 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13278 13279 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13280 if (r.lastWakeTime != 0) { 13281 long wtime; 13282 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13283 synchronized (stats) { 13284 wtime = stats.getProcessWakeTime(r.info.uid, 13285 r.pid, curRealtime); 13286 } 13287 long timeUsed = wtime - r.lastWakeTime; 13288 pw.print(prefix); 13289 pw.print(" "); 13290 pw.print("keep awake over "); 13291 TimeUtils.formatDuration(realtimeSince, pw); 13292 pw.print(" used "); 13293 TimeUtils.formatDuration(timeUsed, pw); 13294 pw.print(" ("); 13295 pw.print((timeUsed*100)/realtimeSince); 13296 pw.println("%)"); 13297 } 13298 if (r.lastCpuTime != 0) { 13299 long timeUsed = r.curCpuTime - r.lastCpuTime; 13300 pw.print(prefix); 13301 pw.print(" "); 13302 pw.print("run cpu over "); 13303 TimeUtils.formatDuration(uptimeSince, pw); 13304 pw.print(" used "); 13305 TimeUtils.formatDuration(timeUsed, pw); 13306 pw.print(" ("); 13307 pw.print((timeUsed*100)/uptimeSince); 13308 pw.println("%)"); 13309 } 13310 } 13311 } 13312 } 13313 return true; 13314 } 13315 13316 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13317 ArrayList<ProcessRecord> procs; 13318 synchronized (this) { 13319 if (args != null && args.length > start 13320 && args[start].charAt(0) != '-') { 13321 procs = new ArrayList<ProcessRecord>(); 13322 int pid = -1; 13323 try { 13324 pid = Integer.parseInt(args[start]); 13325 } catch (NumberFormatException e) { 13326 } 13327 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13328 ProcessRecord proc = mLruProcesses.get(i); 13329 if (proc.pid == pid) { 13330 procs.add(proc); 13331 } else if (proc.processName.equals(args[start])) { 13332 procs.add(proc); 13333 } 13334 } 13335 if (procs.size() <= 0) { 13336 return null; 13337 } 13338 } else { 13339 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13340 } 13341 } 13342 return procs; 13343 } 13344 13345 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13346 PrintWriter pw, String[] args) { 13347 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13348 if (procs == null) { 13349 pw.println("No process found for: " + args[0]); 13350 return; 13351 } 13352 13353 long uptime = SystemClock.uptimeMillis(); 13354 long realtime = SystemClock.elapsedRealtime(); 13355 pw.println("Applications Graphics Acceleration Info:"); 13356 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13357 13358 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13359 ProcessRecord r = procs.get(i); 13360 if (r.thread != null) { 13361 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13362 pw.flush(); 13363 try { 13364 TransferPipe tp = new TransferPipe(); 13365 try { 13366 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13367 tp.go(fd); 13368 } finally { 13369 tp.kill(); 13370 } 13371 } catch (IOException e) { 13372 pw.println("Failure while dumping the app: " + r); 13373 pw.flush(); 13374 } catch (RemoteException e) { 13375 pw.println("Got a RemoteException while dumping the app " + r); 13376 pw.flush(); 13377 } 13378 } 13379 } 13380 } 13381 13382 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13383 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13384 if (procs == null) { 13385 pw.println("No process found for: " + args[0]); 13386 return; 13387 } 13388 13389 pw.println("Applications Database Info:"); 13390 13391 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13392 ProcessRecord r = procs.get(i); 13393 if (r.thread != null) { 13394 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13395 pw.flush(); 13396 try { 13397 TransferPipe tp = new TransferPipe(); 13398 try { 13399 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13400 tp.go(fd); 13401 } finally { 13402 tp.kill(); 13403 } 13404 } catch (IOException e) { 13405 pw.println("Failure while dumping the app: " + r); 13406 pw.flush(); 13407 } catch (RemoteException e) { 13408 pw.println("Got a RemoteException while dumping the app " + r); 13409 pw.flush(); 13410 } 13411 } 13412 } 13413 } 13414 13415 final static class MemItem { 13416 final boolean isProc; 13417 final String label; 13418 final String shortLabel; 13419 final long pss; 13420 final int id; 13421 final boolean hasActivities; 13422 ArrayList<MemItem> subitems; 13423 13424 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13425 boolean _hasActivities) { 13426 isProc = true; 13427 label = _label; 13428 shortLabel = _shortLabel; 13429 pss = _pss; 13430 id = _id; 13431 hasActivities = _hasActivities; 13432 } 13433 13434 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13435 isProc = false; 13436 label = _label; 13437 shortLabel = _shortLabel; 13438 pss = _pss; 13439 id = _id; 13440 hasActivities = false; 13441 } 13442 } 13443 13444 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13445 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13446 if (sort && !isCompact) { 13447 Collections.sort(items, new Comparator<MemItem>() { 13448 @Override 13449 public int compare(MemItem lhs, MemItem rhs) { 13450 if (lhs.pss < rhs.pss) { 13451 return 1; 13452 } else if (lhs.pss > rhs.pss) { 13453 return -1; 13454 } 13455 return 0; 13456 } 13457 }); 13458 } 13459 13460 for (int i=0; i<items.size(); i++) { 13461 MemItem mi = items.get(i); 13462 if (!isCompact) { 13463 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13464 } else if (mi.isProc) { 13465 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13466 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13467 pw.println(mi.hasActivities ? ",a" : ",e"); 13468 } else { 13469 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13470 pw.println(mi.pss); 13471 } 13472 if (mi.subitems != null) { 13473 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13474 true, isCompact); 13475 } 13476 } 13477 } 13478 13479 // These are in KB. 13480 static final long[] DUMP_MEM_BUCKETS = new long[] { 13481 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13482 120*1024, 160*1024, 200*1024, 13483 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13484 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13485 }; 13486 13487 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13488 boolean stackLike) { 13489 int start = label.lastIndexOf('.'); 13490 if (start >= 0) start++; 13491 else start = 0; 13492 int end = label.length(); 13493 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13494 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13495 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13496 out.append(bucket); 13497 out.append(stackLike ? "MB." : "MB "); 13498 out.append(label, start, end); 13499 return; 13500 } 13501 } 13502 out.append(memKB/1024); 13503 out.append(stackLike ? "MB." : "MB "); 13504 out.append(label, start, end); 13505 } 13506 13507 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13508 ProcessList.NATIVE_ADJ, 13509 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13510 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13511 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13512 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13513 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13514 }; 13515 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13516 "Native", 13517 "System", "Persistent", "Foreground", 13518 "Visible", "Perceptible", 13519 "Heavy Weight", "Backup", 13520 "A Services", "Home", 13521 "Previous", "B Services", "Cached" 13522 }; 13523 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13524 "native", 13525 "sys", "pers", "fore", 13526 "vis", "percept", 13527 "heavy", "backup", 13528 "servicea", "home", 13529 "prev", "serviceb", "cached" 13530 }; 13531 13532 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13533 long realtime, boolean isCheckinRequest, boolean isCompact) { 13534 if (isCheckinRequest || isCompact) { 13535 // short checkin version 13536 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13537 } else { 13538 pw.println("Applications Memory Usage (kB):"); 13539 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13540 } 13541 } 13542 13543 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13544 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13545 boolean dumpDetails = false; 13546 boolean dumpFullDetails = false; 13547 boolean dumpDalvik = false; 13548 boolean oomOnly = false; 13549 boolean isCompact = false; 13550 boolean localOnly = false; 13551 13552 int opti = 0; 13553 while (opti < args.length) { 13554 String opt = args[opti]; 13555 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13556 break; 13557 } 13558 opti++; 13559 if ("-a".equals(opt)) { 13560 dumpDetails = true; 13561 dumpFullDetails = true; 13562 dumpDalvik = true; 13563 } else if ("-d".equals(opt)) { 13564 dumpDalvik = true; 13565 } else if ("-c".equals(opt)) { 13566 isCompact = true; 13567 } else if ("--oom".equals(opt)) { 13568 oomOnly = true; 13569 } else if ("--local".equals(opt)) { 13570 localOnly = true; 13571 } else if ("-h".equals(opt)) { 13572 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13573 pw.println(" -a: include all available information for each process."); 13574 pw.println(" -d: include dalvik details when dumping process details."); 13575 pw.println(" -c: dump in a compact machine-parseable representation."); 13576 pw.println(" --oom: only show processes organized by oom adj."); 13577 pw.println(" --local: only collect details locally, don't call process."); 13578 pw.println("If [process] is specified it can be the name or "); 13579 pw.println("pid of a specific process to dump."); 13580 return; 13581 } else { 13582 pw.println("Unknown argument: " + opt + "; use -h for help"); 13583 } 13584 } 13585 13586 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13587 long uptime = SystemClock.uptimeMillis(); 13588 long realtime = SystemClock.elapsedRealtime(); 13589 final long[] tmpLong = new long[1]; 13590 13591 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13592 if (procs == null) { 13593 // No Java processes. Maybe they want to print a native process. 13594 if (args != null && args.length > opti 13595 && args[opti].charAt(0) != '-') { 13596 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13597 = new ArrayList<ProcessCpuTracker.Stats>(); 13598 updateCpuStatsNow(); 13599 int findPid = -1; 13600 try { 13601 findPid = Integer.parseInt(args[opti]); 13602 } catch (NumberFormatException e) { 13603 } 13604 synchronized (mProcessCpuThread) { 13605 final int N = mProcessCpuTracker.countStats(); 13606 for (int i=0; i<N; i++) { 13607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13608 if (st.pid == findPid || (st.baseName != null 13609 && st.baseName.equals(args[opti]))) { 13610 nativeProcs.add(st); 13611 } 13612 } 13613 } 13614 if (nativeProcs.size() > 0) { 13615 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13616 isCompact); 13617 Debug.MemoryInfo mi = null; 13618 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13619 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13620 final int pid = r.pid; 13621 if (!isCheckinRequest && dumpDetails) { 13622 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13623 } 13624 if (mi == null) { 13625 mi = new Debug.MemoryInfo(); 13626 } 13627 if (dumpDetails || (!brief && !oomOnly)) { 13628 Debug.getMemoryInfo(pid, mi); 13629 } else { 13630 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13631 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13632 } 13633 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13634 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13635 if (isCheckinRequest) { 13636 pw.println(); 13637 } 13638 } 13639 return; 13640 } 13641 } 13642 pw.println("No process found for: " + args[opti]); 13643 return; 13644 } 13645 13646 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13647 dumpDetails = true; 13648 } 13649 13650 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13651 13652 String[] innerArgs = new String[args.length-opti]; 13653 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13654 13655 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13656 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13657 long nativePss=0, dalvikPss=0, otherPss=0; 13658 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13659 13660 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13661 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13662 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13663 13664 long totalPss = 0; 13665 long cachedPss = 0; 13666 13667 Debug.MemoryInfo mi = null; 13668 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13669 final ProcessRecord r = procs.get(i); 13670 final IApplicationThread thread; 13671 final int pid; 13672 final int oomAdj; 13673 final boolean hasActivities; 13674 synchronized (this) { 13675 thread = r.thread; 13676 pid = r.pid; 13677 oomAdj = r.getSetAdjWithServices(); 13678 hasActivities = r.activities.size() > 0; 13679 } 13680 if (thread != null) { 13681 if (!isCheckinRequest && dumpDetails) { 13682 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13683 } 13684 if (mi == null) { 13685 mi = new Debug.MemoryInfo(); 13686 } 13687 if (dumpDetails || (!brief && !oomOnly)) { 13688 Debug.getMemoryInfo(pid, mi); 13689 } else { 13690 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13691 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13692 } 13693 if (dumpDetails) { 13694 if (localOnly) { 13695 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13696 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13697 if (isCheckinRequest) { 13698 pw.println(); 13699 } 13700 } else { 13701 try { 13702 pw.flush(); 13703 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13704 dumpDalvik, innerArgs); 13705 } catch (RemoteException e) { 13706 if (!isCheckinRequest) { 13707 pw.println("Got RemoteException!"); 13708 pw.flush(); 13709 } 13710 } 13711 } 13712 } 13713 13714 final long myTotalPss = mi.getTotalPss(); 13715 final long myTotalUss = mi.getTotalUss(); 13716 13717 synchronized (this) { 13718 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13719 // Record this for posterity if the process has been stable. 13720 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13721 } 13722 } 13723 13724 if (!isCheckinRequest && mi != null) { 13725 totalPss += myTotalPss; 13726 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13727 (hasActivities ? " / activities)" : ")"), 13728 r.processName, myTotalPss, pid, hasActivities); 13729 procMems.add(pssItem); 13730 procMemsMap.put(pid, pssItem); 13731 13732 nativePss += mi.nativePss; 13733 dalvikPss += mi.dalvikPss; 13734 otherPss += mi.otherPss; 13735 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13736 long mem = mi.getOtherPss(j); 13737 miscPss[j] += mem; 13738 otherPss -= mem; 13739 } 13740 13741 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13742 cachedPss += myTotalPss; 13743 } 13744 13745 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13746 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13747 || oomIndex == (oomPss.length-1)) { 13748 oomPss[oomIndex] += myTotalPss; 13749 if (oomProcs[oomIndex] == null) { 13750 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13751 } 13752 oomProcs[oomIndex].add(pssItem); 13753 break; 13754 } 13755 } 13756 } 13757 } 13758 } 13759 13760 long nativeProcTotalPss = 0; 13761 13762 if (!isCheckinRequest && procs.size() > 1) { 13763 // If we are showing aggregations, also look for native processes to 13764 // include so that our aggregations are more accurate. 13765 updateCpuStatsNow(); 13766 synchronized (mProcessCpuThread) { 13767 final int N = mProcessCpuTracker.countStats(); 13768 for (int i=0; i<N; i++) { 13769 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13770 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13771 if (mi == null) { 13772 mi = new Debug.MemoryInfo(); 13773 } 13774 if (!brief && !oomOnly) { 13775 Debug.getMemoryInfo(st.pid, mi); 13776 } else { 13777 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13778 mi.nativePrivateDirty = (int)tmpLong[0]; 13779 } 13780 13781 final long myTotalPss = mi.getTotalPss(); 13782 totalPss += myTotalPss; 13783 nativeProcTotalPss += myTotalPss; 13784 13785 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13786 st.name, myTotalPss, st.pid, false); 13787 procMems.add(pssItem); 13788 13789 nativePss += mi.nativePss; 13790 dalvikPss += mi.dalvikPss; 13791 otherPss += mi.otherPss; 13792 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13793 long mem = mi.getOtherPss(j); 13794 miscPss[j] += mem; 13795 otherPss -= mem; 13796 } 13797 oomPss[0] += myTotalPss; 13798 if (oomProcs[0] == null) { 13799 oomProcs[0] = new ArrayList<MemItem>(); 13800 } 13801 oomProcs[0].add(pssItem); 13802 } 13803 } 13804 } 13805 13806 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13807 13808 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13809 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13810 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13811 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13812 String label = Debug.MemoryInfo.getOtherLabel(j); 13813 catMems.add(new MemItem(label, label, miscPss[j], j)); 13814 } 13815 13816 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13817 for (int j=0; j<oomPss.length; j++) { 13818 if (oomPss[j] != 0) { 13819 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13820 : DUMP_MEM_OOM_LABEL[j]; 13821 MemItem item = new MemItem(label, label, oomPss[j], 13822 DUMP_MEM_OOM_ADJ[j]); 13823 item.subitems = oomProcs[j]; 13824 oomMems.add(item); 13825 } 13826 } 13827 13828 if (!brief && !oomOnly && !isCompact) { 13829 pw.println(); 13830 pw.println("Total PSS by process:"); 13831 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13832 pw.println(); 13833 } 13834 if (!isCompact) { 13835 pw.println("Total PSS by OOM adjustment:"); 13836 } 13837 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13838 if (!brief && !oomOnly) { 13839 PrintWriter out = categoryPw != null ? categoryPw : pw; 13840 if (!isCompact) { 13841 out.println(); 13842 out.println("Total PSS by category:"); 13843 } 13844 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13845 } 13846 if (!isCompact) { 13847 pw.println(); 13848 } 13849 MemInfoReader memInfo = new MemInfoReader(); 13850 memInfo.readMemInfo(); 13851 if (nativeProcTotalPss > 0) { 13852 synchronized (this) { 13853 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13854 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13855 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13856 nativeProcTotalPss); 13857 } 13858 } 13859 if (!brief) { 13860 if (!isCompact) { 13861 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13862 pw.print(" kB (status "); 13863 switch (mLastMemoryLevel) { 13864 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13865 pw.println("normal)"); 13866 break; 13867 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13868 pw.println("moderate)"); 13869 break; 13870 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13871 pw.println("low)"); 13872 break; 13873 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13874 pw.println("critical)"); 13875 break; 13876 default: 13877 pw.print(mLastMemoryLevel); 13878 pw.println(")"); 13879 break; 13880 } 13881 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13882 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13883 pw.print(cachedPss); pw.print(" cached pss + "); 13884 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13885 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13886 } else { 13887 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13888 pw.print(cachedPss + memInfo.getCachedSizeKb() 13889 + memInfo.getFreeSizeKb()); pw.print(","); 13890 pw.println(totalPss - cachedPss); 13891 } 13892 } 13893 if (!isCompact) { 13894 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13895 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13896 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13897 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13898 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13899 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13900 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13901 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13902 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13903 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13904 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13905 } 13906 if (!brief) { 13907 if (memInfo.getZramTotalSizeKb() != 0) { 13908 if (!isCompact) { 13909 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13910 pw.print(" kB physical used for "); 13911 pw.print(memInfo.getSwapTotalSizeKb() 13912 - memInfo.getSwapFreeSizeKb()); 13913 pw.print(" kB in swap ("); 13914 pw.print(memInfo.getSwapTotalSizeKb()); 13915 pw.println(" kB total swap)"); 13916 } else { 13917 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13918 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13919 pw.println(memInfo.getSwapFreeSizeKb()); 13920 } 13921 } 13922 final int[] SINGLE_LONG_FORMAT = new int[] { 13923 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13924 }; 13925 long[] longOut = new long[1]; 13926 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13927 SINGLE_LONG_FORMAT, null, longOut, null); 13928 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13929 longOut[0] = 0; 13930 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13931 SINGLE_LONG_FORMAT, null, longOut, null); 13932 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13933 longOut[0] = 0; 13934 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13935 SINGLE_LONG_FORMAT, null, longOut, null); 13936 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13937 longOut[0] = 0; 13938 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13939 SINGLE_LONG_FORMAT, null, longOut, null); 13940 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13941 if (!isCompact) { 13942 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13943 pw.print(" KSM: "); pw.print(sharing); 13944 pw.print(" kB saved from shared "); 13945 pw.print(shared); pw.println(" kB"); 13946 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13947 pw.print(voltile); pw.println(" kB volatile"); 13948 } 13949 pw.print(" Tuning: "); 13950 pw.print(ActivityManager.staticGetMemoryClass()); 13951 pw.print(" (large "); 13952 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13953 pw.print("), oom "); 13954 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13955 pw.print(" kB"); 13956 pw.print(", restore limit "); 13957 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13958 pw.print(" kB"); 13959 if (ActivityManager.isLowRamDeviceStatic()) { 13960 pw.print(" (low-ram)"); 13961 } 13962 if (ActivityManager.isHighEndGfx()) { 13963 pw.print(" (high-end-gfx)"); 13964 } 13965 pw.println(); 13966 } else { 13967 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13968 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13969 pw.println(voltile); 13970 pw.print("tuning,"); 13971 pw.print(ActivityManager.staticGetMemoryClass()); 13972 pw.print(','); 13973 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13974 pw.print(','); 13975 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13976 if (ActivityManager.isLowRamDeviceStatic()) { 13977 pw.print(",low-ram"); 13978 } 13979 if (ActivityManager.isHighEndGfx()) { 13980 pw.print(",high-end-gfx"); 13981 } 13982 pw.println(); 13983 } 13984 } 13985 } 13986 } 13987 13988 /** 13989 * Searches array of arguments for the specified string 13990 * @param args array of argument strings 13991 * @param value value to search for 13992 * @return true if the value is contained in the array 13993 */ 13994 private static boolean scanArgs(String[] args, String value) { 13995 if (args != null) { 13996 for (String arg : args) { 13997 if (value.equals(arg)) { 13998 return true; 13999 } 14000 } 14001 } 14002 return false; 14003 } 14004 14005 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14006 ContentProviderRecord cpr, boolean always) { 14007 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14008 14009 if (!inLaunching || always) { 14010 synchronized (cpr) { 14011 cpr.launchingApp = null; 14012 cpr.notifyAll(); 14013 } 14014 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14015 String names[] = cpr.info.authority.split(";"); 14016 for (int j = 0; j < names.length; j++) { 14017 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14018 } 14019 } 14020 14021 for (int i=0; i<cpr.connections.size(); i++) { 14022 ContentProviderConnection conn = cpr.connections.get(i); 14023 if (conn.waiting) { 14024 // If this connection is waiting for the provider, then we don't 14025 // need to mess with its process unless we are always removing 14026 // or for some reason the provider is not currently launching. 14027 if (inLaunching && !always) { 14028 continue; 14029 } 14030 } 14031 ProcessRecord capp = conn.client; 14032 conn.dead = true; 14033 if (conn.stableCount > 0) { 14034 if (!capp.persistent && capp.thread != null 14035 && capp.pid != 0 14036 && capp.pid != MY_PID) { 14037 capp.kill("depends on provider " 14038 + cpr.name.flattenToShortString() 14039 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14040 } 14041 } else if (capp.thread != null && conn.provider.provider != null) { 14042 try { 14043 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14044 } catch (RemoteException e) { 14045 } 14046 // In the protocol here, we don't expect the client to correctly 14047 // clean up this connection, we'll just remove it. 14048 cpr.connections.remove(i); 14049 conn.client.conProviders.remove(conn); 14050 } 14051 } 14052 14053 if (inLaunching && always) { 14054 mLaunchingProviders.remove(cpr); 14055 } 14056 return inLaunching; 14057 } 14058 14059 /** 14060 * Main code for cleaning up a process when it has gone away. This is 14061 * called both as a result of the process dying, or directly when stopping 14062 * a process when running in single process mode. 14063 */ 14064 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14065 boolean restarting, boolean allowRestart, int index) { 14066 if (index >= 0) { 14067 removeLruProcessLocked(app); 14068 ProcessList.remove(app.pid); 14069 } 14070 14071 mProcessesToGc.remove(app); 14072 mPendingPssProcesses.remove(app); 14073 14074 // Dismiss any open dialogs. 14075 if (app.crashDialog != null && !app.forceCrashReport) { 14076 app.crashDialog.dismiss(); 14077 app.crashDialog = null; 14078 } 14079 if (app.anrDialog != null) { 14080 app.anrDialog.dismiss(); 14081 app.anrDialog = null; 14082 } 14083 if (app.waitDialog != null) { 14084 app.waitDialog.dismiss(); 14085 app.waitDialog = null; 14086 } 14087 14088 app.crashing = false; 14089 app.notResponding = false; 14090 14091 app.resetPackageList(mProcessStats); 14092 app.unlinkDeathRecipient(); 14093 app.makeInactive(mProcessStats); 14094 app.waitingToKill = null; 14095 app.forcingToForeground = null; 14096 updateProcessForegroundLocked(app, false, false); 14097 app.foregroundActivities = false; 14098 app.hasShownUi = false; 14099 app.treatLikeActivity = false; 14100 app.hasAboveClient = false; 14101 app.hasClientActivities = false; 14102 14103 mServices.killServicesLocked(app, allowRestart); 14104 14105 boolean restart = false; 14106 14107 // Remove published content providers. 14108 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14109 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14110 final boolean always = app.bad || !allowRestart; 14111 if (removeDyingProviderLocked(app, cpr, always) || always) { 14112 // We left the provider in the launching list, need to 14113 // restart it. 14114 restart = true; 14115 } 14116 14117 cpr.provider = null; 14118 cpr.proc = null; 14119 } 14120 app.pubProviders.clear(); 14121 14122 // Take care of any launching providers waiting for this process. 14123 if (checkAppInLaunchingProvidersLocked(app, false)) { 14124 restart = true; 14125 } 14126 14127 // Unregister from connected content providers. 14128 if (!app.conProviders.isEmpty()) { 14129 for (int i=0; i<app.conProviders.size(); i++) { 14130 ContentProviderConnection conn = app.conProviders.get(i); 14131 conn.provider.connections.remove(conn); 14132 } 14133 app.conProviders.clear(); 14134 } 14135 14136 // At this point there may be remaining entries in mLaunchingProviders 14137 // where we were the only one waiting, so they are no longer of use. 14138 // Look for these and clean up if found. 14139 // XXX Commented out for now. Trying to figure out a way to reproduce 14140 // the actual situation to identify what is actually going on. 14141 if (false) { 14142 for (int i=0; i<mLaunchingProviders.size(); i++) { 14143 ContentProviderRecord cpr = (ContentProviderRecord) 14144 mLaunchingProviders.get(i); 14145 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14146 synchronized (cpr) { 14147 cpr.launchingApp = null; 14148 cpr.notifyAll(); 14149 } 14150 } 14151 } 14152 } 14153 14154 skipCurrentReceiverLocked(app); 14155 14156 // Unregister any receivers. 14157 for (int i=app.receivers.size()-1; i>=0; i--) { 14158 removeReceiverLocked(app.receivers.valueAt(i)); 14159 } 14160 app.receivers.clear(); 14161 14162 // If the app is undergoing backup, tell the backup manager about it 14163 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14164 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14165 + mBackupTarget.appInfo + " died during backup"); 14166 try { 14167 IBackupManager bm = IBackupManager.Stub.asInterface( 14168 ServiceManager.getService(Context.BACKUP_SERVICE)); 14169 bm.agentDisconnected(app.info.packageName); 14170 } catch (RemoteException e) { 14171 // can't happen; backup manager is local 14172 } 14173 } 14174 14175 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14176 ProcessChangeItem item = mPendingProcessChanges.get(i); 14177 if (item.pid == app.pid) { 14178 mPendingProcessChanges.remove(i); 14179 mAvailProcessChanges.add(item); 14180 } 14181 } 14182 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14183 14184 // If the caller is restarting this app, then leave it in its 14185 // current lists and let the caller take care of it. 14186 if (restarting) { 14187 return; 14188 } 14189 14190 if (!app.persistent || app.isolated) { 14191 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14192 "Removing non-persistent process during cleanup: " + app); 14193 mProcessNames.remove(app.processName, app.uid); 14194 mIsolatedProcesses.remove(app.uid); 14195 if (mHeavyWeightProcess == app) { 14196 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14197 mHeavyWeightProcess.userId, 0)); 14198 mHeavyWeightProcess = null; 14199 } 14200 } else if (!app.removed) { 14201 // This app is persistent, so we need to keep its record around. 14202 // If it is not already on the pending app list, add it there 14203 // and start a new process for it. 14204 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14205 mPersistentStartingProcesses.add(app); 14206 restart = true; 14207 } 14208 } 14209 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14210 "Clean-up removing on hold: " + app); 14211 mProcessesOnHold.remove(app); 14212 14213 if (app == mHomeProcess) { 14214 mHomeProcess = null; 14215 } 14216 if (app == mPreviousProcess) { 14217 mPreviousProcess = null; 14218 } 14219 14220 if (restart && !app.isolated) { 14221 // We have components that still need to be running in the 14222 // process, so re-launch it. 14223 mProcessNames.put(app.processName, app.uid, app); 14224 startProcessLocked(app, "restart", app.processName); 14225 } else if (app.pid > 0 && app.pid != MY_PID) { 14226 // Goodbye! 14227 boolean removed; 14228 synchronized (mPidsSelfLocked) { 14229 mPidsSelfLocked.remove(app.pid); 14230 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14231 } 14232 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14233 if (app.isolated) { 14234 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14235 } 14236 app.setPid(0); 14237 } 14238 } 14239 14240 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14241 // Look through the content providers we are waiting to have launched, 14242 // and if any run in this process then either schedule a restart of 14243 // the process or kill the client waiting for it if this process has 14244 // gone bad. 14245 int NL = mLaunchingProviders.size(); 14246 boolean restart = false; 14247 for (int i=0; i<NL; i++) { 14248 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14249 if (cpr.launchingApp == app) { 14250 if (!alwaysBad && !app.bad) { 14251 restart = true; 14252 } else { 14253 removeDyingProviderLocked(app, cpr, true); 14254 // cpr should have been removed from mLaunchingProviders 14255 NL = mLaunchingProviders.size(); 14256 i--; 14257 } 14258 } 14259 } 14260 return restart; 14261 } 14262 14263 // ========================================================= 14264 // SERVICES 14265 // ========================================================= 14266 14267 @Override 14268 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14269 int flags) { 14270 enforceNotIsolatedCaller("getServices"); 14271 synchronized (this) { 14272 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14273 } 14274 } 14275 14276 @Override 14277 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14278 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14279 synchronized (this) { 14280 return mServices.getRunningServiceControlPanelLocked(name); 14281 } 14282 } 14283 14284 @Override 14285 public ComponentName startService(IApplicationThread caller, Intent service, 14286 String resolvedType, int userId) { 14287 enforceNotIsolatedCaller("startService"); 14288 // Refuse possible leaked file descriptors 14289 if (service != null && service.hasFileDescriptors() == true) { 14290 throw new IllegalArgumentException("File descriptors passed in Intent"); 14291 } 14292 14293 if (DEBUG_SERVICE) 14294 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14295 synchronized(this) { 14296 final int callingPid = Binder.getCallingPid(); 14297 final int callingUid = Binder.getCallingUid(); 14298 final long origId = Binder.clearCallingIdentity(); 14299 ComponentName res = mServices.startServiceLocked(caller, service, 14300 resolvedType, callingPid, callingUid, userId); 14301 Binder.restoreCallingIdentity(origId); 14302 return res; 14303 } 14304 } 14305 14306 ComponentName startServiceInPackage(int uid, 14307 Intent service, String resolvedType, int userId) { 14308 synchronized(this) { 14309 if (DEBUG_SERVICE) 14310 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14311 final long origId = Binder.clearCallingIdentity(); 14312 ComponentName res = mServices.startServiceLocked(null, service, 14313 resolvedType, -1, uid, userId); 14314 Binder.restoreCallingIdentity(origId); 14315 return res; 14316 } 14317 } 14318 14319 @Override 14320 public int stopService(IApplicationThread caller, Intent service, 14321 String resolvedType, int userId) { 14322 enforceNotIsolatedCaller("stopService"); 14323 // Refuse possible leaked file descriptors 14324 if (service != null && service.hasFileDescriptors() == true) { 14325 throw new IllegalArgumentException("File descriptors passed in Intent"); 14326 } 14327 14328 synchronized(this) { 14329 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14330 } 14331 } 14332 14333 @Override 14334 public IBinder peekService(Intent service, String resolvedType) { 14335 enforceNotIsolatedCaller("peekService"); 14336 // Refuse possible leaked file descriptors 14337 if (service != null && service.hasFileDescriptors() == true) { 14338 throw new IllegalArgumentException("File descriptors passed in Intent"); 14339 } 14340 synchronized(this) { 14341 return mServices.peekServiceLocked(service, resolvedType); 14342 } 14343 } 14344 14345 @Override 14346 public boolean stopServiceToken(ComponentName className, IBinder token, 14347 int startId) { 14348 synchronized(this) { 14349 return mServices.stopServiceTokenLocked(className, token, startId); 14350 } 14351 } 14352 14353 @Override 14354 public void setServiceForeground(ComponentName className, IBinder token, 14355 int id, Notification notification, boolean removeNotification) { 14356 synchronized(this) { 14357 mServices.setServiceForegroundLocked(className, token, id, notification, 14358 removeNotification); 14359 } 14360 } 14361 14362 @Override 14363 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14364 boolean requireFull, String name, String callerPackage) { 14365 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14366 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14367 } 14368 14369 int unsafeConvertIncomingUser(int userId) { 14370 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14371 ? mCurrentUserId : userId; 14372 } 14373 14374 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14375 int allowMode, String name, String callerPackage) { 14376 final int callingUserId = UserHandle.getUserId(callingUid); 14377 if (callingUserId == userId) { 14378 return userId; 14379 } 14380 14381 // Note that we may be accessing mCurrentUserId outside of a lock... 14382 // shouldn't be a big deal, if this is being called outside 14383 // of a locked context there is intrinsically a race with 14384 // the value the caller will receive and someone else changing it. 14385 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14386 // we will switch to the calling user if access to the current user fails. 14387 int targetUserId = unsafeConvertIncomingUser(userId); 14388 14389 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14390 final boolean allow; 14391 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14392 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14393 // If the caller has this permission, they always pass go. And collect $200. 14394 allow = true; 14395 } else if (allowMode == ALLOW_FULL_ONLY) { 14396 // We require full access, sucks to be you. 14397 allow = false; 14398 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14399 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14400 // If the caller does not have either permission, they are always doomed. 14401 allow = false; 14402 } else if (allowMode == ALLOW_NON_FULL) { 14403 // We are blanket allowing non-full access, you lucky caller! 14404 allow = true; 14405 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14406 // We may or may not allow this depending on whether the two users are 14407 // in the same profile. 14408 synchronized (mUserProfileGroupIdsSelfLocked) { 14409 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14410 UserInfo.NO_PROFILE_GROUP_ID); 14411 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14412 UserInfo.NO_PROFILE_GROUP_ID); 14413 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14414 && callingProfile == targetProfile; 14415 } 14416 } else { 14417 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14418 } 14419 if (!allow) { 14420 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14421 // In this case, they would like to just execute as their 14422 // owner user instead of failing. 14423 targetUserId = callingUserId; 14424 } else { 14425 StringBuilder builder = new StringBuilder(128); 14426 builder.append("Permission Denial: "); 14427 builder.append(name); 14428 if (callerPackage != null) { 14429 builder.append(" from "); 14430 builder.append(callerPackage); 14431 } 14432 builder.append(" asks to run as user "); 14433 builder.append(userId); 14434 builder.append(" but is calling from user "); 14435 builder.append(UserHandle.getUserId(callingUid)); 14436 builder.append("; this requires "); 14437 builder.append(INTERACT_ACROSS_USERS_FULL); 14438 if (allowMode != ALLOW_FULL_ONLY) { 14439 builder.append(" or "); 14440 builder.append(INTERACT_ACROSS_USERS); 14441 } 14442 String msg = builder.toString(); 14443 Slog.w(TAG, msg); 14444 throw new SecurityException(msg); 14445 } 14446 } 14447 } 14448 if (!allowAll && targetUserId < 0) { 14449 throw new IllegalArgumentException( 14450 "Call does not support special user #" + targetUserId); 14451 } 14452 return targetUserId; 14453 } 14454 14455 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14456 String className, int flags) { 14457 boolean result = false; 14458 // For apps that don't have pre-defined UIDs, check for permission 14459 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14460 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14461 if (ActivityManager.checkUidPermission( 14462 INTERACT_ACROSS_USERS, 14463 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14464 ComponentName comp = new ComponentName(aInfo.packageName, className); 14465 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14466 + " requests FLAG_SINGLE_USER, but app does not hold " 14467 + INTERACT_ACROSS_USERS; 14468 Slog.w(TAG, msg); 14469 throw new SecurityException(msg); 14470 } 14471 // Permission passed 14472 result = true; 14473 } 14474 } else if ("system".equals(componentProcessName)) { 14475 result = true; 14476 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14477 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14478 // Phone app is allowed to export singleuser providers. 14479 result = true; 14480 } else { 14481 // App with pre-defined UID, check if it's a persistent app 14482 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14483 } 14484 if (DEBUG_MU) { 14485 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14486 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14487 } 14488 return result; 14489 } 14490 14491 /** 14492 * Checks to see if the caller is in the same app as the singleton 14493 * component, or the component is in a special app. It allows special apps 14494 * to export singleton components but prevents exporting singleton 14495 * components for regular apps. 14496 */ 14497 boolean isValidSingletonCall(int callingUid, int componentUid) { 14498 int componentAppId = UserHandle.getAppId(componentUid); 14499 return UserHandle.isSameApp(callingUid, componentUid) 14500 || componentAppId == Process.SYSTEM_UID 14501 || componentAppId == Process.PHONE_UID 14502 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14503 == PackageManager.PERMISSION_GRANTED; 14504 } 14505 14506 public int bindService(IApplicationThread caller, IBinder token, 14507 Intent service, String resolvedType, 14508 IServiceConnection connection, int flags, int userId) { 14509 enforceNotIsolatedCaller("bindService"); 14510 // Refuse possible leaked file descriptors 14511 if (service != null && service.hasFileDescriptors() == true) { 14512 throw new IllegalArgumentException("File descriptors passed in Intent"); 14513 } 14514 14515 synchronized(this) { 14516 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14517 connection, flags, userId); 14518 } 14519 } 14520 14521 public boolean unbindService(IServiceConnection connection) { 14522 synchronized (this) { 14523 return mServices.unbindServiceLocked(connection); 14524 } 14525 } 14526 14527 public void publishService(IBinder token, Intent intent, IBinder service) { 14528 // Refuse possible leaked file descriptors 14529 if (intent != null && intent.hasFileDescriptors() == true) { 14530 throw new IllegalArgumentException("File descriptors passed in Intent"); 14531 } 14532 14533 synchronized(this) { 14534 if (!(token instanceof ServiceRecord)) { 14535 throw new IllegalArgumentException("Invalid service token"); 14536 } 14537 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14538 } 14539 } 14540 14541 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14542 // Refuse possible leaked file descriptors 14543 if (intent != null && intent.hasFileDescriptors() == true) { 14544 throw new IllegalArgumentException("File descriptors passed in Intent"); 14545 } 14546 14547 synchronized(this) { 14548 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14549 } 14550 } 14551 14552 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14553 synchronized(this) { 14554 if (!(token instanceof ServiceRecord)) { 14555 throw new IllegalArgumentException("Invalid service token"); 14556 } 14557 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14558 } 14559 } 14560 14561 // ========================================================= 14562 // BACKUP AND RESTORE 14563 // ========================================================= 14564 14565 // Cause the target app to be launched if necessary and its backup agent 14566 // instantiated. The backup agent will invoke backupAgentCreated() on the 14567 // activity manager to announce its creation. 14568 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14569 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14570 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14571 14572 synchronized(this) { 14573 // !!! TODO: currently no check here that we're already bound 14574 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14575 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14576 synchronized (stats) { 14577 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14578 } 14579 14580 // Backup agent is now in use, its package can't be stopped. 14581 try { 14582 AppGlobals.getPackageManager().setPackageStoppedState( 14583 app.packageName, false, UserHandle.getUserId(app.uid)); 14584 } catch (RemoteException e) { 14585 } catch (IllegalArgumentException e) { 14586 Slog.w(TAG, "Failed trying to unstop package " 14587 + app.packageName + ": " + e); 14588 } 14589 14590 BackupRecord r = new BackupRecord(ss, app, backupMode); 14591 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14592 ? new ComponentName(app.packageName, app.backupAgentName) 14593 : new ComponentName("android", "FullBackupAgent"); 14594 // startProcessLocked() returns existing proc's record if it's already running 14595 ProcessRecord proc = startProcessLocked(app.processName, app, 14596 false, 0, "backup", hostingName, false, false, false); 14597 if (proc == null) { 14598 Slog.e(TAG, "Unable to start backup agent process " + r); 14599 return false; 14600 } 14601 14602 r.app = proc; 14603 mBackupTarget = r; 14604 mBackupAppName = app.packageName; 14605 14606 // Try not to kill the process during backup 14607 updateOomAdjLocked(proc); 14608 14609 // If the process is already attached, schedule the creation of the backup agent now. 14610 // If it is not yet live, this will be done when it attaches to the framework. 14611 if (proc.thread != null) { 14612 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14613 try { 14614 proc.thread.scheduleCreateBackupAgent(app, 14615 compatibilityInfoForPackageLocked(app), backupMode); 14616 } catch (RemoteException e) { 14617 // Will time out on the backup manager side 14618 } 14619 } else { 14620 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14621 } 14622 // Invariants: at this point, the target app process exists and the application 14623 // is either already running or in the process of coming up. mBackupTarget and 14624 // mBackupAppName describe the app, so that when it binds back to the AM we 14625 // know that it's scheduled for a backup-agent operation. 14626 } 14627 14628 return true; 14629 } 14630 14631 @Override 14632 public void clearPendingBackup() { 14633 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14634 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14635 14636 synchronized (this) { 14637 mBackupTarget = null; 14638 mBackupAppName = null; 14639 } 14640 } 14641 14642 // A backup agent has just come up 14643 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14644 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14645 + " = " + agent); 14646 14647 synchronized(this) { 14648 if (!agentPackageName.equals(mBackupAppName)) { 14649 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14650 return; 14651 } 14652 } 14653 14654 long oldIdent = Binder.clearCallingIdentity(); 14655 try { 14656 IBackupManager bm = IBackupManager.Stub.asInterface( 14657 ServiceManager.getService(Context.BACKUP_SERVICE)); 14658 bm.agentConnected(agentPackageName, agent); 14659 } catch (RemoteException e) { 14660 // can't happen; the backup manager service is local 14661 } catch (Exception e) { 14662 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14663 e.printStackTrace(); 14664 } finally { 14665 Binder.restoreCallingIdentity(oldIdent); 14666 } 14667 } 14668 14669 // done with this agent 14670 public void unbindBackupAgent(ApplicationInfo appInfo) { 14671 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14672 if (appInfo == null) { 14673 Slog.w(TAG, "unbind backup agent for null app"); 14674 return; 14675 } 14676 14677 synchronized(this) { 14678 try { 14679 if (mBackupAppName == null) { 14680 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14681 return; 14682 } 14683 14684 if (!mBackupAppName.equals(appInfo.packageName)) { 14685 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14686 return; 14687 } 14688 14689 // Not backing this app up any more; reset its OOM adjustment 14690 final ProcessRecord proc = mBackupTarget.app; 14691 updateOomAdjLocked(proc); 14692 14693 // If the app crashed during backup, 'thread' will be null here 14694 if (proc.thread != null) { 14695 try { 14696 proc.thread.scheduleDestroyBackupAgent(appInfo, 14697 compatibilityInfoForPackageLocked(appInfo)); 14698 } catch (Exception e) { 14699 Slog.e(TAG, "Exception when unbinding backup agent:"); 14700 e.printStackTrace(); 14701 } 14702 } 14703 } finally { 14704 mBackupTarget = null; 14705 mBackupAppName = null; 14706 } 14707 } 14708 } 14709 // ========================================================= 14710 // BROADCASTS 14711 // ========================================================= 14712 14713 private final List getStickiesLocked(String action, IntentFilter filter, 14714 List cur, int userId) { 14715 final ContentResolver resolver = mContext.getContentResolver(); 14716 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14717 if (stickies == null) { 14718 return cur; 14719 } 14720 final ArrayList<Intent> list = stickies.get(action); 14721 if (list == null) { 14722 return cur; 14723 } 14724 int N = list.size(); 14725 for (int i=0; i<N; i++) { 14726 Intent intent = list.get(i); 14727 if (filter.match(resolver, intent, true, TAG) >= 0) { 14728 if (cur == null) { 14729 cur = new ArrayList<Intent>(); 14730 } 14731 cur.add(intent); 14732 } 14733 } 14734 return cur; 14735 } 14736 14737 boolean isPendingBroadcastProcessLocked(int pid) { 14738 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14739 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14740 } 14741 14742 void skipPendingBroadcastLocked(int pid) { 14743 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14744 for (BroadcastQueue queue : mBroadcastQueues) { 14745 queue.skipPendingBroadcastLocked(pid); 14746 } 14747 } 14748 14749 // The app just attached; send any pending broadcasts that it should receive 14750 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14751 boolean didSomething = false; 14752 for (BroadcastQueue queue : mBroadcastQueues) { 14753 didSomething |= queue.sendPendingBroadcastsLocked(app); 14754 } 14755 return didSomething; 14756 } 14757 14758 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14759 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14760 enforceNotIsolatedCaller("registerReceiver"); 14761 int callingUid; 14762 int callingPid; 14763 synchronized(this) { 14764 ProcessRecord callerApp = null; 14765 if (caller != null) { 14766 callerApp = getRecordForAppLocked(caller); 14767 if (callerApp == null) { 14768 throw new SecurityException( 14769 "Unable to find app for caller " + caller 14770 + " (pid=" + Binder.getCallingPid() 14771 + ") when registering receiver " + receiver); 14772 } 14773 if (callerApp.info.uid != Process.SYSTEM_UID && 14774 !callerApp.pkgList.containsKey(callerPackage) && 14775 !"android".equals(callerPackage)) { 14776 throw new SecurityException("Given caller package " + callerPackage 14777 + " is not running in process " + callerApp); 14778 } 14779 callingUid = callerApp.info.uid; 14780 callingPid = callerApp.pid; 14781 } else { 14782 callerPackage = null; 14783 callingUid = Binder.getCallingUid(); 14784 callingPid = Binder.getCallingPid(); 14785 } 14786 14787 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14788 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14789 14790 List allSticky = null; 14791 14792 // Look for any matching sticky broadcasts... 14793 Iterator actions = filter.actionsIterator(); 14794 if (actions != null) { 14795 while (actions.hasNext()) { 14796 String action = (String)actions.next(); 14797 allSticky = getStickiesLocked(action, filter, allSticky, 14798 UserHandle.USER_ALL); 14799 allSticky = getStickiesLocked(action, filter, allSticky, 14800 UserHandle.getUserId(callingUid)); 14801 } 14802 } else { 14803 allSticky = getStickiesLocked(null, filter, allSticky, 14804 UserHandle.USER_ALL); 14805 allSticky = getStickiesLocked(null, filter, allSticky, 14806 UserHandle.getUserId(callingUid)); 14807 } 14808 14809 // The first sticky in the list is returned directly back to 14810 // the client. 14811 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14812 14813 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14814 + ": " + sticky); 14815 14816 if (receiver == null) { 14817 return sticky; 14818 } 14819 14820 ReceiverList rl 14821 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14822 if (rl == null) { 14823 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14824 userId, receiver); 14825 if (rl.app != null) { 14826 rl.app.receivers.add(rl); 14827 } else { 14828 try { 14829 receiver.asBinder().linkToDeath(rl, 0); 14830 } catch (RemoteException e) { 14831 return sticky; 14832 } 14833 rl.linkedToDeath = true; 14834 } 14835 mRegisteredReceivers.put(receiver.asBinder(), rl); 14836 } else if (rl.uid != callingUid) { 14837 throw new IllegalArgumentException( 14838 "Receiver requested to register for uid " + callingUid 14839 + " was previously registered for uid " + rl.uid); 14840 } else if (rl.pid != callingPid) { 14841 throw new IllegalArgumentException( 14842 "Receiver requested to register for pid " + callingPid 14843 + " was previously registered for pid " + rl.pid); 14844 } else if (rl.userId != userId) { 14845 throw new IllegalArgumentException( 14846 "Receiver requested to register for user " + userId 14847 + " was previously registered for user " + rl.userId); 14848 } 14849 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14850 permission, callingUid, userId); 14851 rl.add(bf); 14852 if (!bf.debugCheck()) { 14853 Slog.w(TAG, "==> For Dynamic broadast"); 14854 } 14855 mReceiverResolver.addFilter(bf); 14856 14857 // Enqueue broadcasts for all existing stickies that match 14858 // this filter. 14859 if (allSticky != null) { 14860 ArrayList receivers = new ArrayList(); 14861 receivers.add(bf); 14862 14863 int N = allSticky.size(); 14864 for (int i=0; i<N; i++) { 14865 Intent intent = (Intent)allSticky.get(i); 14866 BroadcastQueue queue = broadcastQueueForIntent(intent); 14867 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14868 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14869 null, null, false, true, true, -1); 14870 queue.enqueueParallelBroadcastLocked(r); 14871 queue.scheduleBroadcastsLocked(); 14872 } 14873 } 14874 14875 return sticky; 14876 } 14877 } 14878 14879 public void unregisterReceiver(IIntentReceiver receiver) { 14880 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14881 14882 final long origId = Binder.clearCallingIdentity(); 14883 try { 14884 boolean doTrim = false; 14885 14886 synchronized(this) { 14887 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14888 if (rl != null) { 14889 if (rl.curBroadcast != null) { 14890 BroadcastRecord r = rl.curBroadcast; 14891 final boolean doNext = finishReceiverLocked( 14892 receiver.asBinder(), r.resultCode, r.resultData, 14893 r.resultExtras, r.resultAbort); 14894 if (doNext) { 14895 doTrim = true; 14896 r.queue.processNextBroadcast(false); 14897 } 14898 } 14899 14900 if (rl.app != null) { 14901 rl.app.receivers.remove(rl); 14902 } 14903 removeReceiverLocked(rl); 14904 if (rl.linkedToDeath) { 14905 rl.linkedToDeath = false; 14906 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14907 } 14908 } 14909 } 14910 14911 // If we actually concluded any broadcasts, we might now be able 14912 // to trim the recipients' apps from our working set 14913 if (doTrim) { 14914 trimApplications(); 14915 return; 14916 } 14917 14918 } finally { 14919 Binder.restoreCallingIdentity(origId); 14920 } 14921 } 14922 14923 void removeReceiverLocked(ReceiverList rl) { 14924 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14925 int N = rl.size(); 14926 for (int i=0; i<N; i++) { 14927 mReceiverResolver.removeFilter(rl.get(i)); 14928 } 14929 } 14930 14931 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14932 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14933 ProcessRecord r = mLruProcesses.get(i); 14934 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14935 try { 14936 r.thread.dispatchPackageBroadcast(cmd, packages); 14937 } catch (RemoteException ex) { 14938 } 14939 } 14940 } 14941 } 14942 14943 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14944 int[] users) { 14945 List<ResolveInfo> receivers = null; 14946 try { 14947 HashSet<ComponentName> singleUserReceivers = null; 14948 boolean scannedFirstReceivers = false; 14949 for (int user : users) { 14950 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14951 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14952 if (user != 0 && newReceivers != null) { 14953 // If this is not the primary user, we need to check for 14954 // any receivers that should be filtered out. 14955 for (int i=0; i<newReceivers.size(); i++) { 14956 ResolveInfo ri = newReceivers.get(i); 14957 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14958 newReceivers.remove(i); 14959 i--; 14960 } 14961 } 14962 } 14963 if (newReceivers != null && newReceivers.size() == 0) { 14964 newReceivers = null; 14965 } 14966 if (receivers == null) { 14967 receivers = newReceivers; 14968 } else if (newReceivers != null) { 14969 // We need to concatenate the additional receivers 14970 // found with what we have do far. This would be easy, 14971 // but we also need to de-dup any receivers that are 14972 // singleUser. 14973 if (!scannedFirstReceivers) { 14974 // Collect any single user receivers we had already retrieved. 14975 scannedFirstReceivers = true; 14976 for (int i=0; i<receivers.size(); i++) { 14977 ResolveInfo ri = receivers.get(i); 14978 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14979 ComponentName cn = new ComponentName( 14980 ri.activityInfo.packageName, ri.activityInfo.name); 14981 if (singleUserReceivers == null) { 14982 singleUserReceivers = new HashSet<ComponentName>(); 14983 } 14984 singleUserReceivers.add(cn); 14985 } 14986 } 14987 } 14988 // Add the new results to the existing results, tracking 14989 // and de-dupping single user receivers. 14990 for (int i=0; i<newReceivers.size(); i++) { 14991 ResolveInfo ri = newReceivers.get(i); 14992 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14993 ComponentName cn = new ComponentName( 14994 ri.activityInfo.packageName, ri.activityInfo.name); 14995 if (singleUserReceivers == null) { 14996 singleUserReceivers = new HashSet<ComponentName>(); 14997 } 14998 if (!singleUserReceivers.contains(cn)) { 14999 singleUserReceivers.add(cn); 15000 receivers.add(ri); 15001 } 15002 } else { 15003 receivers.add(ri); 15004 } 15005 } 15006 } 15007 } 15008 } catch (RemoteException ex) { 15009 // pm is in same process, this will never happen. 15010 } 15011 return receivers; 15012 } 15013 15014 private final int broadcastIntentLocked(ProcessRecord callerApp, 15015 String callerPackage, Intent intent, String resolvedType, 15016 IIntentReceiver resultTo, int resultCode, String resultData, 15017 Bundle map, String requiredPermission, int appOp, 15018 boolean ordered, boolean sticky, int callingPid, int callingUid, 15019 int userId) { 15020 intent = new Intent(intent); 15021 15022 // By default broadcasts do not go to stopped apps. 15023 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15024 15025 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15026 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15027 + " ordered=" + ordered + " userid=" + userId); 15028 if ((resultTo != null) && !ordered) { 15029 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15030 } 15031 15032 userId = handleIncomingUser(callingPid, callingUid, userId, 15033 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15034 15035 // Make sure that the user who is receiving this broadcast is started. 15036 // If not, we will just skip it. 15037 15038 15039 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15040 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15041 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15042 Slog.w(TAG, "Skipping broadcast of " + intent 15043 + ": user " + userId + " is stopped"); 15044 return ActivityManager.BROADCAST_SUCCESS; 15045 } 15046 } 15047 15048 /* 15049 * Prevent non-system code (defined here to be non-persistent 15050 * processes) from sending protected broadcasts. 15051 */ 15052 int callingAppId = UserHandle.getAppId(callingUid); 15053 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15054 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15055 || callingAppId == Process.NFC_UID || callingUid == 0) { 15056 // Always okay. 15057 } else if (callerApp == null || !callerApp.persistent) { 15058 try { 15059 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15060 intent.getAction())) { 15061 String msg = "Permission Denial: not allowed to send broadcast " 15062 + intent.getAction() + " from pid=" 15063 + callingPid + ", uid=" + callingUid; 15064 Slog.w(TAG, msg); 15065 throw new SecurityException(msg); 15066 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15067 // Special case for compatibility: we don't want apps to send this, 15068 // but historically it has not been protected and apps may be using it 15069 // to poke their own app widget. So, instead of making it protected, 15070 // just limit it to the caller. 15071 if (callerApp == null) { 15072 String msg = "Permission Denial: not allowed to send broadcast " 15073 + intent.getAction() + " from unknown caller."; 15074 Slog.w(TAG, msg); 15075 throw new SecurityException(msg); 15076 } else if (intent.getComponent() != null) { 15077 // They are good enough to send to an explicit component... verify 15078 // it is being sent to the calling app. 15079 if (!intent.getComponent().getPackageName().equals( 15080 callerApp.info.packageName)) { 15081 String msg = "Permission Denial: not allowed to send broadcast " 15082 + intent.getAction() + " to " 15083 + intent.getComponent().getPackageName() + " from " 15084 + callerApp.info.packageName; 15085 Slog.w(TAG, msg); 15086 throw new SecurityException(msg); 15087 } 15088 } else { 15089 // Limit broadcast to their own package. 15090 intent.setPackage(callerApp.info.packageName); 15091 } 15092 } 15093 } catch (RemoteException e) { 15094 Slog.w(TAG, "Remote exception", e); 15095 return ActivityManager.BROADCAST_SUCCESS; 15096 } 15097 } 15098 15099 // Handle special intents: if this broadcast is from the package 15100 // manager about a package being removed, we need to remove all of 15101 // its activities from the history stack. 15102 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15103 intent.getAction()); 15104 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15105 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15106 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15107 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15108 || uidRemoved) { 15109 if (checkComponentPermission( 15110 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15111 callingPid, callingUid, -1, true) 15112 == PackageManager.PERMISSION_GRANTED) { 15113 if (uidRemoved) { 15114 final Bundle intentExtras = intent.getExtras(); 15115 final int uid = intentExtras != null 15116 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15117 if (uid >= 0) { 15118 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15119 synchronized (bs) { 15120 bs.removeUidStatsLocked(uid); 15121 } 15122 mAppOpsService.uidRemoved(uid); 15123 } 15124 } else { 15125 // If resources are unavailable just force stop all 15126 // those packages and flush the attribute cache as well. 15127 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15128 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15129 if (list != null && (list.length > 0)) { 15130 for (String pkg : list) { 15131 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15132 "storage unmount"); 15133 } 15134 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15135 sendPackageBroadcastLocked( 15136 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15137 } 15138 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15139 intent.getAction())) { 15140 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15141 } else { 15142 Uri data = intent.getData(); 15143 String ssp; 15144 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15145 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15146 intent.getAction()); 15147 boolean fullUninstall = removed && 15148 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15149 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15150 forceStopPackageLocked(ssp, UserHandle.getAppId( 15151 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15152 false, fullUninstall, userId, 15153 removed ? "pkg removed" : "pkg changed"); 15154 } 15155 if (removed) { 15156 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15157 new String[] {ssp}, userId); 15158 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15159 mAppOpsService.packageRemoved( 15160 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15161 15162 // Remove all permissions granted from/to this package 15163 removeUriPermissionsForPackageLocked(ssp, userId, true); 15164 } 15165 } 15166 } 15167 } 15168 } 15169 } else { 15170 String msg = "Permission Denial: " + intent.getAction() 15171 + " broadcast from " + callerPackage + " (pid=" + callingPid 15172 + ", uid=" + callingUid + ")" 15173 + " requires " 15174 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15175 Slog.w(TAG, msg); 15176 throw new SecurityException(msg); 15177 } 15178 15179 // Special case for adding a package: by default turn on compatibility 15180 // mode. 15181 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15182 Uri data = intent.getData(); 15183 String ssp; 15184 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15185 mCompatModePackages.handlePackageAddedLocked(ssp, 15186 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15187 } 15188 } 15189 15190 /* 15191 * If this is the time zone changed action, queue up a message that will reset the timezone 15192 * of all currently running processes. This message will get queued up before the broadcast 15193 * happens. 15194 */ 15195 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15196 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15197 } 15198 15199 /* 15200 * If the user set the time, let all running processes know. 15201 */ 15202 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15203 final int is24Hour = intent.getBooleanExtra( 15204 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15205 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15206 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15207 synchronized (stats) { 15208 stats.noteCurrentTimeChangedLocked(); 15209 } 15210 } 15211 15212 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15213 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15214 } 15215 15216 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15217 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15218 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15219 } 15220 15221 // Add to the sticky list if requested. 15222 if (sticky) { 15223 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15224 callingPid, callingUid) 15225 != PackageManager.PERMISSION_GRANTED) { 15226 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15227 + callingPid + ", uid=" + callingUid 15228 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15229 Slog.w(TAG, msg); 15230 throw new SecurityException(msg); 15231 } 15232 if (requiredPermission != null) { 15233 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15234 + " and enforce permission " + requiredPermission); 15235 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15236 } 15237 if (intent.getComponent() != null) { 15238 throw new SecurityException( 15239 "Sticky broadcasts can't target a specific component"); 15240 } 15241 // We use userId directly here, since the "all" target is maintained 15242 // as a separate set of sticky broadcasts. 15243 if (userId != UserHandle.USER_ALL) { 15244 // But first, if this is not a broadcast to all users, then 15245 // make sure it doesn't conflict with an existing broadcast to 15246 // all users. 15247 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15248 UserHandle.USER_ALL); 15249 if (stickies != null) { 15250 ArrayList<Intent> list = stickies.get(intent.getAction()); 15251 if (list != null) { 15252 int N = list.size(); 15253 int i; 15254 for (i=0; i<N; i++) { 15255 if (intent.filterEquals(list.get(i))) { 15256 throw new IllegalArgumentException( 15257 "Sticky broadcast " + intent + " for user " 15258 + userId + " conflicts with existing global broadcast"); 15259 } 15260 } 15261 } 15262 } 15263 } 15264 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15265 if (stickies == null) { 15266 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15267 mStickyBroadcasts.put(userId, stickies); 15268 } 15269 ArrayList<Intent> list = stickies.get(intent.getAction()); 15270 if (list == null) { 15271 list = new ArrayList<Intent>(); 15272 stickies.put(intent.getAction(), list); 15273 } 15274 int N = list.size(); 15275 int i; 15276 for (i=0; i<N; i++) { 15277 if (intent.filterEquals(list.get(i))) { 15278 // This sticky already exists, replace it. 15279 list.set(i, new Intent(intent)); 15280 break; 15281 } 15282 } 15283 if (i >= N) { 15284 list.add(new Intent(intent)); 15285 } 15286 } 15287 15288 int[] users; 15289 if (userId == UserHandle.USER_ALL) { 15290 // Caller wants broadcast to go to all started users. 15291 users = mStartedUserArray; 15292 } else { 15293 // Caller wants broadcast to go to one specific user. 15294 users = new int[] {userId}; 15295 } 15296 15297 // Figure out who all will receive this broadcast. 15298 List receivers = null; 15299 List<BroadcastFilter> registeredReceivers = null; 15300 // Need to resolve the intent to interested receivers... 15301 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15302 == 0) { 15303 receivers = collectReceiverComponents(intent, resolvedType, users); 15304 } 15305 if (intent.getComponent() == null) { 15306 registeredReceivers = mReceiverResolver.queryIntent(intent, 15307 resolvedType, false, userId); 15308 } 15309 15310 final boolean replacePending = 15311 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15312 15313 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15314 + " replacePending=" + replacePending); 15315 15316 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15317 if (!ordered && NR > 0) { 15318 // If we are not serializing this broadcast, then send the 15319 // registered receivers separately so they don't wait for the 15320 // components to be launched. 15321 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15322 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15323 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15324 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15325 ordered, sticky, false, userId); 15326 if (DEBUG_BROADCAST) Slog.v( 15327 TAG, "Enqueueing parallel broadcast " + r); 15328 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15329 if (!replaced) { 15330 queue.enqueueParallelBroadcastLocked(r); 15331 queue.scheduleBroadcastsLocked(); 15332 } 15333 registeredReceivers = null; 15334 NR = 0; 15335 } 15336 15337 // Merge into one list. 15338 int ir = 0; 15339 if (receivers != null) { 15340 // A special case for PACKAGE_ADDED: do not allow the package 15341 // being added to see this broadcast. This prevents them from 15342 // using this as a back door to get run as soon as they are 15343 // installed. Maybe in the future we want to have a special install 15344 // broadcast or such for apps, but we'd like to deliberately make 15345 // this decision. 15346 String skipPackages[] = null; 15347 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15348 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15349 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15350 Uri data = intent.getData(); 15351 if (data != null) { 15352 String pkgName = data.getSchemeSpecificPart(); 15353 if (pkgName != null) { 15354 skipPackages = new String[] { pkgName }; 15355 } 15356 } 15357 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15358 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15359 } 15360 if (skipPackages != null && (skipPackages.length > 0)) { 15361 for (String skipPackage : skipPackages) { 15362 if (skipPackage != null) { 15363 int NT = receivers.size(); 15364 for (int it=0; it<NT; it++) { 15365 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15366 if (curt.activityInfo.packageName.equals(skipPackage)) { 15367 receivers.remove(it); 15368 it--; 15369 NT--; 15370 } 15371 } 15372 } 15373 } 15374 } 15375 15376 int NT = receivers != null ? receivers.size() : 0; 15377 int it = 0; 15378 ResolveInfo curt = null; 15379 BroadcastFilter curr = null; 15380 while (it < NT && ir < NR) { 15381 if (curt == null) { 15382 curt = (ResolveInfo)receivers.get(it); 15383 } 15384 if (curr == null) { 15385 curr = registeredReceivers.get(ir); 15386 } 15387 if (curr.getPriority() >= curt.priority) { 15388 // Insert this broadcast record into the final list. 15389 receivers.add(it, curr); 15390 ir++; 15391 curr = null; 15392 it++; 15393 NT++; 15394 } else { 15395 // Skip to the next ResolveInfo in the final list. 15396 it++; 15397 curt = null; 15398 } 15399 } 15400 } 15401 while (ir < NR) { 15402 if (receivers == null) { 15403 receivers = new ArrayList(); 15404 } 15405 receivers.add(registeredReceivers.get(ir)); 15406 ir++; 15407 } 15408 15409 if ((receivers != null && receivers.size() > 0) 15410 || resultTo != null) { 15411 BroadcastQueue queue = broadcastQueueForIntent(intent); 15412 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15413 callerPackage, callingPid, callingUid, resolvedType, 15414 requiredPermission, appOp, receivers, resultTo, resultCode, 15415 resultData, map, ordered, sticky, false, userId); 15416 if (DEBUG_BROADCAST) Slog.v( 15417 TAG, "Enqueueing ordered broadcast " + r 15418 + ": prev had " + queue.mOrderedBroadcasts.size()); 15419 if (DEBUG_BROADCAST) { 15420 int seq = r.intent.getIntExtra("seq", -1); 15421 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15422 } 15423 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15424 if (!replaced) { 15425 queue.enqueueOrderedBroadcastLocked(r); 15426 queue.scheduleBroadcastsLocked(); 15427 } 15428 } 15429 15430 return ActivityManager.BROADCAST_SUCCESS; 15431 } 15432 15433 final Intent verifyBroadcastLocked(Intent intent) { 15434 // Refuse possible leaked file descriptors 15435 if (intent != null && intent.hasFileDescriptors() == true) { 15436 throw new IllegalArgumentException("File descriptors passed in Intent"); 15437 } 15438 15439 int flags = intent.getFlags(); 15440 15441 if (!mProcessesReady) { 15442 // if the caller really truly claims to know what they're doing, go 15443 // ahead and allow the broadcast without launching any receivers 15444 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15445 intent = new Intent(intent); 15446 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15447 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15448 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15449 + " before boot completion"); 15450 throw new IllegalStateException("Cannot broadcast before boot completed"); 15451 } 15452 } 15453 15454 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15455 throw new IllegalArgumentException( 15456 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15457 } 15458 15459 return intent; 15460 } 15461 15462 public final int broadcastIntent(IApplicationThread caller, 15463 Intent intent, String resolvedType, IIntentReceiver resultTo, 15464 int resultCode, String resultData, Bundle map, 15465 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15466 enforceNotIsolatedCaller("broadcastIntent"); 15467 synchronized(this) { 15468 intent = verifyBroadcastLocked(intent); 15469 15470 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15471 final int callingPid = Binder.getCallingPid(); 15472 final int callingUid = Binder.getCallingUid(); 15473 final long origId = Binder.clearCallingIdentity(); 15474 int res = broadcastIntentLocked(callerApp, 15475 callerApp != null ? callerApp.info.packageName : null, 15476 intent, resolvedType, resultTo, 15477 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15478 callingPid, callingUid, userId); 15479 Binder.restoreCallingIdentity(origId); 15480 return res; 15481 } 15482 } 15483 15484 int broadcastIntentInPackage(String packageName, int uid, 15485 Intent intent, String resolvedType, IIntentReceiver resultTo, 15486 int resultCode, String resultData, Bundle map, 15487 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15488 synchronized(this) { 15489 intent = verifyBroadcastLocked(intent); 15490 15491 final long origId = Binder.clearCallingIdentity(); 15492 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15493 resultTo, resultCode, resultData, map, requiredPermission, 15494 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15495 Binder.restoreCallingIdentity(origId); 15496 return res; 15497 } 15498 } 15499 15500 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15501 // Refuse possible leaked file descriptors 15502 if (intent != null && intent.hasFileDescriptors() == true) { 15503 throw new IllegalArgumentException("File descriptors passed in Intent"); 15504 } 15505 15506 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15507 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15508 15509 synchronized(this) { 15510 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15511 != PackageManager.PERMISSION_GRANTED) { 15512 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15513 + Binder.getCallingPid() 15514 + ", uid=" + Binder.getCallingUid() 15515 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15516 Slog.w(TAG, msg); 15517 throw new SecurityException(msg); 15518 } 15519 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15520 if (stickies != null) { 15521 ArrayList<Intent> list = stickies.get(intent.getAction()); 15522 if (list != null) { 15523 int N = list.size(); 15524 int i; 15525 for (i=0; i<N; i++) { 15526 if (intent.filterEquals(list.get(i))) { 15527 list.remove(i); 15528 break; 15529 } 15530 } 15531 if (list.size() <= 0) { 15532 stickies.remove(intent.getAction()); 15533 } 15534 } 15535 if (stickies.size() <= 0) { 15536 mStickyBroadcasts.remove(userId); 15537 } 15538 } 15539 } 15540 } 15541 15542 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15543 String resultData, Bundle resultExtras, boolean resultAbort) { 15544 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15545 if (r == null) { 15546 Slog.w(TAG, "finishReceiver called but not found on queue"); 15547 return false; 15548 } 15549 15550 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15551 } 15552 15553 void backgroundServicesFinishedLocked(int userId) { 15554 for (BroadcastQueue queue : mBroadcastQueues) { 15555 queue.backgroundServicesFinishedLocked(userId); 15556 } 15557 } 15558 15559 public void finishReceiver(IBinder who, int resultCode, String resultData, 15560 Bundle resultExtras, boolean resultAbort) { 15561 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15562 15563 // Refuse possible leaked file descriptors 15564 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15565 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15566 } 15567 15568 final long origId = Binder.clearCallingIdentity(); 15569 try { 15570 boolean doNext = false; 15571 BroadcastRecord r; 15572 15573 synchronized(this) { 15574 r = broadcastRecordForReceiverLocked(who); 15575 if (r != null) { 15576 doNext = r.queue.finishReceiverLocked(r, resultCode, 15577 resultData, resultExtras, resultAbort, true); 15578 } 15579 } 15580 15581 if (doNext) { 15582 r.queue.processNextBroadcast(false); 15583 } 15584 trimApplications(); 15585 } finally { 15586 Binder.restoreCallingIdentity(origId); 15587 } 15588 } 15589 15590 // ========================================================= 15591 // INSTRUMENTATION 15592 // ========================================================= 15593 15594 public boolean startInstrumentation(ComponentName className, 15595 String profileFile, int flags, Bundle arguments, 15596 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15597 int userId, String abiOverride) { 15598 enforceNotIsolatedCaller("startInstrumentation"); 15599 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15600 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15601 // Refuse possible leaked file descriptors 15602 if (arguments != null && arguments.hasFileDescriptors()) { 15603 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15604 } 15605 15606 synchronized(this) { 15607 InstrumentationInfo ii = null; 15608 ApplicationInfo ai = null; 15609 try { 15610 ii = mContext.getPackageManager().getInstrumentationInfo( 15611 className, STOCK_PM_FLAGS); 15612 ai = AppGlobals.getPackageManager().getApplicationInfo( 15613 ii.targetPackage, STOCK_PM_FLAGS, userId); 15614 } catch (PackageManager.NameNotFoundException e) { 15615 } catch (RemoteException e) { 15616 } 15617 if (ii == null) { 15618 reportStartInstrumentationFailure(watcher, className, 15619 "Unable to find instrumentation info for: " + className); 15620 return false; 15621 } 15622 if (ai == null) { 15623 reportStartInstrumentationFailure(watcher, className, 15624 "Unable to find instrumentation target package: " + ii.targetPackage); 15625 return false; 15626 } 15627 15628 int match = mContext.getPackageManager().checkSignatures( 15629 ii.targetPackage, ii.packageName); 15630 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15631 String msg = "Permission Denial: starting instrumentation " 15632 + className + " from pid=" 15633 + Binder.getCallingPid() 15634 + ", uid=" + Binder.getCallingPid() 15635 + " not allowed because package " + ii.packageName 15636 + " does not have a signature matching the target " 15637 + ii.targetPackage; 15638 reportStartInstrumentationFailure(watcher, className, msg); 15639 throw new SecurityException(msg); 15640 } 15641 15642 final long origId = Binder.clearCallingIdentity(); 15643 // Instrumentation can kill and relaunch even persistent processes 15644 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15645 "start instr"); 15646 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15647 app.instrumentationClass = className; 15648 app.instrumentationInfo = ai; 15649 app.instrumentationProfileFile = profileFile; 15650 app.instrumentationArguments = arguments; 15651 app.instrumentationWatcher = watcher; 15652 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15653 app.instrumentationResultClass = className; 15654 Binder.restoreCallingIdentity(origId); 15655 } 15656 15657 return true; 15658 } 15659 15660 /** 15661 * Report errors that occur while attempting to start Instrumentation. Always writes the 15662 * error to the logs, but if somebody is watching, send the report there too. This enables 15663 * the "am" command to report errors with more information. 15664 * 15665 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15666 * @param cn The component name of the instrumentation. 15667 * @param report The error report. 15668 */ 15669 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15670 ComponentName cn, String report) { 15671 Slog.w(TAG, report); 15672 try { 15673 if (watcher != null) { 15674 Bundle results = new Bundle(); 15675 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15676 results.putString("Error", report); 15677 watcher.instrumentationStatus(cn, -1, results); 15678 } 15679 } catch (RemoteException e) { 15680 Slog.w(TAG, e); 15681 } 15682 } 15683 15684 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15685 if (app.instrumentationWatcher != null) { 15686 try { 15687 // NOTE: IInstrumentationWatcher *must* be oneway here 15688 app.instrumentationWatcher.instrumentationFinished( 15689 app.instrumentationClass, 15690 resultCode, 15691 results); 15692 } catch (RemoteException e) { 15693 } 15694 } 15695 if (app.instrumentationUiAutomationConnection != null) { 15696 try { 15697 app.instrumentationUiAutomationConnection.shutdown(); 15698 } catch (RemoteException re) { 15699 /* ignore */ 15700 } 15701 // Only a UiAutomation can set this flag and now that 15702 // it is finished we make sure it is reset to its default. 15703 mUserIsMonkey = false; 15704 } 15705 app.instrumentationWatcher = null; 15706 app.instrumentationUiAutomationConnection = null; 15707 app.instrumentationClass = null; 15708 app.instrumentationInfo = null; 15709 app.instrumentationProfileFile = null; 15710 app.instrumentationArguments = null; 15711 15712 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15713 "finished inst"); 15714 } 15715 15716 public void finishInstrumentation(IApplicationThread target, 15717 int resultCode, Bundle results) { 15718 int userId = UserHandle.getCallingUserId(); 15719 // Refuse possible leaked file descriptors 15720 if (results != null && results.hasFileDescriptors()) { 15721 throw new IllegalArgumentException("File descriptors passed in Intent"); 15722 } 15723 15724 synchronized(this) { 15725 ProcessRecord app = getRecordForAppLocked(target); 15726 if (app == null) { 15727 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15728 return; 15729 } 15730 final long origId = Binder.clearCallingIdentity(); 15731 finishInstrumentationLocked(app, resultCode, results); 15732 Binder.restoreCallingIdentity(origId); 15733 } 15734 } 15735 15736 // ========================================================= 15737 // CONFIGURATION 15738 // ========================================================= 15739 15740 public ConfigurationInfo getDeviceConfigurationInfo() { 15741 ConfigurationInfo config = new ConfigurationInfo(); 15742 synchronized (this) { 15743 config.reqTouchScreen = mConfiguration.touchscreen; 15744 config.reqKeyboardType = mConfiguration.keyboard; 15745 config.reqNavigation = mConfiguration.navigation; 15746 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15747 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15748 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15749 } 15750 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15751 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15752 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15753 } 15754 config.reqGlEsVersion = GL_ES_VERSION; 15755 } 15756 return config; 15757 } 15758 15759 ActivityStack getFocusedStack() { 15760 return mStackSupervisor.getFocusedStack(); 15761 } 15762 15763 public Configuration getConfiguration() { 15764 Configuration ci; 15765 synchronized(this) { 15766 ci = new Configuration(mConfiguration); 15767 } 15768 return ci; 15769 } 15770 15771 public void updatePersistentConfiguration(Configuration values) { 15772 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15773 "updateConfiguration()"); 15774 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15775 "updateConfiguration()"); 15776 if (values == null) { 15777 throw new NullPointerException("Configuration must not be null"); 15778 } 15779 15780 synchronized(this) { 15781 final long origId = Binder.clearCallingIdentity(); 15782 updateConfigurationLocked(values, null, true, false); 15783 Binder.restoreCallingIdentity(origId); 15784 } 15785 } 15786 15787 public void updateConfiguration(Configuration values) { 15788 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15789 "updateConfiguration()"); 15790 15791 synchronized(this) { 15792 if (values == null && mWindowManager != null) { 15793 // sentinel: fetch the current configuration from the window manager 15794 values = mWindowManager.computeNewConfiguration(); 15795 } 15796 15797 if (mWindowManager != null) { 15798 mProcessList.applyDisplaySize(mWindowManager); 15799 } 15800 15801 final long origId = Binder.clearCallingIdentity(); 15802 if (values != null) { 15803 Settings.System.clearConfiguration(values); 15804 } 15805 updateConfigurationLocked(values, null, false, false); 15806 Binder.restoreCallingIdentity(origId); 15807 } 15808 } 15809 15810 /** 15811 * Do either or both things: (1) change the current configuration, and (2) 15812 * make sure the given activity is running with the (now) current 15813 * configuration. Returns true if the activity has been left running, or 15814 * false if <var>starting</var> is being destroyed to match the new 15815 * configuration. 15816 * @param persistent TODO 15817 */ 15818 boolean updateConfigurationLocked(Configuration values, 15819 ActivityRecord starting, boolean persistent, boolean initLocale) { 15820 int changes = 0; 15821 15822 if (values != null) { 15823 Configuration newConfig = new Configuration(mConfiguration); 15824 changes = newConfig.updateFrom(values); 15825 if (changes != 0) { 15826 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15827 Slog.i(TAG, "Updating configuration to: " + values); 15828 } 15829 15830 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15831 15832 if (values.locale != null && !initLocale) { 15833 saveLocaleLocked(values.locale, 15834 !values.locale.equals(mConfiguration.locale), 15835 values.userSetLocale); 15836 } 15837 15838 mConfigurationSeq++; 15839 if (mConfigurationSeq <= 0) { 15840 mConfigurationSeq = 1; 15841 } 15842 newConfig.seq = mConfigurationSeq; 15843 mConfiguration = newConfig; 15844 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15845 //mUsageStatsService.noteStartConfig(newConfig); 15846 15847 final Configuration configCopy = new Configuration(mConfiguration); 15848 15849 // TODO: If our config changes, should we auto dismiss any currently 15850 // showing dialogs? 15851 mShowDialogs = shouldShowDialogs(newConfig); 15852 15853 AttributeCache ac = AttributeCache.instance(); 15854 if (ac != null) { 15855 ac.updateConfiguration(configCopy); 15856 } 15857 15858 // Make sure all resources in our process are updated 15859 // right now, so that anyone who is going to retrieve 15860 // resource values after we return will be sure to get 15861 // the new ones. This is especially important during 15862 // boot, where the first config change needs to guarantee 15863 // all resources have that config before following boot 15864 // code is executed. 15865 mSystemThread.applyConfigurationToResources(configCopy); 15866 15867 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15868 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15869 msg.obj = new Configuration(configCopy); 15870 mHandler.sendMessage(msg); 15871 } 15872 15873 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15874 ProcessRecord app = mLruProcesses.get(i); 15875 try { 15876 if (app.thread != null) { 15877 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15878 + app.processName + " new config " + mConfiguration); 15879 app.thread.scheduleConfigurationChanged(configCopy); 15880 } 15881 } catch (Exception e) { 15882 } 15883 } 15884 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15885 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15886 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15887 | Intent.FLAG_RECEIVER_FOREGROUND); 15888 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15889 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15890 Process.SYSTEM_UID, UserHandle.USER_ALL); 15891 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15892 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15893 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15894 broadcastIntentLocked(null, null, intent, 15895 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15896 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15897 } 15898 } 15899 } 15900 15901 boolean kept = true; 15902 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15903 // mainStack is null during startup. 15904 if (mainStack != null) { 15905 if (changes != 0 && starting == null) { 15906 // If the configuration changed, and the caller is not already 15907 // in the process of starting an activity, then find the top 15908 // activity to check if its configuration needs to change. 15909 starting = mainStack.topRunningActivityLocked(null); 15910 } 15911 15912 if (starting != null) { 15913 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15914 // And we need to make sure at this point that all other activities 15915 // are made visible with the correct configuration. 15916 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15917 } 15918 } 15919 15920 if (values != null && mWindowManager != null) { 15921 mWindowManager.setNewConfiguration(mConfiguration); 15922 } 15923 15924 return kept; 15925 } 15926 15927 /** 15928 * Decide based on the configuration whether we should shouw the ANR, 15929 * crash, etc dialogs. The idea is that if there is no affordnace to 15930 * press the on-screen buttons, we shouldn't show the dialog. 15931 * 15932 * A thought: SystemUI might also want to get told about this, the Power 15933 * dialog / global actions also might want different behaviors. 15934 */ 15935 private static final boolean shouldShowDialogs(Configuration config) { 15936 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15937 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15938 } 15939 15940 /** 15941 * Save the locale. You must be inside a synchronized (this) block. 15942 */ 15943 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15944 if(isDiff) { 15945 SystemProperties.set("user.language", l.getLanguage()); 15946 SystemProperties.set("user.region", l.getCountry()); 15947 } 15948 15949 if(isPersist) { 15950 SystemProperties.set("persist.sys.language", l.getLanguage()); 15951 SystemProperties.set("persist.sys.country", l.getCountry()); 15952 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15953 } 15954 } 15955 15956 @Override 15957 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 15958 synchronized (this) { 15959 ActivityRecord srec = ActivityRecord.forToken(token); 15960 if (srec.task != null && srec.task.stack != null) { 15961 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 15962 } 15963 } 15964 return false; 15965 } 15966 15967 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15968 Intent resultData) { 15969 15970 synchronized (this) { 15971 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15972 if (stack != null) { 15973 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15974 } 15975 return false; 15976 } 15977 } 15978 15979 public int getLaunchedFromUid(IBinder activityToken) { 15980 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15981 if (srec == null) { 15982 return -1; 15983 } 15984 return srec.launchedFromUid; 15985 } 15986 15987 public String getLaunchedFromPackage(IBinder activityToken) { 15988 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15989 if (srec == null) { 15990 return null; 15991 } 15992 return srec.launchedFromPackage; 15993 } 15994 15995 // ========================================================= 15996 // LIFETIME MANAGEMENT 15997 // ========================================================= 15998 15999 // Returns which broadcast queue the app is the current [or imminent] receiver 16000 // on, or 'null' if the app is not an active broadcast recipient. 16001 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16002 BroadcastRecord r = app.curReceiver; 16003 if (r != null) { 16004 return r.queue; 16005 } 16006 16007 // It's not the current receiver, but it might be starting up to become one 16008 synchronized (this) { 16009 for (BroadcastQueue queue : mBroadcastQueues) { 16010 r = queue.mPendingBroadcast; 16011 if (r != null && r.curApp == app) { 16012 // found it; report which queue it's in 16013 return queue; 16014 } 16015 } 16016 } 16017 16018 return null; 16019 } 16020 16021 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16022 boolean doingAll, long now) { 16023 if (mAdjSeq == app.adjSeq) { 16024 // This adjustment has already been computed. 16025 return app.curRawAdj; 16026 } 16027 16028 if (app.thread == null) { 16029 app.adjSeq = mAdjSeq; 16030 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16031 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16032 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16033 } 16034 16035 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16036 app.adjSource = null; 16037 app.adjTarget = null; 16038 app.empty = false; 16039 app.cached = false; 16040 16041 final int activitiesSize = app.activities.size(); 16042 16043 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16044 // The max adjustment doesn't allow this app to be anything 16045 // below foreground, so it is not worth doing work for it. 16046 app.adjType = "fixed"; 16047 app.adjSeq = mAdjSeq; 16048 app.curRawAdj = app.maxAdj; 16049 app.foregroundActivities = false; 16050 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16051 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16052 // System processes can do UI, and when they do we want to have 16053 // them trim their memory after the user leaves the UI. To 16054 // facilitate this, here we need to determine whether or not it 16055 // is currently showing UI. 16056 app.systemNoUi = true; 16057 if (app == TOP_APP) { 16058 app.systemNoUi = false; 16059 } else if (activitiesSize > 0) { 16060 for (int j = 0; j < activitiesSize; j++) { 16061 final ActivityRecord r = app.activities.get(j); 16062 if (r.visible) { 16063 app.systemNoUi = false; 16064 } 16065 } 16066 } 16067 if (!app.systemNoUi) { 16068 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16069 } 16070 return (app.curAdj=app.maxAdj); 16071 } 16072 16073 app.systemNoUi = false; 16074 16075 // Determine the importance of the process, starting with most 16076 // important to least, and assign an appropriate OOM adjustment. 16077 int adj; 16078 int schedGroup; 16079 int procState; 16080 boolean foregroundActivities = false; 16081 BroadcastQueue queue; 16082 if (app == TOP_APP) { 16083 // The last app on the list is the foreground app. 16084 adj = ProcessList.FOREGROUND_APP_ADJ; 16085 schedGroup = Process.THREAD_GROUP_DEFAULT; 16086 app.adjType = "top-activity"; 16087 foregroundActivities = true; 16088 procState = ActivityManager.PROCESS_STATE_TOP; 16089 } else if (app.instrumentationClass != null) { 16090 // Don't want to kill running instrumentation. 16091 adj = ProcessList.FOREGROUND_APP_ADJ; 16092 schedGroup = Process.THREAD_GROUP_DEFAULT; 16093 app.adjType = "instrumentation"; 16094 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16095 } else if ((queue = isReceivingBroadcast(app)) != null) { 16096 // An app that is currently receiving a broadcast also 16097 // counts as being in the foreground for OOM killer purposes. 16098 // It's placed in a sched group based on the nature of the 16099 // broadcast as reflected by which queue it's active in. 16100 adj = ProcessList.FOREGROUND_APP_ADJ; 16101 schedGroup = (queue == mFgBroadcastQueue) 16102 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16103 app.adjType = "broadcast"; 16104 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16105 } else if (app.executingServices.size() > 0) { 16106 // An app that is currently executing a service callback also 16107 // counts as being in the foreground. 16108 adj = ProcessList.FOREGROUND_APP_ADJ; 16109 schedGroup = app.execServicesFg ? 16110 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16111 app.adjType = "exec-service"; 16112 procState = ActivityManager.PROCESS_STATE_SERVICE; 16113 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16114 } else { 16115 // As far as we know the process is empty. We may change our mind later. 16116 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16117 // At this point we don't actually know the adjustment. Use the cached adj 16118 // value that the caller wants us to. 16119 adj = cachedAdj; 16120 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16121 app.cached = true; 16122 app.empty = true; 16123 app.adjType = "cch-empty"; 16124 } 16125 16126 // Examine all activities if not already foreground. 16127 if (!foregroundActivities && activitiesSize > 0) { 16128 for (int j = 0; j < activitiesSize; j++) { 16129 final ActivityRecord r = app.activities.get(j); 16130 if (r.app != app) { 16131 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16132 + app + "?!?"); 16133 continue; 16134 } 16135 if (r.visible) { 16136 // App has a visible activity; only upgrade adjustment. 16137 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16138 adj = ProcessList.VISIBLE_APP_ADJ; 16139 app.adjType = "visible"; 16140 } 16141 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16142 procState = ActivityManager.PROCESS_STATE_TOP; 16143 } 16144 schedGroup = Process.THREAD_GROUP_DEFAULT; 16145 app.cached = false; 16146 app.empty = false; 16147 foregroundActivities = true; 16148 break; 16149 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16150 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16151 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16152 app.adjType = "pausing"; 16153 } 16154 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16155 procState = ActivityManager.PROCESS_STATE_TOP; 16156 } 16157 schedGroup = Process.THREAD_GROUP_DEFAULT; 16158 app.cached = false; 16159 app.empty = false; 16160 foregroundActivities = true; 16161 } else if (r.state == ActivityState.STOPPING) { 16162 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16163 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16164 app.adjType = "stopping"; 16165 } 16166 // For the process state, we will at this point consider the 16167 // process to be cached. It will be cached either as an activity 16168 // or empty depending on whether the activity is finishing. We do 16169 // this so that we can treat the process as cached for purposes of 16170 // memory trimming (determing current memory level, trim command to 16171 // send to process) since there can be an arbitrary number of stopping 16172 // processes and they should soon all go into the cached state. 16173 if (!r.finishing) { 16174 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16175 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16176 } 16177 } 16178 app.cached = false; 16179 app.empty = false; 16180 foregroundActivities = true; 16181 } else { 16182 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16183 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16184 app.adjType = "cch-act"; 16185 } 16186 } 16187 } 16188 } 16189 16190 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16191 if (app.foregroundServices) { 16192 // The user is aware of this app, so make it visible. 16193 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16194 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16195 app.cached = false; 16196 app.adjType = "fg-service"; 16197 schedGroup = Process.THREAD_GROUP_DEFAULT; 16198 } else if (app.forcingToForeground != null) { 16199 // The user is aware of this app, so make it visible. 16200 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16201 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16202 app.cached = false; 16203 app.adjType = "force-fg"; 16204 app.adjSource = app.forcingToForeground; 16205 schedGroup = Process.THREAD_GROUP_DEFAULT; 16206 } 16207 } 16208 16209 if (app == mHeavyWeightProcess) { 16210 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16211 // We don't want to kill the current heavy-weight process. 16212 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16213 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16214 app.cached = false; 16215 app.adjType = "heavy"; 16216 } 16217 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16218 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16219 } 16220 } 16221 16222 if (app == mHomeProcess) { 16223 if (adj > ProcessList.HOME_APP_ADJ) { 16224 // This process is hosting what we currently consider to be the 16225 // home app, so we don't want to let it go into the background. 16226 adj = ProcessList.HOME_APP_ADJ; 16227 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16228 app.cached = false; 16229 app.adjType = "home"; 16230 } 16231 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16232 procState = ActivityManager.PROCESS_STATE_HOME; 16233 } 16234 } 16235 16236 if (app == mPreviousProcess && app.activities.size() > 0) { 16237 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16238 // This was the previous process that showed UI to the user. 16239 // We want to try to keep it around more aggressively, to give 16240 // a good experience around switching between two apps. 16241 adj = ProcessList.PREVIOUS_APP_ADJ; 16242 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16243 app.cached = false; 16244 app.adjType = "previous"; 16245 } 16246 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16247 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16248 } 16249 } 16250 16251 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16252 + " reason=" + app.adjType); 16253 16254 // By default, we use the computed adjustment. It may be changed if 16255 // there are applications dependent on our services or providers, but 16256 // this gives us a baseline and makes sure we don't get into an 16257 // infinite recursion. 16258 app.adjSeq = mAdjSeq; 16259 app.curRawAdj = adj; 16260 app.hasStartedServices = false; 16261 16262 if (mBackupTarget != null && app == mBackupTarget.app) { 16263 // If possible we want to avoid killing apps while they're being backed up 16264 if (adj > ProcessList.BACKUP_APP_ADJ) { 16265 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16266 adj = ProcessList.BACKUP_APP_ADJ; 16267 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16268 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16269 } 16270 app.adjType = "backup"; 16271 app.cached = false; 16272 } 16273 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16274 procState = ActivityManager.PROCESS_STATE_BACKUP; 16275 } 16276 } 16277 16278 boolean mayBeTop = false; 16279 16280 for (int is = app.services.size()-1; 16281 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16282 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16283 || procState > ActivityManager.PROCESS_STATE_TOP); 16284 is--) { 16285 ServiceRecord s = app.services.valueAt(is); 16286 if (s.startRequested) { 16287 app.hasStartedServices = true; 16288 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16289 procState = ActivityManager.PROCESS_STATE_SERVICE; 16290 } 16291 if (app.hasShownUi && app != mHomeProcess) { 16292 // If this process has shown some UI, let it immediately 16293 // go to the LRU list because it may be pretty heavy with 16294 // UI stuff. We'll tag it with a label just to help 16295 // debug and understand what is going on. 16296 if (adj > ProcessList.SERVICE_ADJ) { 16297 app.adjType = "cch-started-ui-services"; 16298 } 16299 } else { 16300 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16301 // This service has seen some activity within 16302 // recent memory, so we will keep its process ahead 16303 // of the background processes. 16304 if (adj > ProcessList.SERVICE_ADJ) { 16305 adj = ProcessList.SERVICE_ADJ; 16306 app.adjType = "started-services"; 16307 app.cached = false; 16308 } 16309 } 16310 // If we have let the service slide into the background 16311 // state, still have some text describing what it is doing 16312 // even though the service no longer has an impact. 16313 if (adj > ProcessList.SERVICE_ADJ) { 16314 app.adjType = "cch-started-services"; 16315 } 16316 } 16317 } 16318 for (int conni = s.connections.size()-1; 16319 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16320 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16321 || procState > ActivityManager.PROCESS_STATE_TOP); 16322 conni--) { 16323 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16324 for (int i = 0; 16325 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16326 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16327 || procState > ActivityManager.PROCESS_STATE_TOP); 16328 i++) { 16329 // XXX should compute this based on the max of 16330 // all connected clients. 16331 ConnectionRecord cr = clist.get(i); 16332 if (cr.binding.client == app) { 16333 // Binding to ourself is not interesting. 16334 continue; 16335 } 16336 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16337 ProcessRecord client = cr.binding.client; 16338 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16339 TOP_APP, doingAll, now); 16340 int clientProcState = client.curProcState; 16341 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16342 // If the other app is cached for any reason, for purposes here 16343 // we are going to consider it empty. The specific cached state 16344 // doesn't propagate except under certain conditions. 16345 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16346 } 16347 String adjType = null; 16348 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16349 // Not doing bind OOM management, so treat 16350 // this guy more like a started service. 16351 if (app.hasShownUi && app != mHomeProcess) { 16352 // If this process has shown some UI, let it immediately 16353 // go to the LRU list because it may be pretty heavy with 16354 // UI stuff. We'll tag it with a label just to help 16355 // debug and understand what is going on. 16356 if (adj > clientAdj) { 16357 adjType = "cch-bound-ui-services"; 16358 } 16359 app.cached = false; 16360 clientAdj = adj; 16361 clientProcState = procState; 16362 } else { 16363 if (now >= (s.lastActivity 16364 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16365 // This service has not seen activity within 16366 // recent memory, so allow it to drop to the 16367 // LRU list if there is no other reason to keep 16368 // it around. We'll also tag it with a label just 16369 // to help debug and undertand what is going on. 16370 if (adj > clientAdj) { 16371 adjType = "cch-bound-services"; 16372 } 16373 clientAdj = adj; 16374 } 16375 } 16376 } 16377 if (adj > clientAdj) { 16378 // If this process has recently shown UI, and 16379 // the process that is binding to it is less 16380 // important than being visible, then we don't 16381 // care about the binding as much as we care 16382 // about letting this process get into the LRU 16383 // list to be killed and restarted if needed for 16384 // memory. 16385 if (app.hasShownUi && app != mHomeProcess 16386 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16387 adjType = "cch-bound-ui-services"; 16388 } else { 16389 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16390 |Context.BIND_IMPORTANT)) != 0) { 16391 adj = clientAdj; 16392 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16393 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16394 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16395 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16396 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16397 adj = clientAdj; 16398 } else { 16399 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16400 adj = ProcessList.VISIBLE_APP_ADJ; 16401 } 16402 } 16403 if (!client.cached) { 16404 app.cached = false; 16405 } 16406 adjType = "service"; 16407 } 16408 } 16409 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16410 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16411 schedGroup = Process.THREAD_GROUP_DEFAULT; 16412 } 16413 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16414 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16415 // Special handling of clients who are in the top state. 16416 // We *may* want to consider this process to be in the 16417 // top state as well, but only if there is not another 16418 // reason for it to be running. Being on the top is a 16419 // special state, meaning you are specifically running 16420 // for the current top app. If the process is already 16421 // running in the background for some other reason, it 16422 // is more important to continue considering it to be 16423 // in the background state. 16424 mayBeTop = true; 16425 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16426 } else { 16427 // Special handling for above-top states (persistent 16428 // processes). These should not bring the current process 16429 // into the top state, since they are not on top. Instead 16430 // give them the best state after that. 16431 clientProcState = 16432 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16433 } 16434 } 16435 } else { 16436 if (clientProcState < 16437 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16438 clientProcState = 16439 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16440 } 16441 } 16442 if (procState > clientProcState) { 16443 procState = clientProcState; 16444 } 16445 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16446 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16447 app.pendingUiClean = true; 16448 } 16449 if (adjType != null) { 16450 app.adjType = adjType; 16451 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16452 .REASON_SERVICE_IN_USE; 16453 app.adjSource = cr.binding.client; 16454 app.adjSourceProcState = clientProcState; 16455 app.adjTarget = s.name; 16456 } 16457 } 16458 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16459 app.treatLikeActivity = true; 16460 } 16461 final ActivityRecord a = cr.activity; 16462 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16463 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16464 (a.visible || a.state == ActivityState.RESUMED 16465 || a.state == ActivityState.PAUSING)) { 16466 adj = ProcessList.FOREGROUND_APP_ADJ; 16467 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16468 schedGroup = Process.THREAD_GROUP_DEFAULT; 16469 } 16470 app.cached = false; 16471 app.adjType = "service"; 16472 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16473 .REASON_SERVICE_IN_USE; 16474 app.adjSource = a; 16475 app.adjSourceProcState = procState; 16476 app.adjTarget = s.name; 16477 } 16478 } 16479 } 16480 } 16481 } 16482 16483 for (int provi = app.pubProviders.size()-1; 16484 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16485 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16486 || procState > ActivityManager.PROCESS_STATE_TOP); 16487 provi--) { 16488 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16489 for (int i = cpr.connections.size()-1; 16490 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16491 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16492 || procState > ActivityManager.PROCESS_STATE_TOP); 16493 i--) { 16494 ContentProviderConnection conn = cpr.connections.get(i); 16495 ProcessRecord client = conn.client; 16496 if (client == app) { 16497 // Being our own client is not interesting. 16498 continue; 16499 } 16500 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16501 int clientProcState = client.curProcState; 16502 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16503 // If the other app is cached for any reason, for purposes here 16504 // we are going to consider it empty. 16505 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16506 } 16507 if (adj > clientAdj) { 16508 if (app.hasShownUi && app != mHomeProcess 16509 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16510 app.adjType = "cch-ui-provider"; 16511 } else { 16512 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16513 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16514 app.adjType = "provider"; 16515 } 16516 app.cached &= client.cached; 16517 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16518 .REASON_PROVIDER_IN_USE; 16519 app.adjSource = client; 16520 app.adjSourceProcState = clientProcState; 16521 app.adjTarget = cpr.name; 16522 } 16523 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16524 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16525 // Special handling of clients who are in the top state. 16526 // We *may* want to consider this process to be in the 16527 // top state as well, but only if there is not another 16528 // reason for it to be running. Being on the top is a 16529 // special state, meaning you are specifically running 16530 // for the current top app. If the process is already 16531 // running in the background for some other reason, it 16532 // is more important to continue considering it to be 16533 // in the background state. 16534 mayBeTop = true; 16535 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16536 } else { 16537 // Special handling for above-top states (persistent 16538 // processes). These should not bring the current process 16539 // into the top state, since they are not on top. Instead 16540 // give them the best state after that. 16541 clientProcState = 16542 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16543 } 16544 } 16545 if (procState > clientProcState) { 16546 procState = clientProcState; 16547 } 16548 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16549 schedGroup = Process.THREAD_GROUP_DEFAULT; 16550 } 16551 } 16552 // If the provider has external (non-framework) process 16553 // dependencies, ensure that its adjustment is at least 16554 // FOREGROUND_APP_ADJ. 16555 if (cpr.hasExternalProcessHandles()) { 16556 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16557 adj = ProcessList.FOREGROUND_APP_ADJ; 16558 schedGroup = Process.THREAD_GROUP_DEFAULT; 16559 app.cached = false; 16560 app.adjType = "provider"; 16561 app.adjTarget = cpr.name; 16562 } 16563 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16564 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16565 } 16566 } 16567 } 16568 16569 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16570 // A client of one of our services or providers is in the top state. We 16571 // *may* want to be in the top state, but not if we are already running in 16572 // the background for some other reason. For the decision here, we are going 16573 // to pick out a few specific states that we want to remain in when a client 16574 // is top (states that tend to be longer-term) and otherwise allow it to go 16575 // to the top state. 16576 switch (procState) { 16577 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16578 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16579 case ActivityManager.PROCESS_STATE_SERVICE: 16580 // These all are longer-term states, so pull them up to the top 16581 // of the background states, but not all the way to the top state. 16582 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16583 break; 16584 default: 16585 // Otherwise, top is a better choice, so take it. 16586 procState = ActivityManager.PROCESS_STATE_TOP; 16587 break; 16588 } 16589 } 16590 16591 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16592 if (app.hasClientActivities) { 16593 // This is a cached process, but with client activities. Mark it so. 16594 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16595 app.adjType = "cch-client-act"; 16596 } else if (app.treatLikeActivity) { 16597 // This is a cached process, but somebody wants us to treat it like it has 16598 // an activity, okay! 16599 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16600 app.adjType = "cch-as-act"; 16601 } 16602 } 16603 16604 if (adj == ProcessList.SERVICE_ADJ) { 16605 if (doingAll) { 16606 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16607 mNewNumServiceProcs++; 16608 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16609 if (!app.serviceb) { 16610 // This service isn't far enough down on the LRU list to 16611 // normally be a B service, but if we are low on RAM and it 16612 // is large we want to force it down since we would prefer to 16613 // keep launcher over it. 16614 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16615 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16616 app.serviceHighRam = true; 16617 app.serviceb = true; 16618 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16619 } else { 16620 mNewNumAServiceProcs++; 16621 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16622 } 16623 } else { 16624 app.serviceHighRam = false; 16625 } 16626 } 16627 if (app.serviceb) { 16628 adj = ProcessList.SERVICE_B_ADJ; 16629 } 16630 } 16631 16632 app.curRawAdj = adj; 16633 16634 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16635 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16636 if (adj > app.maxAdj) { 16637 adj = app.maxAdj; 16638 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16639 schedGroup = Process.THREAD_GROUP_DEFAULT; 16640 } 16641 } 16642 16643 // Do final modification to adj. Everything we do between here and applying 16644 // the final setAdj must be done in this function, because we will also use 16645 // it when computing the final cached adj later. Note that we don't need to 16646 // worry about this for max adj above, since max adj will always be used to 16647 // keep it out of the cached vaues. 16648 app.curAdj = app.modifyRawOomAdj(adj); 16649 app.curSchedGroup = schedGroup; 16650 app.curProcState = procState; 16651 app.foregroundActivities = foregroundActivities; 16652 16653 return app.curRawAdj; 16654 } 16655 16656 /** 16657 * Schedule PSS collection of a process. 16658 */ 16659 void requestPssLocked(ProcessRecord proc, int procState) { 16660 if (mPendingPssProcesses.contains(proc)) { 16661 return; 16662 } 16663 if (mPendingPssProcesses.size() == 0) { 16664 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16665 } 16666 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16667 proc.pssProcState = procState; 16668 mPendingPssProcesses.add(proc); 16669 } 16670 16671 /** 16672 * Schedule PSS collection of all processes. 16673 */ 16674 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16675 if (!always) { 16676 if (now < (mLastFullPssTime + 16677 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16678 return; 16679 } 16680 } 16681 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16682 mLastFullPssTime = now; 16683 mFullPssPending = true; 16684 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16685 mPendingPssProcesses.clear(); 16686 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16687 ProcessRecord app = mLruProcesses.get(i); 16688 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16689 app.pssProcState = app.setProcState; 16690 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16691 isSleeping(), now); 16692 mPendingPssProcesses.add(app); 16693 } 16694 } 16695 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16696 } 16697 16698 /** 16699 * Ask a given process to GC right now. 16700 */ 16701 final void performAppGcLocked(ProcessRecord app) { 16702 try { 16703 app.lastRequestedGc = SystemClock.uptimeMillis(); 16704 if (app.thread != null) { 16705 if (app.reportLowMemory) { 16706 app.reportLowMemory = false; 16707 app.thread.scheduleLowMemory(); 16708 } else { 16709 app.thread.processInBackground(); 16710 } 16711 } 16712 } catch (Exception e) { 16713 // whatever. 16714 } 16715 } 16716 16717 /** 16718 * Returns true if things are idle enough to perform GCs. 16719 */ 16720 private final boolean canGcNowLocked() { 16721 boolean processingBroadcasts = false; 16722 for (BroadcastQueue q : mBroadcastQueues) { 16723 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16724 processingBroadcasts = true; 16725 } 16726 } 16727 return !processingBroadcasts 16728 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16729 } 16730 16731 /** 16732 * Perform GCs on all processes that are waiting for it, but only 16733 * if things are idle. 16734 */ 16735 final void performAppGcsLocked() { 16736 final int N = mProcessesToGc.size(); 16737 if (N <= 0) { 16738 return; 16739 } 16740 if (canGcNowLocked()) { 16741 while (mProcessesToGc.size() > 0) { 16742 ProcessRecord proc = mProcessesToGc.remove(0); 16743 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16744 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16745 <= SystemClock.uptimeMillis()) { 16746 // To avoid spamming the system, we will GC processes one 16747 // at a time, waiting a few seconds between each. 16748 performAppGcLocked(proc); 16749 scheduleAppGcsLocked(); 16750 return; 16751 } else { 16752 // It hasn't been long enough since we last GCed this 16753 // process... put it in the list to wait for its time. 16754 addProcessToGcListLocked(proc); 16755 break; 16756 } 16757 } 16758 } 16759 16760 scheduleAppGcsLocked(); 16761 } 16762 } 16763 16764 /** 16765 * If all looks good, perform GCs on all processes waiting for them. 16766 */ 16767 final void performAppGcsIfAppropriateLocked() { 16768 if (canGcNowLocked()) { 16769 performAppGcsLocked(); 16770 return; 16771 } 16772 // Still not idle, wait some more. 16773 scheduleAppGcsLocked(); 16774 } 16775 16776 /** 16777 * Schedule the execution of all pending app GCs. 16778 */ 16779 final void scheduleAppGcsLocked() { 16780 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16781 16782 if (mProcessesToGc.size() > 0) { 16783 // Schedule a GC for the time to the next process. 16784 ProcessRecord proc = mProcessesToGc.get(0); 16785 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16786 16787 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16788 long now = SystemClock.uptimeMillis(); 16789 if (when < (now+GC_TIMEOUT)) { 16790 when = now + GC_TIMEOUT; 16791 } 16792 mHandler.sendMessageAtTime(msg, when); 16793 } 16794 } 16795 16796 /** 16797 * Add a process to the array of processes waiting to be GCed. Keeps the 16798 * list in sorted order by the last GC time. The process can't already be 16799 * on the list. 16800 */ 16801 final void addProcessToGcListLocked(ProcessRecord proc) { 16802 boolean added = false; 16803 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16804 if (mProcessesToGc.get(i).lastRequestedGc < 16805 proc.lastRequestedGc) { 16806 added = true; 16807 mProcessesToGc.add(i+1, proc); 16808 break; 16809 } 16810 } 16811 if (!added) { 16812 mProcessesToGc.add(0, proc); 16813 } 16814 } 16815 16816 /** 16817 * Set up to ask a process to GC itself. This will either do it 16818 * immediately, or put it on the list of processes to gc the next 16819 * time things are idle. 16820 */ 16821 final void scheduleAppGcLocked(ProcessRecord app) { 16822 long now = SystemClock.uptimeMillis(); 16823 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16824 return; 16825 } 16826 if (!mProcessesToGc.contains(app)) { 16827 addProcessToGcListLocked(app); 16828 scheduleAppGcsLocked(); 16829 } 16830 } 16831 16832 final void checkExcessivePowerUsageLocked(boolean doKills) { 16833 updateCpuStatsNow(); 16834 16835 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16836 boolean doWakeKills = doKills; 16837 boolean doCpuKills = doKills; 16838 if (mLastPowerCheckRealtime == 0) { 16839 doWakeKills = false; 16840 } 16841 if (mLastPowerCheckUptime == 0) { 16842 doCpuKills = false; 16843 } 16844 if (stats.isScreenOn()) { 16845 doWakeKills = false; 16846 } 16847 final long curRealtime = SystemClock.elapsedRealtime(); 16848 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16849 final long curUptime = SystemClock.uptimeMillis(); 16850 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16851 mLastPowerCheckRealtime = curRealtime; 16852 mLastPowerCheckUptime = curUptime; 16853 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16854 doWakeKills = false; 16855 } 16856 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16857 doCpuKills = false; 16858 } 16859 int i = mLruProcesses.size(); 16860 while (i > 0) { 16861 i--; 16862 ProcessRecord app = mLruProcesses.get(i); 16863 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16864 long wtime; 16865 synchronized (stats) { 16866 wtime = stats.getProcessWakeTime(app.info.uid, 16867 app.pid, curRealtime); 16868 } 16869 long wtimeUsed = wtime - app.lastWakeTime; 16870 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16871 if (DEBUG_POWER) { 16872 StringBuilder sb = new StringBuilder(128); 16873 sb.append("Wake for "); 16874 app.toShortString(sb); 16875 sb.append(": over "); 16876 TimeUtils.formatDuration(realtimeSince, sb); 16877 sb.append(" used "); 16878 TimeUtils.formatDuration(wtimeUsed, sb); 16879 sb.append(" ("); 16880 sb.append((wtimeUsed*100)/realtimeSince); 16881 sb.append("%)"); 16882 Slog.i(TAG, sb.toString()); 16883 sb.setLength(0); 16884 sb.append("CPU for "); 16885 app.toShortString(sb); 16886 sb.append(": over "); 16887 TimeUtils.formatDuration(uptimeSince, sb); 16888 sb.append(" used "); 16889 TimeUtils.formatDuration(cputimeUsed, sb); 16890 sb.append(" ("); 16891 sb.append((cputimeUsed*100)/uptimeSince); 16892 sb.append("%)"); 16893 Slog.i(TAG, sb.toString()); 16894 } 16895 // If a process has held a wake lock for more 16896 // than 50% of the time during this period, 16897 // that sounds bad. Kill! 16898 if (doWakeKills && realtimeSince > 0 16899 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16900 synchronized (stats) { 16901 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16902 realtimeSince, wtimeUsed); 16903 } 16904 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16905 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16906 } else if (doCpuKills && uptimeSince > 0 16907 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16908 synchronized (stats) { 16909 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16910 uptimeSince, cputimeUsed); 16911 } 16912 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16913 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16914 } else { 16915 app.lastWakeTime = wtime; 16916 app.lastCpuTime = app.curCpuTime; 16917 } 16918 } 16919 } 16920 } 16921 16922 private final boolean applyOomAdjLocked(ProcessRecord app, 16923 ProcessRecord TOP_APP, boolean doingAll, long now) { 16924 boolean success = true; 16925 16926 if (app.curRawAdj != app.setRawAdj) { 16927 app.setRawAdj = app.curRawAdj; 16928 } 16929 16930 int changes = 0; 16931 16932 if (app.curAdj != app.setAdj) { 16933 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16934 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16935 TAG, "Set " + app.pid + " " + app.processName + 16936 " adj " + app.curAdj + ": " + app.adjType); 16937 app.setAdj = app.curAdj; 16938 } 16939 16940 if (app.setSchedGroup != app.curSchedGroup) { 16941 app.setSchedGroup = app.curSchedGroup; 16942 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16943 "Setting process group of " + app.processName 16944 + " to " + app.curSchedGroup); 16945 if (app.waitingToKill != null && 16946 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16947 app.kill(app.waitingToKill, true); 16948 success = false; 16949 } else { 16950 if (true) { 16951 long oldId = Binder.clearCallingIdentity(); 16952 try { 16953 Process.setProcessGroup(app.pid, app.curSchedGroup); 16954 } catch (Exception e) { 16955 Slog.w(TAG, "Failed setting process group of " + app.pid 16956 + " to " + app.curSchedGroup); 16957 e.printStackTrace(); 16958 } finally { 16959 Binder.restoreCallingIdentity(oldId); 16960 } 16961 } else { 16962 if (app.thread != null) { 16963 try { 16964 app.thread.setSchedulingGroup(app.curSchedGroup); 16965 } catch (RemoteException e) { 16966 } 16967 } 16968 } 16969 Process.setSwappiness(app.pid, 16970 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16971 } 16972 } 16973 if (app.repForegroundActivities != app.foregroundActivities) { 16974 app.repForegroundActivities = app.foregroundActivities; 16975 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16976 } 16977 if (app.repProcState != app.curProcState) { 16978 app.repProcState = app.curProcState; 16979 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16980 if (app.thread != null) { 16981 try { 16982 if (false) { 16983 //RuntimeException h = new RuntimeException("here"); 16984 Slog.i(TAG, "Sending new process state " + app.repProcState 16985 + " to " + app /*, h*/); 16986 } 16987 app.thread.setProcessState(app.repProcState); 16988 } catch (RemoteException e) { 16989 } 16990 } 16991 } 16992 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16993 app.setProcState)) { 16994 app.lastStateTime = now; 16995 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16996 isSleeping(), now); 16997 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16998 + ProcessList.makeProcStateString(app.setProcState) + " to " 16999 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17000 + (app.nextPssTime-now) + ": " + app); 17001 } else { 17002 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17003 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17004 requestPssLocked(app, app.setProcState); 17005 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17006 isSleeping(), now); 17007 } else if (false && DEBUG_PSS) { 17008 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17009 } 17010 } 17011 if (app.setProcState != app.curProcState) { 17012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17013 "Proc state change of " + app.processName 17014 + " to " + app.curProcState); 17015 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17016 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17017 if (setImportant && !curImportant) { 17018 // This app is no longer something we consider important enough to allow to 17019 // use arbitrary amounts of battery power. Note 17020 // its current wake lock time to later know to kill it if 17021 // it is not behaving well. 17022 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17023 synchronized (stats) { 17024 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17025 app.pid, SystemClock.elapsedRealtime()); 17026 } 17027 app.lastCpuTime = app.curCpuTime; 17028 17029 } 17030 app.setProcState = app.curProcState; 17031 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17032 app.notCachedSinceIdle = false; 17033 } 17034 if (!doingAll) { 17035 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17036 } else { 17037 app.procStateChanged = true; 17038 } 17039 } 17040 17041 if (changes != 0) { 17042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17043 int i = mPendingProcessChanges.size()-1; 17044 ProcessChangeItem item = null; 17045 while (i >= 0) { 17046 item = mPendingProcessChanges.get(i); 17047 if (item.pid == app.pid) { 17048 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17049 break; 17050 } 17051 i--; 17052 } 17053 if (i < 0) { 17054 // No existing item in pending changes; need a new one. 17055 final int NA = mAvailProcessChanges.size(); 17056 if (NA > 0) { 17057 item = mAvailProcessChanges.remove(NA-1); 17058 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17059 } else { 17060 item = new ProcessChangeItem(); 17061 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17062 } 17063 item.changes = 0; 17064 item.pid = app.pid; 17065 item.uid = app.info.uid; 17066 if (mPendingProcessChanges.size() == 0) { 17067 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17068 "*** Enqueueing dispatch processes changed!"); 17069 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17070 } 17071 mPendingProcessChanges.add(item); 17072 } 17073 item.changes |= changes; 17074 item.processState = app.repProcState; 17075 item.foregroundActivities = app.repForegroundActivities; 17076 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17077 + Integer.toHexString(System.identityHashCode(item)) 17078 + " " + app.toShortString() + ": changes=" + item.changes 17079 + " procState=" + item.processState 17080 + " foreground=" + item.foregroundActivities 17081 + " type=" + app.adjType + " source=" + app.adjSource 17082 + " target=" + app.adjTarget); 17083 } 17084 17085 return success; 17086 } 17087 17088 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17089 if (proc.thread != null) { 17090 if (proc.baseProcessTracker != null) { 17091 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17092 } 17093 if (proc.repProcState >= 0) { 17094 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17095 proc.repProcState); 17096 } 17097 } 17098 } 17099 17100 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17101 ProcessRecord TOP_APP, boolean doingAll, long now) { 17102 if (app.thread == null) { 17103 return false; 17104 } 17105 17106 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17107 17108 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17109 } 17110 17111 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17112 boolean oomAdj) { 17113 if (isForeground != proc.foregroundServices) { 17114 proc.foregroundServices = isForeground; 17115 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17116 proc.info.uid); 17117 if (isForeground) { 17118 if (curProcs == null) { 17119 curProcs = new ArrayList<ProcessRecord>(); 17120 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17121 } 17122 if (!curProcs.contains(proc)) { 17123 curProcs.add(proc); 17124 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17125 proc.info.packageName, proc.info.uid); 17126 } 17127 } else { 17128 if (curProcs != null) { 17129 if (curProcs.remove(proc)) { 17130 mBatteryStatsService.noteEvent( 17131 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17132 proc.info.packageName, proc.info.uid); 17133 if (curProcs.size() <= 0) { 17134 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17135 } 17136 } 17137 } 17138 } 17139 if (oomAdj) { 17140 updateOomAdjLocked(); 17141 } 17142 } 17143 } 17144 17145 private final ActivityRecord resumedAppLocked() { 17146 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17147 String pkg; 17148 int uid; 17149 if (act != null) { 17150 pkg = act.packageName; 17151 uid = act.info.applicationInfo.uid; 17152 } else { 17153 pkg = null; 17154 uid = -1; 17155 } 17156 // Has the UID or resumed package name changed? 17157 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17158 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17159 if (mCurResumedPackage != null) { 17160 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17161 mCurResumedPackage, mCurResumedUid); 17162 } 17163 mCurResumedPackage = pkg; 17164 mCurResumedUid = uid; 17165 if (mCurResumedPackage != null) { 17166 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17167 mCurResumedPackage, mCurResumedUid); 17168 } 17169 } 17170 return act; 17171 } 17172 17173 final boolean updateOomAdjLocked(ProcessRecord app) { 17174 final ActivityRecord TOP_ACT = resumedAppLocked(); 17175 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17176 final boolean wasCached = app.cached; 17177 17178 mAdjSeq++; 17179 17180 // This is the desired cached adjusment we want to tell it to use. 17181 // If our app is currently cached, we know it, and that is it. Otherwise, 17182 // we don't know it yet, and it needs to now be cached we will then 17183 // need to do a complete oom adj. 17184 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17185 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17186 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17187 SystemClock.uptimeMillis()); 17188 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17189 // Changed to/from cached state, so apps after it in the LRU 17190 // list may also be changed. 17191 updateOomAdjLocked(); 17192 } 17193 return success; 17194 } 17195 17196 final void updateOomAdjLocked() { 17197 final ActivityRecord TOP_ACT = resumedAppLocked(); 17198 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17199 final long now = SystemClock.uptimeMillis(); 17200 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17201 final int N = mLruProcesses.size(); 17202 17203 if (false) { 17204 RuntimeException e = new RuntimeException(); 17205 e.fillInStackTrace(); 17206 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17207 } 17208 17209 mAdjSeq++; 17210 mNewNumServiceProcs = 0; 17211 mNewNumAServiceProcs = 0; 17212 17213 final int emptyProcessLimit; 17214 final int cachedProcessLimit; 17215 if (mProcessLimit <= 0) { 17216 emptyProcessLimit = cachedProcessLimit = 0; 17217 } else if (mProcessLimit == 1) { 17218 emptyProcessLimit = 1; 17219 cachedProcessLimit = 0; 17220 } else { 17221 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17222 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17223 } 17224 17225 // Let's determine how many processes we have running vs. 17226 // how many slots we have for background processes; we may want 17227 // to put multiple processes in a slot of there are enough of 17228 // them. 17229 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17230 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17231 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17232 if (numEmptyProcs > cachedProcessLimit) { 17233 // If there are more empty processes than our limit on cached 17234 // processes, then use the cached process limit for the factor. 17235 // This ensures that the really old empty processes get pushed 17236 // down to the bottom, so if we are running low on memory we will 17237 // have a better chance at keeping around more cached processes 17238 // instead of a gazillion empty processes. 17239 numEmptyProcs = cachedProcessLimit; 17240 } 17241 int emptyFactor = numEmptyProcs/numSlots; 17242 if (emptyFactor < 1) emptyFactor = 1; 17243 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17244 if (cachedFactor < 1) cachedFactor = 1; 17245 int stepCached = 0; 17246 int stepEmpty = 0; 17247 int numCached = 0; 17248 int numEmpty = 0; 17249 int numTrimming = 0; 17250 17251 mNumNonCachedProcs = 0; 17252 mNumCachedHiddenProcs = 0; 17253 17254 // First update the OOM adjustment for each of the 17255 // application processes based on their current state. 17256 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17257 int nextCachedAdj = curCachedAdj+1; 17258 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17259 int nextEmptyAdj = curEmptyAdj+2; 17260 for (int i=N-1; i>=0; i--) { 17261 ProcessRecord app = mLruProcesses.get(i); 17262 if (!app.killedByAm && app.thread != null) { 17263 app.procStateChanged = false; 17264 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17265 17266 // If we haven't yet assigned the final cached adj 17267 // to the process, do that now. 17268 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17269 switch (app.curProcState) { 17270 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17271 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17272 // This process is a cached process holding activities... 17273 // assign it the next cached value for that type, and then 17274 // step that cached level. 17275 app.curRawAdj = curCachedAdj; 17276 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17277 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17278 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17279 + ")"); 17280 if (curCachedAdj != nextCachedAdj) { 17281 stepCached++; 17282 if (stepCached >= cachedFactor) { 17283 stepCached = 0; 17284 curCachedAdj = nextCachedAdj; 17285 nextCachedAdj += 2; 17286 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17287 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17288 } 17289 } 17290 } 17291 break; 17292 default: 17293 // For everything else, assign next empty cached process 17294 // level and bump that up. Note that this means that 17295 // long-running services that have dropped down to the 17296 // cached level will be treated as empty (since their process 17297 // state is still as a service), which is what we want. 17298 app.curRawAdj = curEmptyAdj; 17299 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17300 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17301 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17302 + ")"); 17303 if (curEmptyAdj != nextEmptyAdj) { 17304 stepEmpty++; 17305 if (stepEmpty >= emptyFactor) { 17306 stepEmpty = 0; 17307 curEmptyAdj = nextEmptyAdj; 17308 nextEmptyAdj += 2; 17309 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17310 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17311 } 17312 } 17313 } 17314 break; 17315 } 17316 } 17317 17318 applyOomAdjLocked(app, TOP_APP, true, now); 17319 17320 // Count the number of process types. 17321 switch (app.curProcState) { 17322 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17323 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17324 mNumCachedHiddenProcs++; 17325 numCached++; 17326 if (numCached > cachedProcessLimit) { 17327 app.kill("cached #" + numCached, true); 17328 } 17329 break; 17330 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17331 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17332 && app.lastActivityTime < oldTime) { 17333 app.kill("empty for " 17334 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17335 / 1000) + "s", true); 17336 } else { 17337 numEmpty++; 17338 if (numEmpty > emptyProcessLimit) { 17339 app.kill("empty #" + numEmpty, true); 17340 } 17341 } 17342 break; 17343 default: 17344 mNumNonCachedProcs++; 17345 break; 17346 } 17347 17348 if (app.isolated && app.services.size() <= 0) { 17349 // If this is an isolated process, and there are no 17350 // services running in it, then the process is no longer 17351 // needed. We agressively kill these because we can by 17352 // definition not re-use the same process again, and it is 17353 // good to avoid having whatever code was running in them 17354 // left sitting around after no longer needed. 17355 app.kill("isolated not needed", true); 17356 } 17357 17358 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17359 && !app.killedByAm) { 17360 numTrimming++; 17361 } 17362 } 17363 } 17364 17365 mNumServiceProcs = mNewNumServiceProcs; 17366 17367 // Now determine the memory trimming level of background processes. 17368 // Unfortunately we need to start at the back of the list to do this 17369 // properly. We only do this if the number of background apps we 17370 // are managing to keep around is less than half the maximum we desire; 17371 // if we are keeping a good number around, we'll let them use whatever 17372 // memory they want. 17373 final int numCachedAndEmpty = numCached + numEmpty; 17374 int memFactor; 17375 if (numCached <= ProcessList.TRIM_CACHED_APPS 17376 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17377 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17378 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17379 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17380 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17381 } else { 17382 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17383 } 17384 } else { 17385 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17386 } 17387 // We always allow the memory level to go up (better). We only allow it to go 17388 // down if we are in a state where that is allowed, *and* the total number of processes 17389 // has gone down since last time. 17390 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17391 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17392 + " last=" + mLastNumProcesses); 17393 if (memFactor > mLastMemoryLevel) { 17394 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17395 memFactor = mLastMemoryLevel; 17396 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17397 } 17398 } 17399 mLastMemoryLevel = memFactor; 17400 mLastNumProcesses = mLruProcesses.size(); 17401 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17402 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17403 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17404 if (mLowRamStartTime == 0) { 17405 mLowRamStartTime = now; 17406 } 17407 int step = 0; 17408 int fgTrimLevel; 17409 switch (memFactor) { 17410 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17411 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17412 break; 17413 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17414 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17415 break; 17416 default: 17417 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17418 break; 17419 } 17420 int factor = numTrimming/3; 17421 int minFactor = 2; 17422 if (mHomeProcess != null) minFactor++; 17423 if (mPreviousProcess != null) minFactor++; 17424 if (factor < minFactor) factor = minFactor; 17425 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17426 for (int i=N-1; i>=0; i--) { 17427 ProcessRecord app = mLruProcesses.get(i); 17428 if (allChanged || app.procStateChanged) { 17429 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17430 app.procStateChanged = false; 17431 } 17432 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17433 && !app.killedByAm) { 17434 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17435 try { 17436 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17437 "Trimming memory of " + app.processName 17438 + " to " + curLevel); 17439 app.thread.scheduleTrimMemory(curLevel); 17440 } catch (RemoteException e) { 17441 } 17442 if (false) { 17443 // For now we won't do this; our memory trimming seems 17444 // to be good enough at this point that destroying 17445 // activities causes more harm than good. 17446 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17447 && app != mHomeProcess && app != mPreviousProcess) { 17448 // Need to do this on its own message because the stack may not 17449 // be in a consistent state at this point. 17450 // For these apps we will also finish their activities 17451 // to help them free memory. 17452 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17453 } 17454 } 17455 } 17456 app.trimMemoryLevel = curLevel; 17457 step++; 17458 if (step >= factor) { 17459 step = 0; 17460 switch (curLevel) { 17461 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17462 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17463 break; 17464 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17465 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17466 break; 17467 } 17468 } 17469 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17470 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17471 && app.thread != null) { 17472 try { 17473 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17474 "Trimming memory of heavy-weight " + app.processName 17475 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17476 app.thread.scheduleTrimMemory( 17477 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17478 } catch (RemoteException e) { 17479 } 17480 } 17481 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17482 } else { 17483 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17484 || app.systemNoUi) && app.pendingUiClean) { 17485 // If this application is now in the background and it 17486 // had done UI, then give it the special trim level to 17487 // have it free UI resources. 17488 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17489 if (app.trimMemoryLevel < level && app.thread != null) { 17490 try { 17491 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17492 "Trimming memory of bg-ui " + app.processName 17493 + " to " + level); 17494 app.thread.scheduleTrimMemory(level); 17495 } catch (RemoteException e) { 17496 } 17497 } 17498 app.pendingUiClean = false; 17499 } 17500 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17501 try { 17502 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17503 "Trimming memory of fg " + app.processName 17504 + " to " + fgTrimLevel); 17505 app.thread.scheduleTrimMemory(fgTrimLevel); 17506 } catch (RemoteException e) { 17507 } 17508 } 17509 app.trimMemoryLevel = fgTrimLevel; 17510 } 17511 } 17512 } else { 17513 if (mLowRamStartTime != 0) { 17514 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17515 mLowRamStartTime = 0; 17516 } 17517 for (int i=N-1; i>=0; i--) { 17518 ProcessRecord app = mLruProcesses.get(i); 17519 if (allChanged || app.procStateChanged) { 17520 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17521 app.procStateChanged = false; 17522 } 17523 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17524 || app.systemNoUi) && app.pendingUiClean) { 17525 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17526 && app.thread != null) { 17527 try { 17528 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17529 "Trimming memory of ui hidden " + app.processName 17530 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17531 app.thread.scheduleTrimMemory( 17532 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17533 } catch (RemoteException e) { 17534 } 17535 } 17536 app.pendingUiClean = false; 17537 } 17538 app.trimMemoryLevel = 0; 17539 } 17540 } 17541 17542 if (mAlwaysFinishActivities) { 17543 // Need to do this on its own message because the stack may not 17544 // be in a consistent state at this point. 17545 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17546 } 17547 17548 if (allChanged) { 17549 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17550 } 17551 17552 if (mProcessStats.shouldWriteNowLocked(now)) { 17553 mHandler.post(new Runnable() { 17554 @Override public void run() { 17555 synchronized (ActivityManagerService.this) { 17556 mProcessStats.writeStateAsyncLocked(); 17557 } 17558 } 17559 }); 17560 } 17561 17562 if (DEBUG_OOM_ADJ) { 17563 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17564 } 17565 } 17566 17567 final void trimApplications() { 17568 synchronized (this) { 17569 int i; 17570 17571 // First remove any unused application processes whose package 17572 // has been removed. 17573 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17574 final ProcessRecord app = mRemovedProcesses.get(i); 17575 if (app.activities.size() == 0 17576 && app.curReceiver == null && app.services.size() == 0) { 17577 Slog.i( 17578 TAG, "Exiting empty application process " 17579 + app.processName + " (" 17580 + (app.thread != null ? app.thread.asBinder() : null) 17581 + ")\n"); 17582 if (app.pid > 0 && app.pid != MY_PID) { 17583 app.kill("empty", false); 17584 } else { 17585 try { 17586 app.thread.scheduleExit(); 17587 } catch (Exception e) { 17588 // Ignore exceptions. 17589 } 17590 } 17591 cleanUpApplicationRecordLocked(app, false, true, -1); 17592 mRemovedProcesses.remove(i); 17593 17594 if (app.persistent) { 17595 addAppLocked(app.info, false, null /* ABI override */); 17596 } 17597 } 17598 } 17599 17600 // Now update the oom adj for all processes. 17601 updateOomAdjLocked(); 17602 } 17603 } 17604 17605 /** This method sends the specified signal to each of the persistent apps */ 17606 public void signalPersistentProcesses(int sig) throws RemoteException { 17607 if (sig != Process.SIGNAL_USR1) { 17608 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17609 } 17610 17611 synchronized (this) { 17612 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17613 != PackageManager.PERMISSION_GRANTED) { 17614 throw new SecurityException("Requires permission " 17615 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17616 } 17617 17618 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17619 ProcessRecord r = mLruProcesses.get(i); 17620 if (r.thread != null && r.persistent) { 17621 Process.sendSignal(r.pid, sig); 17622 } 17623 } 17624 } 17625 } 17626 17627 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17628 if (proc == null || proc == mProfileProc) { 17629 proc = mProfileProc; 17630 profileType = mProfileType; 17631 clearProfilerLocked(); 17632 } 17633 if (proc == null) { 17634 return; 17635 } 17636 try { 17637 proc.thread.profilerControl(false, null, profileType); 17638 } catch (RemoteException e) { 17639 throw new IllegalStateException("Process disappeared"); 17640 } 17641 } 17642 17643 private void clearProfilerLocked() { 17644 if (mProfileFd != null) { 17645 try { 17646 mProfileFd.close(); 17647 } catch (IOException e) { 17648 } 17649 } 17650 mProfileApp = null; 17651 mProfileProc = null; 17652 mProfileFile = null; 17653 mProfileType = 0; 17654 mAutoStopProfiler = false; 17655 mSamplingInterval = 0; 17656 } 17657 17658 public boolean profileControl(String process, int userId, boolean start, 17659 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17660 17661 try { 17662 synchronized (this) { 17663 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17664 // its own permission. 17665 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17666 != PackageManager.PERMISSION_GRANTED) { 17667 throw new SecurityException("Requires permission " 17668 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17669 } 17670 17671 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17672 throw new IllegalArgumentException("null profile info or fd"); 17673 } 17674 17675 ProcessRecord proc = null; 17676 if (process != null) { 17677 proc = findProcessLocked(process, userId, "profileControl"); 17678 } 17679 17680 if (start && (proc == null || proc.thread == null)) { 17681 throw new IllegalArgumentException("Unknown process: " + process); 17682 } 17683 17684 if (start) { 17685 stopProfilerLocked(null, 0); 17686 setProfileApp(proc.info, proc.processName, profilerInfo); 17687 mProfileProc = proc; 17688 mProfileType = profileType; 17689 ParcelFileDescriptor fd = profilerInfo.profileFd; 17690 try { 17691 fd = fd.dup(); 17692 } catch (IOException e) { 17693 fd = null; 17694 } 17695 profilerInfo.profileFd = fd; 17696 proc.thread.profilerControl(start, profilerInfo, profileType); 17697 fd = null; 17698 mProfileFd = null; 17699 } else { 17700 stopProfilerLocked(proc, profileType); 17701 if (profilerInfo != null && profilerInfo.profileFd != null) { 17702 try { 17703 profilerInfo.profileFd.close(); 17704 } catch (IOException e) { 17705 } 17706 } 17707 } 17708 17709 return true; 17710 } 17711 } catch (RemoteException e) { 17712 throw new IllegalStateException("Process disappeared"); 17713 } finally { 17714 if (profilerInfo != null && profilerInfo.profileFd != null) { 17715 try { 17716 profilerInfo.profileFd.close(); 17717 } catch (IOException e) { 17718 } 17719 } 17720 } 17721 } 17722 17723 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17724 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17725 userId, true, ALLOW_FULL_ONLY, callName, null); 17726 ProcessRecord proc = null; 17727 try { 17728 int pid = Integer.parseInt(process); 17729 synchronized (mPidsSelfLocked) { 17730 proc = mPidsSelfLocked.get(pid); 17731 } 17732 } catch (NumberFormatException e) { 17733 } 17734 17735 if (proc == null) { 17736 ArrayMap<String, SparseArray<ProcessRecord>> all 17737 = mProcessNames.getMap(); 17738 SparseArray<ProcessRecord> procs = all.get(process); 17739 if (procs != null && procs.size() > 0) { 17740 proc = procs.valueAt(0); 17741 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17742 for (int i=1; i<procs.size(); i++) { 17743 ProcessRecord thisProc = procs.valueAt(i); 17744 if (thisProc.userId == userId) { 17745 proc = thisProc; 17746 break; 17747 } 17748 } 17749 } 17750 } 17751 } 17752 17753 return proc; 17754 } 17755 17756 public boolean dumpHeap(String process, int userId, boolean managed, 17757 String path, ParcelFileDescriptor fd) throws RemoteException { 17758 17759 try { 17760 synchronized (this) { 17761 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17762 // its own permission (same as profileControl). 17763 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17764 != PackageManager.PERMISSION_GRANTED) { 17765 throw new SecurityException("Requires permission " 17766 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17767 } 17768 17769 if (fd == null) { 17770 throw new IllegalArgumentException("null fd"); 17771 } 17772 17773 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17774 if (proc == null || proc.thread == null) { 17775 throw new IllegalArgumentException("Unknown process: " + process); 17776 } 17777 17778 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17779 if (!isDebuggable) { 17780 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17781 throw new SecurityException("Process not debuggable: " + proc); 17782 } 17783 } 17784 17785 proc.thread.dumpHeap(managed, path, fd); 17786 fd = null; 17787 return true; 17788 } 17789 } catch (RemoteException e) { 17790 throw new IllegalStateException("Process disappeared"); 17791 } finally { 17792 if (fd != null) { 17793 try { 17794 fd.close(); 17795 } catch (IOException e) { 17796 } 17797 } 17798 } 17799 } 17800 17801 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17802 public void monitor() { 17803 synchronized (this) { } 17804 } 17805 17806 void onCoreSettingsChange(Bundle settings) { 17807 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17808 ProcessRecord processRecord = mLruProcesses.get(i); 17809 try { 17810 if (processRecord.thread != null) { 17811 processRecord.thread.setCoreSettings(settings); 17812 } 17813 } catch (RemoteException re) { 17814 /* ignore */ 17815 } 17816 } 17817 } 17818 17819 // Multi-user methods 17820 17821 /** 17822 * Start user, if its not already running, but don't bring it to foreground. 17823 */ 17824 @Override 17825 public boolean startUserInBackground(final int userId) { 17826 return startUser(userId, /* foreground */ false); 17827 } 17828 17829 /** 17830 * Start user, if its not already running, and bring it to foreground. 17831 */ 17832 boolean startUserInForeground(final int userId, Dialog dlg) { 17833 boolean result = startUser(userId, /* foreground */ true); 17834 dlg.dismiss(); 17835 return result; 17836 } 17837 17838 /** 17839 * Refreshes the list of users related to the current user when either a 17840 * user switch happens or when a new related user is started in the 17841 * background. 17842 */ 17843 private void updateCurrentProfileIdsLocked() { 17844 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17845 mCurrentUserId, false /* enabledOnly */); 17846 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17847 for (int i = 0; i < currentProfileIds.length; i++) { 17848 currentProfileIds[i] = profiles.get(i).id; 17849 } 17850 mCurrentProfileIds = currentProfileIds; 17851 17852 synchronized (mUserProfileGroupIdsSelfLocked) { 17853 mUserProfileGroupIdsSelfLocked.clear(); 17854 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17855 for (int i = 0; i < users.size(); i++) { 17856 UserInfo user = users.get(i); 17857 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17858 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17859 } 17860 } 17861 } 17862 } 17863 17864 private Set getProfileIdsLocked(int userId) { 17865 Set userIds = new HashSet<Integer>(); 17866 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17867 userId, false /* enabledOnly */); 17868 for (UserInfo user : profiles) { 17869 userIds.add(Integer.valueOf(user.id)); 17870 } 17871 return userIds; 17872 } 17873 17874 @Override 17875 public boolean switchUser(final int userId) { 17876 String userName; 17877 synchronized (this) { 17878 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17879 if (userInfo == null) { 17880 Slog.w(TAG, "No user info for user #" + userId); 17881 return false; 17882 } 17883 if (userInfo.isManagedProfile()) { 17884 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17885 return false; 17886 } 17887 userName = userInfo.name; 17888 } 17889 mHandler.removeMessages(START_USER_SWITCH_MSG); 17890 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17891 return true; 17892 } 17893 17894 private void showUserSwitchDialog(int userId, String userName) { 17895 // The dialog will show and then initiate the user switch by calling startUserInForeground 17896 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17897 true /* above system */); 17898 d.show(); 17899 } 17900 17901 private boolean startUser(final int userId, final boolean foreground) { 17902 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17903 != PackageManager.PERMISSION_GRANTED) { 17904 String msg = "Permission Denial: switchUser() from pid=" 17905 + Binder.getCallingPid() 17906 + ", uid=" + Binder.getCallingUid() 17907 + " requires " + INTERACT_ACROSS_USERS_FULL; 17908 Slog.w(TAG, msg); 17909 throw new SecurityException(msg); 17910 } 17911 17912 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17913 17914 final long ident = Binder.clearCallingIdentity(); 17915 try { 17916 synchronized (this) { 17917 final int oldUserId = mCurrentUserId; 17918 if (oldUserId == userId) { 17919 return true; 17920 } 17921 17922 mStackSupervisor.setLockTaskModeLocked(null, false); 17923 17924 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17925 if (userInfo == null) { 17926 Slog.w(TAG, "No user info for user #" + userId); 17927 return false; 17928 } 17929 if (foreground && userInfo.isManagedProfile()) { 17930 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17931 return false; 17932 } 17933 17934 if (foreground) { 17935 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17936 R.anim.screen_user_enter); 17937 } 17938 17939 boolean needStart = false; 17940 17941 // If the user we are switching to is not currently started, then 17942 // we need to start it now. 17943 if (mStartedUsers.get(userId) == null) { 17944 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17945 updateStartedUserArrayLocked(); 17946 needStart = true; 17947 } 17948 17949 final Integer userIdInt = Integer.valueOf(userId); 17950 mUserLru.remove(userIdInt); 17951 mUserLru.add(userIdInt); 17952 17953 if (foreground) { 17954 mCurrentUserId = userId; 17955 updateCurrentProfileIdsLocked(); 17956 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17957 // Once the internal notion of the active user has switched, we lock the device 17958 // with the option to show the user switcher on the keyguard. 17959 mWindowManager.lockNow(null); 17960 } else { 17961 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17962 updateCurrentProfileIdsLocked(); 17963 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17964 mUserLru.remove(currentUserIdInt); 17965 mUserLru.add(currentUserIdInt); 17966 } 17967 17968 final UserStartedState uss = mStartedUsers.get(userId); 17969 17970 // Make sure user is in the started state. If it is currently 17971 // stopping, we need to knock that off. 17972 if (uss.mState == UserStartedState.STATE_STOPPING) { 17973 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17974 // so we can just fairly silently bring the user back from 17975 // the almost-dead. 17976 uss.mState = UserStartedState.STATE_RUNNING; 17977 updateStartedUserArrayLocked(); 17978 needStart = true; 17979 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17980 // This means ACTION_SHUTDOWN has been sent, so we will 17981 // need to treat this as a new boot of the user. 17982 uss.mState = UserStartedState.STATE_BOOTING; 17983 updateStartedUserArrayLocked(); 17984 needStart = true; 17985 } 17986 17987 if (uss.mState == UserStartedState.STATE_BOOTING) { 17988 // Booting up a new user, need to tell system services about it. 17989 // Note that this is on the same handler as scheduling of broadcasts, 17990 // which is important because it needs to go first. 17991 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 17992 } 17993 17994 if (foreground) { 17995 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17996 oldUserId)); 17997 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17998 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17999 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18000 oldUserId, userId, uss)); 18001 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18002 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18003 } 18004 18005 if (needStart) { 18006 // Send USER_STARTED broadcast 18007 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18008 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18009 | Intent.FLAG_RECEIVER_FOREGROUND); 18010 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18011 broadcastIntentLocked(null, null, intent, 18012 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18013 false, false, MY_PID, Process.SYSTEM_UID, userId); 18014 } 18015 18016 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18017 if (userId != UserHandle.USER_OWNER) { 18018 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18019 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18020 broadcastIntentLocked(null, null, intent, null, 18021 new IIntentReceiver.Stub() { 18022 public void performReceive(Intent intent, int resultCode, 18023 String data, Bundle extras, boolean ordered, 18024 boolean sticky, int sendingUser) { 18025 onUserInitialized(uss, foreground, oldUserId, userId); 18026 } 18027 }, 0, null, null, null, AppOpsManager.OP_NONE, 18028 true, false, MY_PID, Process.SYSTEM_UID, 18029 userId); 18030 uss.initializing = true; 18031 } else { 18032 getUserManagerLocked().makeInitialized(userInfo.id); 18033 } 18034 } 18035 18036 if (foreground) { 18037 if (!uss.initializing) { 18038 moveUserToForeground(uss, oldUserId, userId); 18039 } 18040 } else { 18041 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18042 } 18043 18044 if (needStart) { 18045 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18046 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18047 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18048 broadcastIntentLocked(null, null, intent, 18049 null, new IIntentReceiver.Stub() { 18050 @Override 18051 public void performReceive(Intent intent, int resultCode, String data, 18052 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18053 throws RemoteException { 18054 } 18055 }, 0, null, null, 18056 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18057 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18058 } 18059 } 18060 } finally { 18061 Binder.restoreCallingIdentity(ident); 18062 } 18063 18064 return true; 18065 } 18066 18067 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18068 long ident = Binder.clearCallingIdentity(); 18069 try { 18070 Intent intent; 18071 if (oldUserId >= 0) { 18072 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18073 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18074 int count = profiles.size(); 18075 for (int i = 0; i < count; i++) { 18076 int profileUserId = profiles.get(i).id; 18077 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18078 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18079 | Intent.FLAG_RECEIVER_FOREGROUND); 18080 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18081 broadcastIntentLocked(null, null, intent, 18082 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18083 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18084 } 18085 } 18086 if (newUserId >= 0) { 18087 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18088 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18089 int count = profiles.size(); 18090 for (int i = 0; i < count; i++) { 18091 int profileUserId = profiles.get(i).id; 18092 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18093 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18094 | Intent.FLAG_RECEIVER_FOREGROUND); 18095 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18096 broadcastIntentLocked(null, null, intent, 18097 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18098 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18099 } 18100 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18101 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18102 | Intent.FLAG_RECEIVER_FOREGROUND); 18103 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18104 broadcastIntentLocked(null, null, intent, 18105 null, null, 0, null, null, 18106 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18107 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18108 } 18109 } finally { 18110 Binder.restoreCallingIdentity(ident); 18111 } 18112 } 18113 18114 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18115 final int newUserId) { 18116 final int N = mUserSwitchObservers.beginBroadcast(); 18117 if (N > 0) { 18118 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18119 int mCount = 0; 18120 @Override 18121 public void sendResult(Bundle data) throws RemoteException { 18122 synchronized (ActivityManagerService.this) { 18123 if (mCurUserSwitchCallback == this) { 18124 mCount++; 18125 if (mCount == N) { 18126 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18127 } 18128 } 18129 } 18130 } 18131 }; 18132 synchronized (this) { 18133 uss.switching = true; 18134 mCurUserSwitchCallback = callback; 18135 } 18136 for (int i=0; i<N; i++) { 18137 try { 18138 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18139 newUserId, callback); 18140 } catch (RemoteException e) { 18141 } 18142 } 18143 } else { 18144 synchronized (this) { 18145 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18146 } 18147 } 18148 mUserSwitchObservers.finishBroadcast(); 18149 } 18150 18151 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18152 synchronized (this) { 18153 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18154 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18155 } 18156 } 18157 18158 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18159 mCurUserSwitchCallback = null; 18160 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18161 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18162 oldUserId, newUserId, uss)); 18163 } 18164 18165 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18166 synchronized (this) { 18167 if (foreground) { 18168 moveUserToForeground(uss, oldUserId, newUserId); 18169 } 18170 } 18171 18172 completeSwitchAndInitalize(uss, newUserId, true, false); 18173 } 18174 18175 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18176 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18177 if (homeInFront) { 18178 startHomeActivityLocked(newUserId); 18179 } else { 18180 mStackSupervisor.resumeTopActivitiesLocked(); 18181 } 18182 EventLogTags.writeAmSwitchUser(newUserId); 18183 getUserManagerLocked().userForeground(newUserId); 18184 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18185 } 18186 18187 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18188 completeSwitchAndInitalize(uss, newUserId, false, true); 18189 } 18190 18191 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18192 boolean clearInitializing, boolean clearSwitching) { 18193 boolean unfrozen = false; 18194 synchronized (this) { 18195 if (clearInitializing) { 18196 uss.initializing = false; 18197 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18198 } 18199 if (clearSwitching) { 18200 uss.switching = false; 18201 } 18202 if (!uss.switching && !uss.initializing) { 18203 mWindowManager.stopFreezingScreen(); 18204 unfrozen = true; 18205 } 18206 } 18207 if (unfrozen) { 18208 final int N = mUserSwitchObservers.beginBroadcast(); 18209 for (int i=0; i<N; i++) { 18210 try { 18211 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18212 } catch (RemoteException e) { 18213 } 18214 } 18215 mUserSwitchObservers.finishBroadcast(); 18216 } 18217 } 18218 18219 void scheduleStartProfilesLocked() { 18220 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18221 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18222 DateUtils.SECOND_IN_MILLIS); 18223 } 18224 } 18225 18226 void startProfilesLocked() { 18227 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18228 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18229 mCurrentUserId, false /* enabledOnly */); 18230 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18231 for (UserInfo user : profiles) { 18232 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18233 && user.id != mCurrentUserId) { 18234 toStart.add(user); 18235 } 18236 } 18237 final int n = toStart.size(); 18238 int i = 0; 18239 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18240 startUserInBackground(toStart.get(i).id); 18241 } 18242 if (i < n) { 18243 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18244 } 18245 } 18246 18247 void finishUserBoot(UserStartedState uss) { 18248 synchronized (this) { 18249 if (uss.mState == UserStartedState.STATE_BOOTING 18250 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18251 uss.mState = UserStartedState.STATE_RUNNING; 18252 final int userId = uss.mHandle.getIdentifier(); 18253 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18254 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18255 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18256 broadcastIntentLocked(null, null, intent, 18257 null, null, 0, null, null, 18258 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18259 true, false, MY_PID, Process.SYSTEM_UID, userId); 18260 } 18261 } 18262 } 18263 18264 void finishUserSwitch(UserStartedState uss) { 18265 synchronized (this) { 18266 finishUserBoot(uss); 18267 18268 startProfilesLocked(); 18269 18270 int num = mUserLru.size(); 18271 int i = 0; 18272 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18273 Integer oldUserId = mUserLru.get(i); 18274 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18275 if (oldUss == null) { 18276 // Shouldn't happen, but be sane if it does. 18277 mUserLru.remove(i); 18278 num--; 18279 continue; 18280 } 18281 if (oldUss.mState == UserStartedState.STATE_STOPPING 18282 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18283 // This user is already stopping, doesn't count. 18284 num--; 18285 i++; 18286 continue; 18287 } 18288 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18289 // Owner and current can't be stopped, but count as running. 18290 i++; 18291 continue; 18292 } 18293 // This is a user to be stopped. 18294 stopUserLocked(oldUserId, null); 18295 num--; 18296 i++; 18297 } 18298 } 18299 } 18300 18301 @Override 18302 public int stopUser(final int userId, final IStopUserCallback callback) { 18303 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18304 != PackageManager.PERMISSION_GRANTED) { 18305 String msg = "Permission Denial: switchUser() from pid=" 18306 + Binder.getCallingPid() 18307 + ", uid=" + Binder.getCallingUid() 18308 + " requires " + INTERACT_ACROSS_USERS_FULL; 18309 Slog.w(TAG, msg); 18310 throw new SecurityException(msg); 18311 } 18312 if (userId <= 0) { 18313 throw new IllegalArgumentException("Can't stop primary user " + userId); 18314 } 18315 synchronized (this) { 18316 return stopUserLocked(userId, callback); 18317 } 18318 } 18319 18320 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18321 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18322 if (mCurrentUserId == userId) { 18323 return ActivityManager.USER_OP_IS_CURRENT; 18324 } 18325 18326 final UserStartedState uss = mStartedUsers.get(userId); 18327 if (uss == null) { 18328 // User is not started, nothing to do... but we do need to 18329 // callback if requested. 18330 if (callback != null) { 18331 mHandler.post(new Runnable() { 18332 @Override 18333 public void run() { 18334 try { 18335 callback.userStopped(userId); 18336 } catch (RemoteException e) { 18337 } 18338 } 18339 }); 18340 } 18341 return ActivityManager.USER_OP_SUCCESS; 18342 } 18343 18344 if (callback != null) { 18345 uss.mStopCallbacks.add(callback); 18346 } 18347 18348 if (uss.mState != UserStartedState.STATE_STOPPING 18349 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18350 uss.mState = UserStartedState.STATE_STOPPING; 18351 updateStartedUserArrayLocked(); 18352 18353 long ident = Binder.clearCallingIdentity(); 18354 try { 18355 // We are going to broadcast ACTION_USER_STOPPING and then 18356 // once that is done send a final ACTION_SHUTDOWN and then 18357 // stop the user. 18358 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18359 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18360 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18361 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18362 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18363 // This is the result receiver for the final shutdown broadcast. 18364 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18365 @Override 18366 public void performReceive(Intent intent, int resultCode, String data, 18367 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18368 finishUserStop(uss); 18369 } 18370 }; 18371 // This is the result receiver for the initial stopping broadcast. 18372 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18373 @Override 18374 public void performReceive(Intent intent, int resultCode, String data, 18375 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18376 // On to the next. 18377 synchronized (ActivityManagerService.this) { 18378 if (uss.mState != UserStartedState.STATE_STOPPING) { 18379 // Whoops, we are being started back up. Abort, abort! 18380 return; 18381 } 18382 uss.mState = UserStartedState.STATE_SHUTDOWN; 18383 } 18384 mBatteryStatsService.noteEvent( 18385 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18386 Integer.toString(userId), userId); 18387 mSystemServiceManager.stopUser(userId); 18388 broadcastIntentLocked(null, null, shutdownIntent, 18389 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18390 true, false, MY_PID, Process.SYSTEM_UID, userId); 18391 } 18392 }; 18393 // Kick things off. 18394 broadcastIntentLocked(null, null, stoppingIntent, 18395 null, stoppingReceiver, 0, null, null, 18396 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18397 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18398 } finally { 18399 Binder.restoreCallingIdentity(ident); 18400 } 18401 } 18402 18403 return ActivityManager.USER_OP_SUCCESS; 18404 } 18405 18406 void finishUserStop(UserStartedState uss) { 18407 final int userId = uss.mHandle.getIdentifier(); 18408 boolean stopped; 18409 ArrayList<IStopUserCallback> callbacks; 18410 synchronized (this) { 18411 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18412 if (mStartedUsers.get(userId) != uss) { 18413 stopped = false; 18414 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18415 stopped = false; 18416 } else { 18417 stopped = true; 18418 // User can no longer run. 18419 mStartedUsers.remove(userId); 18420 mUserLru.remove(Integer.valueOf(userId)); 18421 updateStartedUserArrayLocked(); 18422 18423 // Clean up all state and processes associated with the user. 18424 // Kill all the processes for the user. 18425 forceStopUserLocked(userId, "finish user"); 18426 } 18427 18428 // Explicitly remove the old information in mRecentTasks. 18429 removeRecentTasksForUserLocked(userId); 18430 } 18431 18432 for (int i=0; i<callbacks.size(); i++) { 18433 try { 18434 if (stopped) callbacks.get(i).userStopped(userId); 18435 else callbacks.get(i).userStopAborted(userId); 18436 } catch (RemoteException e) { 18437 } 18438 } 18439 18440 if (stopped) { 18441 mSystemServiceManager.cleanupUser(userId); 18442 synchronized (this) { 18443 mStackSupervisor.removeUserLocked(userId); 18444 } 18445 } 18446 } 18447 18448 @Override 18449 public UserInfo getCurrentUser() { 18450 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18451 != PackageManager.PERMISSION_GRANTED) && ( 18452 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18453 != PackageManager.PERMISSION_GRANTED)) { 18454 String msg = "Permission Denial: getCurrentUser() from pid=" 18455 + Binder.getCallingPid() 18456 + ", uid=" + Binder.getCallingUid() 18457 + " requires " + INTERACT_ACROSS_USERS; 18458 Slog.w(TAG, msg); 18459 throw new SecurityException(msg); 18460 } 18461 synchronized (this) { 18462 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18463 } 18464 } 18465 18466 int getCurrentUserIdLocked() { 18467 return mCurrentUserId; 18468 } 18469 18470 @Override 18471 public boolean isUserRunning(int userId, boolean orStopped) { 18472 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18473 != PackageManager.PERMISSION_GRANTED) { 18474 String msg = "Permission Denial: isUserRunning() from pid=" 18475 + Binder.getCallingPid() 18476 + ", uid=" + Binder.getCallingUid() 18477 + " requires " + INTERACT_ACROSS_USERS; 18478 Slog.w(TAG, msg); 18479 throw new SecurityException(msg); 18480 } 18481 synchronized (this) { 18482 return isUserRunningLocked(userId, orStopped); 18483 } 18484 } 18485 18486 boolean isUserRunningLocked(int userId, boolean orStopped) { 18487 UserStartedState state = mStartedUsers.get(userId); 18488 if (state == null) { 18489 return false; 18490 } 18491 if (orStopped) { 18492 return true; 18493 } 18494 return state.mState != UserStartedState.STATE_STOPPING 18495 && state.mState != UserStartedState.STATE_SHUTDOWN; 18496 } 18497 18498 @Override 18499 public int[] getRunningUserIds() { 18500 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18501 != PackageManager.PERMISSION_GRANTED) { 18502 String msg = "Permission Denial: isUserRunning() from pid=" 18503 + Binder.getCallingPid() 18504 + ", uid=" + Binder.getCallingUid() 18505 + " requires " + INTERACT_ACROSS_USERS; 18506 Slog.w(TAG, msg); 18507 throw new SecurityException(msg); 18508 } 18509 synchronized (this) { 18510 return mStartedUserArray; 18511 } 18512 } 18513 18514 private void updateStartedUserArrayLocked() { 18515 int num = 0; 18516 for (int i=0; i<mStartedUsers.size(); i++) { 18517 UserStartedState uss = mStartedUsers.valueAt(i); 18518 // This list does not include stopping users. 18519 if (uss.mState != UserStartedState.STATE_STOPPING 18520 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18521 num++; 18522 } 18523 } 18524 mStartedUserArray = new int[num]; 18525 num = 0; 18526 for (int i=0; i<mStartedUsers.size(); i++) { 18527 UserStartedState uss = mStartedUsers.valueAt(i); 18528 if (uss.mState != UserStartedState.STATE_STOPPING 18529 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18530 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18531 num++; 18532 } 18533 } 18534 } 18535 18536 @Override 18537 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18538 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18539 != PackageManager.PERMISSION_GRANTED) { 18540 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18541 + Binder.getCallingPid() 18542 + ", uid=" + Binder.getCallingUid() 18543 + " requires " + INTERACT_ACROSS_USERS_FULL; 18544 Slog.w(TAG, msg); 18545 throw new SecurityException(msg); 18546 } 18547 18548 mUserSwitchObservers.register(observer); 18549 } 18550 18551 @Override 18552 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18553 mUserSwitchObservers.unregister(observer); 18554 } 18555 18556 private boolean userExists(int userId) { 18557 if (userId == 0) { 18558 return true; 18559 } 18560 UserManagerService ums = getUserManagerLocked(); 18561 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18562 } 18563 18564 int[] getUsersLocked() { 18565 UserManagerService ums = getUserManagerLocked(); 18566 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18567 } 18568 18569 UserManagerService getUserManagerLocked() { 18570 if (mUserManager == null) { 18571 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18572 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18573 } 18574 return mUserManager; 18575 } 18576 18577 private int applyUserId(int uid, int userId) { 18578 return UserHandle.getUid(userId, uid); 18579 } 18580 18581 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18582 if (info == null) return null; 18583 ApplicationInfo newInfo = new ApplicationInfo(info); 18584 newInfo.uid = applyUserId(info.uid, userId); 18585 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18586 + info.packageName; 18587 return newInfo; 18588 } 18589 18590 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18591 if (aInfo == null 18592 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18593 return aInfo; 18594 } 18595 18596 ActivityInfo info = new ActivityInfo(aInfo); 18597 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18598 return info; 18599 } 18600 18601 private final class LocalService extends ActivityManagerInternal { 18602 @Override 18603 public void goingToSleep() { 18604 ActivityManagerService.this.goingToSleep(); 18605 } 18606 18607 @Override 18608 public void wakingUp() { 18609 ActivityManagerService.this.wakingUp(); 18610 } 18611 18612 @Override 18613 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18614 String processName, String abiOverride, int uid, Runnable crashHandler) { 18615 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18616 processName, abiOverride, uid, crashHandler); 18617 } 18618 } 18619 18620 /** 18621 * An implementation of IAppTask, that allows an app to manage its own tasks via 18622 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18623 * only the process that calls getAppTasks() can call the AppTask methods. 18624 */ 18625 class AppTaskImpl extends IAppTask.Stub { 18626 private int mTaskId; 18627 private int mCallingUid; 18628 18629 public AppTaskImpl(int taskId, int callingUid) { 18630 mTaskId = taskId; 18631 mCallingUid = callingUid; 18632 } 18633 18634 private void checkCaller() { 18635 if (mCallingUid != Binder.getCallingUid()) { 18636 throw new SecurityException("Caller " + mCallingUid 18637 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18638 } 18639 } 18640 18641 @Override 18642 public void finishAndRemoveTask() { 18643 checkCaller(); 18644 18645 synchronized (ActivityManagerService.this) { 18646 long origId = Binder.clearCallingIdentity(); 18647 try { 18648 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18649 if (tr == null) { 18650 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18651 } 18652 // Only kill the process if we are not a new document 18653 int flags = tr.getBaseIntent().getFlags(); 18654 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18655 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18656 removeTaskByIdLocked(mTaskId, 18657 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18658 } finally { 18659 Binder.restoreCallingIdentity(origId); 18660 } 18661 } 18662 } 18663 18664 @Override 18665 public ActivityManager.RecentTaskInfo getTaskInfo() { 18666 checkCaller(); 18667 18668 synchronized (ActivityManagerService.this) { 18669 long origId = Binder.clearCallingIdentity(); 18670 try { 18671 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18672 if (tr == null) { 18673 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18674 } 18675 return createRecentTaskInfoFromTaskRecord(tr); 18676 } finally { 18677 Binder.restoreCallingIdentity(origId); 18678 } 18679 } 18680 } 18681 18682 @Override 18683 public void moveToFront() { 18684 checkCaller(); 18685 18686 final TaskRecord tr; 18687 synchronized (ActivityManagerService.this) { 18688 tr = recentTaskForIdLocked(mTaskId); 18689 if (tr == null) { 18690 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18691 } 18692 if (tr.getRootActivity() != null) { 18693 long origId = Binder.clearCallingIdentity(); 18694 try { 18695 moveTaskToFrontLocked(tr.taskId, 0, null); 18696 return; 18697 } finally { 18698 Binder.restoreCallingIdentity(origId); 18699 } 18700 } 18701 } 18702 18703 startActivityFromRecentsInner(tr.taskId, null); 18704 } 18705 18706 @Override 18707 public int startActivity(IBinder whoThread, String callingPackage, 18708 Intent intent, String resolvedType, Bundle options) { 18709 checkCaller(); 18710 18711 int callingUser = UserHandle.getCallingUserId(); 18712 TaskRecord tr; 18713 IApplicationThread appThread; 18714 synchronized (ActivityManagerService.this) { 18715 tr = recentTaskForIdLocked(mTaskId); 18716 if (tr == null) { 18717 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18718 } 18719 appThread = ApplicationThreadNative.asInterface(whoThread); 18720 if (appThread == null) { 18721 throw new IllegalArgumentException("Bad app thread " + appThread); 18722 } 18723 } 18724 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18725 resolvedType, null, null, null, null, 0, 0, null, null, 18726 null, options, callingUser, null, tr); 18727 } 18728 18729 @Override 18730 public void setExcludeFromRecents(boolean exclude) { 18731 checkCaller(); 18732 18733 synchronized (ActivityManagerService.this) { 18734 long origId = Binder.clearCallingIdentity(); 18735 try { 18736 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18737 if (tr == null) { 18738 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18739 } 18740 Intent intent = tr.getBaseIntent(); 18741 if (exclude) { 18742 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18743 } else { 18744 intent.setFlags(intent.getFlags() 18745 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18746 } 18747 } finally { 18748 Binder.restoreCallingIdentity(origId); 18749 } 18750 } 18751 } 18752 } 18753} 18754