ActivityManagerService.java revision ffa2ec664479bff6b4b61d4c349d9db2cb37ca16
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 274 275 // Maximum number recent bitmaps to keep in memory. 276 static final int MAX_RECENT_BITMAPS = 5; 277 278 // Amount of time after a call to stopAppSwitches() during which we will 279 // prevent further untrusted switches from happening. 280 static final long APP_SWITCH_DELAY_TIME = 5*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real. 284 static final int PROC_START_TIMEOUT = 10*1000; 285 286 // How long we wait for a launched process to attach to the activity manager 287 // before we decide it's never going to come up for real, when the process was 288 // started with a wrapper for instrumentation (such as Valgrind) because it 289 // could take much longer than usual. 290 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 291 292 // How long to wait after going idle before forcing apps to GC. 293 static final int GC_TIMEOUT = 5*1000; 294 295 // The minimum amount of time between successive GC requests for a process. 296 static final int GC_MIN_INTERVAL = 60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process. 299 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 300 301 // The minimum amount of time between successive PSS requests for a process 302 // when the request is due to the memory state being lowered. 303 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 304 305 // The rate at which we check for apps using excessive power -- 15 mins. 306 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on wake locks to start killing things. 310 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // The minimum sample duration we will allow before deciding we have 313 // enough data on CPU usage to start killing things. 314 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 315 316 // How long we allow a receiver to run before giving up on it. 317 static final int BROADCAST_FG_TIMEOUT = 10*1000; 318 static final int BROADCAST_BG_TIMEOUT = 60*1000; 319 320 // How long we wait until we timeout on key dispatching. 321 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 322 323 // How long we wait until we timeout on key dispatching during instrumentation. 324 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 325 326 // Amount of time we wait for observers to handle a user switch before 327 // giving up on them and unfreezing the screen. 328 static final int USER_SWITCH_TIMEOUT = 2*1000; 329 330 // Maximum number of users we allow to be running at a time. 331 static final int MAX_RUNNING_USERS = 3; 332 333 // How long to wait in getAssistContextExtras for the activity and foreground services 334 // to respond with the result. 335 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 336 337 // Maximum number of persisted Uri grants a package is allowed 338 static final int MAX_PERSISTED_URI_GRANTS = 128; 339 340 static final int MY_PID = Process.myPid(); 341 342 static final String[] EMPTY_STRING_ARRAY = new String[0]; 343 344 // How many bytes to write into the dropbox log before truncating 345 static final int DROPBOX_MAX_SIZE = 256 * 1024; 346 347 /** All system services */ 348 SystemServiceManager mSystemServiceManager; 349 350 /** Run all ActivityStacks through this */ 351 ActivityStackSupervisor mStackSupervisor; 352 353 public IntentFirewall mIntentFirewall; 354 355 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 356 // default actuion automatically. Important for devices without direct input 357 // devices. 358 private boolean mShowDialogs = true; 359 360 /** 361 * Description of a request to start a new activity, which has been held 362 * due to app switches being disabled. 363 */ 364 static class PendingActivityLaunch { 365 final ActivityRecord r; 366 final ActivityRecord sourceRecord; 367 final int startFlags; 368 final ActivityStack stack; 369 370 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 371 int _startFlags, ActivityStack _stack) { 372 r = _r; 373 sourceRecord = _sourceRecord; 374 startFlags = _startFlags; 375 stack = _stack; 376 } 377 } 378 379 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 380 = new ArrayList<PendingActivityLaunch>(); 381 382 BroadcastQueue mFgBroadcastQueue; 383 BroadcastQueue mBgBroadcastQueue; 384 // Convenient for easy iteration over the queues. Foreground is first 385 // so that dispatch of foreground broadcasts gets precedence. 386 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 387 388 BroadcastQueue broadcastQueueForIntent(Intent intent) { 389 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 390 if (DEBUG_BACKGROUND_BROADCAST) { 391 Slog.i(TAG, "Broadcast intent " + intent + " on " 392 + (isFg ? "foreground" : "background") 393 + " queue"); 394 } 395 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 396 } 397 398 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 399 for (BroadcastQueue queue : mBroadcastQueues) { 400 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 401 if (r != null) { 402 return r; 403 } 404 } 405 return null; 406 } 407 408 /** 409 * Activity we have told the window manager to have key focus. 410 */ 411 ActivityRecord mFocusedActivity = null; 412 413 /** 414 * List of intents that were used to start the most recent tasks. 415 */ 416 ArrayList<TaskRecord> mRecentTasks; 417 418 public class PendingAssistExtras extends Binder implements Runnable { 419 public final ActivityRecord activity; 420 public boolean haveResult = false; 421 public Bundle result = null; 422 public PendingAssistExtras(ActivityRecord _activity) { 423 activity = _activity; 424 } 425 @Override 426 public void run() { 427 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 428 synchronized (this) { 429 haveResult = true; 430 notifyAll(); 431 } 432 } 433 } 434 435 final ArrayList<PendingAssistExtras> mPendingAssistExtras 436 = new ArrayList<PendingAssistExtras>(); 437 438 /** 439 * Process management. 440 */ 441 final ProcessList mProcessList = new ProcessList(); 442 443 /** 444 * All of the applications we currently have running organized by name. 445 * The keys are strings of the application package name (as 446 * returned by the package manager), and the keys are ApplicationRecord 447 * objects. 448 */ 449 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 450 451 /** 452 * Tracking long-term execution of processes to look for abuse and other 453 * bad app behavior. 454 */ 455 final ProcessStatsService mProcessStats; 456 457 /** 458 * The currently running isolated processes. 459 */ 460 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 461 462 /** 463 * Counter for assigning isolated process uids, to avoid frequently reusing the 464 * same ones. 465 */ 466 int mNextIsolatedProcessUid = 0; 467 468 /** 469 * The currently running heavy-weight process, if any. 470 */ 471 ProcessRecord mHeavyWeightProcess = null; 472 473 /** 474 * The last time that various processes have crashed. 475 */ 476 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 477 478 /** 479 * Information about a process that is currently marked as bad. 480 */ 481 static final class BadProcessInfo { 482 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 483 this.time = time; 484 this.shortMsg = shortMsg; 485 this.longMsg = longMsg; 486 this.stack = stack; 487 } 488 489 final long time; 490 final String shortMsg; 491 final String longMsg; 492 final String stack; 493 } 494 495 /** 496 * Set of applications that we consider to be bad, and will reject 497 * incoming broadcasts from (which the user has no control over). 498 * Processes are added to this set when they have crashed twice within 499 * a minimum amount of time; they are removed from it when they are 500 * later restarted (hopefully due to some user action). The value is the 501 * time it was added to the list. 502 */ 503 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 504 505 /** 506 * All of the processes we currently have running organized by pid. 507 * The keys are the pid running the application. 508 * 509 * <p>NOTE: This object is protected by its own lock, NOT the global 510 * activity manager lock! 511 */ 512 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 513 514 /** 515 * All of the processes that have been forced to be foreground. The key 516 * is the pid of the caller who requested it (we hold a death 517 * link on it). 518 */ 519 abstract class ForegroundToken implements IBinder.DeathRecipient { 520 int pid; 521 IBinder token; 522 } 523 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 524 525 /** 526 * List of records for processes that someone had tried to start before the 527 * system was ready. We don't start them at that point, but ensure they 528 * are started by the time booting is complete. 529 */ 530 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 531 532 /** 533 * List of persistent applications that are in the process 534 * of being started. 535 */ 536 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * Processes that are being forcibly torn down. 540 */ 541 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * List of running applications, sorted by recent usage. 545 * The first entry in the list is the least recently used. 546 */ 547 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 548 549 /** 550 * Where in mLruProcesses that the processes hosting activities start. 551 */ 552 int mLruProcessActivityStart = 0; 553 554 /** 555 * Where in mLruProcesses that the processes hosting services start. 556 * This is after (lower index) than mLruProcessesActivityStart. 557 */ 558 int mLruProcessServiceStart = 0; 559 560 /** 561 * List of processes that should gc as soon as things are idle. 562 */ 563 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Processes we want to collect PSS data from. 567 */ 568 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 569 570 /** 571 * Last time we requested PSS data of all processes. 572 */ 573 long mLastFullPssTime = SystemClock.uptimeMillis(); 574 575 /** 576 * If set, the next time we collect PSS data we should do a full collection 577 * with data from native processes and the kernel. 578 */ 579 boolean mFullPssPending = false; 580 581 /** 582 * This is the process holding what we currently consider to be 583 * the "home" activity. 584 */ 585 ProcessRecord mHomeProcess; 586 587 /** 588 * This is the process holding the activity the user last visited that 589 * is in a different process from the one they are currently in. 590 */ 591 ProcessRecord mPreviousProcess; 592 593 /** 594 * The time at which the previous process was last visible. 595 */ 596 long mPreviousProcessVisibleTime; 597 598 /** 599 * Which uses have been started, so are allowed to run code. 600 */ 601 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 602 603 /** 604 * LRU list of history of current users. Most recently current is at the end. 605 */ 606 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 607 608 /** 609 * Constant array of the users that are currently started. 610 */ 611 int[] mStartedUserArray = new int[] { 0 }; 612 613 /** 614 * Registered observers of the user switching mechanics. 615 */ 616 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 617 = new RemoteCallbackList<IUserSwitchObserver>(); 618 619 /** 620 * Currently active user switch. 621 */ 622 Object mCurUserSwitchCallback; 623 624 /** 625 * Packages that the user has asked to have run in screen size 626 * compatibility mode instead of filling the screen. 627 */ 628 final CompatModePackages mCompatModePackages; 629 630 /** 631 * Set of IntentSenderRecord objects that are currently active. 632 */ 633 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 634 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 635 636 /** 637 * Fingerprints (hashCode()) of stack traces that we've 638 * already logged DropBox entries for. Guarded by itself. If 639 * something (rogue user app) forces this over 640 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 641 */ 642 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 643 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 644 645 /** 646 * Strict Mode background batched logging state. 647 * 648 * The string buffer is guarded by itself, and its lock is also 649 * used to determine if another batched write is already 650 * in-flight. 651 */ 652 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 653 654 /** 655 * Keeps track of all IIntentReceivers that have been registered for 656 * broadcasts. Hash keys are the receiver IBinder, hash value is 657 * a ReceiverList. 658 */ 659 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 660 new HashMap<IBinder, ReceiverList>(); 661 662 /** 663 * Resolver for broadcast intents to registered receivers. 664 * Holds BroadcastFilter (subclass of IntentFilter). 665 */ 666 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 667 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 668 @Override 669 protected boolean allowFilterResult( 670 BroadcastFilter filter, List<BroadcastFilter> dest) { 671 IBinder target = filter.receiverList.receiver.asBinder(); 672 for (int i=dest.size()-1; i>=0; i--) { 673 if (dest.get(i).receiverList.receiver.asBinder() == target) { 674 return false; 675 } 676 } 677 return true; 678 } 679 680 @Override 681 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 682 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 683 || userId == filter.owningUserId) { 684 return super.newResult(filter, match, userId); 685 } 686 return null; 687 } 688 689 @Override 690 protected BroadcastFilter[] newArray(int size) { 691 return new BroadcastFilter[size]; 692 } 693 694 @Override 695 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 696 return packageName.equals(filter.packageName); 697 } 698 }; 699 700 /** 701 * State of all active sticky broadcasts per user. Keys are the action of the 702 * sticky Intent, values are an ArrayList of all broadcasted intents with 703 * that action (which should usually be one). The SparseArray is keyed 704 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 705 * for stickies that are sent to all users. 706 */ 707 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 708 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 709 710 final ActiveServices mServices; 711 712 /** 713 * Backup/restore process management 714 */ 715 String mBackupAppName = null; 716 BackupRecord mBackupTarget = null; 717 718 final ProviderMap mProviderMap; 719 720 /** 721 * List of content providers who have clients waiting for them. The 722 * application is currently being launched and the provider will be 723 * removed from this list once it is published. 724 */ 725 final ArrayList<ContentProviderRecord> mLaunchingProviders 726 = new ArrayList<ContentProviderRecord>(); 727 728 /** 729 * File storing persisted {@link #mGrantedUriPermissions}. 730 */ 731 private final AtomicFile mGrantFile; 732 733 /** XML constants used in {@link #mGrantFile} */ 734 private static final String TAG_URI_GRANTS = "uri-grants"; 735 private static final String TAG_URI_GRANT = "uri-grant"; 736 private static final String ATTR_USER_HANDLE = "userHandle"; 737 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 738 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 739 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 740 private static final String ATTR_TARGET_PKG = "targetPkg"; 741 private static final String ATTR_URI = "uri"; 742 private static final String ATTR_MODE_FLAGS = "modeFlags"; 743 private static final String ATTR_CREATED_TIME = "createdTime"; 744 private static final String ATTR_PREFIX = "prefix"; 745 746 /** 747 * Global set of specific {@link Uri} permissions that have been granted. 748 * This optimized lookup structure maps from {@link UriPermission#targetUid} 749 * to {@link UriPermission#uri} to {@link UriPermission}. 750 */ 751 @GuardedBy("this") 752 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 753 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 754 755 public static class GrantUri { 756 public final int sourceUserId; 757 public final Uri uri; 758 public boolean prefix; 759 760 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 761 this.sourceUserId = sourceUserId; 762 this.uri = uri; 763 this.prefix = prefix; 764 } 765 766 @Override 767 public int hashCode() { 768 return toString().hashCode(); 769 } 770 771 @Override 772 public boolean equals(Object o) { 773 if (o instanceof GrantUri) { 774 GrantUri other = (GrantUri) o; 775 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 776 && prefix == other.prefix; 777 } 778 return false; 779 } 780 781 @Override 782 public String toString() { 783 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 784 if (prefix) result += " [prefix]"; 785 return result; 786 } 787 788 public String toSafeString() { 789 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 790 if (prefix) result += " [prefix]"; 791 return result; 792 } 793 794 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 795 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 796 ContentProvider.getUriWithoutUserId(uri), false); 797 } 798 } 799 800 CoreSettingsObserver mCoreSettingsObserver; 801 802 /** 803 * Thread-local storage used to carry caller permissions over through 804 * indirect content-provider access. 805 */ 806 private class Identity { 807 public int pid; 808 public int uid; 809 810 Identity(int _pid, int _uid) { 811 pid = _pid; 812 uid = _uid; 813 } 814 } 815 816 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 817 818 /** 819 * All information we have collected about the runtime performance of 820 * any user id that can impact battery performance. 821 */ 822 final BatteryStatsService mBatteryStatsService; 823 824 /** 825 * Information about component usage 826 */ 827 final UsageStatsService mUsageStatsService; 828 829 /** 830 * Information about and control over application operations 831 */ 832 final AppOpsService mAppOpsService; 833 834 /** 835 * Save recent tasks information across reboots. 836 */ 837 final TaskPersister mTaskPersister; 838 839 /** 840 * Current configuration information. HistoryRecord objects are given 841 * a reference to this object to indicate which configuration they are 842 * currently running in, so this object must be kept immutable. 843 */ 844 Configuration mConfiguration = new Configuration(); 845 846 /** 847 * Current sequencing integer of the configuration, for skipping old 848 * configurations. 849 */ 850 int mConfigurationSeq = 0; 851 852 /** 853 * Hardware-reported OpenGLES version. 854 */ 855 final int GL_ES_VERSION; 856 857 /** 858 * List of initialization arguments to pass to all processes when binding applications to them. 859 * For example, references to the commonly used services. 860 */ 861 HashMap<String, IBinder> mAppBindArgs; 862 863 /** 864 * Temporary to avoid allocations. Protected by main lock. 865 */ 866 final StringBuilder mStringBuilder = new StringBuilder(256); 867 868 /** 869 * Used to control how we initialize the service. 870 */ 871 ComponentName mTopComponent; 872 String mTopAction = Intent.ACTION_MAIN; 873 String mTopData; 874 boolean mProcessesReady = false; 875 boolean mSystemReady = false; 876 boolean mBooting = false; 877 boolean mWaitingUpdate = false; 878 boolean mDidUpdate = false; 879 boolean mOnBattery = false; 880 boolean mLaunchWarningShown = false; 881 882 Context mContext; 883 884 int mFactoryTest; 885 886 boolean mCheckedForSetup; 887 888 /** 889 * The time at which we will allow normal application switches again, 890 * after a call to {@link #stopAppSwitches()}. 891 */ 892 long mAppSwitchesAllowedTime; 893 894 /** 895 * This is set to true after the first switch after mAppSwitchesAllowedTime 896 * is set; any switches after that will clear the time. 897 */ 898 boolean mDidAppSwitch; 899 900 /** 901 * Last time (in realtime) at which we checked for power usage. 902 */ 903 long mLastPowerCheckRealtime; 904 905 /** 906 * Last time (in uptime) at which we checked for power usage. 907 */ 908 long mLastPowerCheckUptime; 909 910 /** 911 * Set while we are wanting to sleep, to prevent any 912 * activities from being started/resumed. 913 */ 914 private boolean mSleeping = false; 915 916 /** 917 * Set while we are running a voice interaction. This overrides 918 * sleeping while it is active. 919 */ 920 private boolean mRunningVoice = false; 921 922 /** 923 * State of external calls telling us if the device is asleep. 924 */ 925 private boolean mWentToSleep = false; 926 927 /** 928 * State of external call telling us if the lock screen is shown. 929 */ 930 private boolean mLockScreenShown = false; 931 932 /** 933 * Set if we are shutting down the system, similar to sleeping. 934 */ 935 boolean mShuttingDown = false; 936 937 /** 938 * Current sequence id for oom_adj computation traversal. 939 */ 940 int mAdjSeq = 0; 941 942 /** 943 * Current sequence id for process LRU updating. 944 */ 945 int mLruSeq = 0; 946 947 /** 948 * Keep track of the non-cached/empty process we last found, to help 949 * determine how to distribute cached/empty processes next time. 950 */ 951 int mNumNonCachedProcs = 0; 952 953 /** 954 * Keep track of the number of cached hidden procs, to balance oom adj 955 * distribution between those and empty procs. 956 */ 957 int mNumCachedHiddenProcs = 0; 958 959 /** 960 * Keep track of the number of service processes we last found, to 961 * determine on the next iteration which should be B services. 962 */ 963 int mNumServiceProcs = 0; 964 int mNewNumAServiceProcs = 0; 965 int mNewNumServiceProcs = 0; 966 967 /** 968 * Allow the current computed overall memory level of the system to go down? 969 * This is set to false when we are killing processes for reasons other than 970 * memory management, so that the now smaller process list will not be taken as 971 * an indication that memory is tighter. 972 */ 973 boolean mAllowLowerMemLevel = false; 974 975 /** 976 * The last computed memory level, for holding when we are in a state that 977 * processes are going away for other reasons. 978 */ 979 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 980 981 /** 982 * The last total number of process we have, to determine if changes actually look 983 * like a shrinking number of process due to lower RAM. 984 */ 985 int mLastNumProcesses; 986 987 /** 988 * The uptime of the last time we performed idle maintenance. 989 */ 990 long mLastIdleTime = SystemClock.uptimeMillis(); 991 992 /** 993 * Total time spent with RAM that has been added in the past since the last idle time. 994 */ 995 long mLowRamTimeSinceLastIdle = 0; 996 997 /** 998 * If RAM is currently low, when that horrible situation started. 999 */ 1000 long mLowRamStartTime = 0; 1001 1002 /** 1003 * For reporting to battery stats the current top application. 1004 */ 1005 private String mCurResumedPackage = null; 1006 private int mCurResumedUid = -1; 1007 1008 /** 1009 * For reporting to battery stats the apps currently running foreground 1010 * service. The ProcessMap is package/uid tuples; each of these contain 1011 * an array of the currently foreground processes. 1012 */ 1013 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1014 = new ProcessMap<ArrayList<ProcessRecord>>(); 1015 1016 /** 1017 * This is set if we had to do a delayed dexopt of an app before launching 1018 * it, to increase the ANR timeouts in that case. 1019 */ 1020 boolean mDidDexOpt; 1021 1022 /** 1023 * Set if the systemServer made a call to enterSafeMode. 1024 */ 1025 boolean mSafeMode; 1026 1027 String mDebugApp = null; 1028 boolean mWaitForDebugger = false; 1029 boolean mDebugTransient = false; 1030 String mOrigDebugApp = null; 1031 boolean mOrigWaitForDebugger = false; 1032 boolean mAlwaysFinishActivities = false; 1033 IActivityController mController = null; 1034 String mProfileApp = null; 1035 ProcessRecord mProfileProc = null; 1036 String mProfileFile; 1037 ParcelFileDescriptor mProfileFd; 1038 int mProfileType = 0; 1039 boolean mAutoStopProfiler = false; 1040 String mOpenGlTraceApp = null; 1041 1042 static class ProcessChangeItem { 1043 static final int CHANGE_ACTIVITIES = 1<<0; 1044 static final int CHANGE_PROCESS_STATE = 1<<1; 1045 int changes; 1046 int uid; 1047 int pid; 1048 int processState; 1049 boolean foregroundActivities; 1050 } 1051 1052 final RemoteCallbackList<IProcessObserver> mProcessObservers 1053 = new RemoteCallbackList<IProcessObserver>(); 1054 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1055 1056 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1057 = new ArrayList<ProcessChangeItem>(); 1058 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1059 = new ArrayList<ProcessChangeItem>(); 1060 1061 /** 1062 * Runtime CPU use collection thread. This object's lock is used to 1063 * protect all related state. 1064 */ 1065 final Thread mProcessCpuThread; 1066 1067 /** 1068 * Used to collect process stats when showing not responding dialog. 1069 * Protected by mProcessCpuThread. 1070 */ 1071 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1072 MONITOR_THREAD_CPU_USAGE); 1073 final AtomicLong mLastCpuTime = new AtomicLong(0); 1074 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1075 1076 long mLastWriteTime = 0; 1077 1078 /** 1079 * Used to retain an update lock when the foreground activity is in 1080 * immersive mode. 1081 */ 1082 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1083 1084 /** 1085 * Set to true after the system has finished booting. 1086 */ 1087 boolean mBooted = false; 1088 1089 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1090 int mProcessLimitOverride = -1; 1091 1092 WindowManagerService mWindowManager; 1093 1094 final ActivityThread mSystemThread; 1095 1096 int mCurrentUserId = 0; 1097 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1098 private UserManagerService mUserManager; 1099 1100 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1101 final ProcessRecord mApp; 1102 final int mPid; 1103 final IApplicationThread mAppThread; 1104 1105 AppDeathRecipient(ProcessRecord app, int pid, 1106 IApplicationThread thread) { 1107 if (localLOGV) Slog.v( 1108 TAG, "New death recipient " + this 1109 + " for thread " + thread.asBinder()); 1110 mApp = app; 1111 mPid = pid; 1112 mAppThread = thread; 1113 } 1114 1115 @Override 1116 public void binderDied() { 1117 if (localLOGV) Slog.v( 1118 TAG, "Death received in " + this 1119 + " for thread " + mAppThread.asBinder()); 1120 synchronized(ActivityManagerService.this) { 1121 appDiedLocked(mApp, mPid, mAppThread); 1122 } 1123 } 1124 } 1125 1126 static final int SHOW_ERROR_MSG = 1; 1127 static final int SHOW_NOT_RESPONDING_MSG = 2; 1128 static final int SHOW_FACTORY_ERROR_MSG = 3; 1129 static final int UPDATE_CONFIGURATION_MSG = 4; 1130 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1131 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1132 static final int SERVICE_TIMEOUT_MSG = 12; 1133 static final int UPDATE_TIME_ZONE = 13; 1134 static final int SHOW_UID_ERROR_MSG = 14; 1135 static final int IM_FEELING_LUCKY_MSG = 15; 1136 static final int PROC_START_TIMEOUT_MSG = 20; 1137 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1138 static final int KILL_APPLICATION_MSG = 22; 1139 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1140 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1141 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1142 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1143 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1144 static final int CLEAR_DNS_CACHE_MSG = 28; 1145 static final int UPDATE_HTTP_PROXY_MSG = 29; 1146 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1147 static final int DISPATCH_PROCESSES_CHANGED = 31; 1148 static final int DISPATCH_PROCESS_DIED = 32; 1149 static final int REPORT_MEM_USAGE_MSG = 33; 1150 static final int REPORT_USER_SWITCH_MSG = 34; 1151 static final int CONTINUE_USER_SWITCH_MSG = 35; 1152 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1153 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1154 static final int PERSIST_URI_GRANTS_MSG = 38; 1155 static final int REQUEST_ALL_PSS_MSG = 39; 1156 static final int START_PROFILES_MSG = 40; 1157 static final int UPDATE_TIME = 41; 1158 static final int SYSTEM_USER_START_MSG = 42; 1159 static final int SYSTEM_USER_CURRENT_MSG = 43; 1160 1161 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1162 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1163 static final int FIRST_COMPAT_MODE_MSG = 300; 1164 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1165 1166 AlertDialog mUidAlert; 1167 CompatModeDialog mCompatModeDialog; 1168 long mLastMemUsageReportTime = 0; 1169 1170 private LockToAppRequestDialog mLockToAppRequest; 1171 1172 /** 1173 * Flag whether the current user is a "monkey", i.e. whether 1174 * the UI is driven by a UI automation tool. 1175 */ 1176 private boolean mUserIsMonkey; 1177 1178 final ServiceThread mHandlerThread; 1179 final MainHandler mHandler; 1180 1181 final class MainHandler extends Handler { 1182 public MainHandler(Looper looper) { 1183 super(looper, null, true); 1184 } 1185 1186 @Override 1187 public void handleMessage(Message msg) { 1188 switch (msg.what) { 1189 case SHOW_ERROR_MSG: { 1190 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1191 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1192 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1193 synchronized (ActivityManagerService.this) { 1194 ProcessRecord proc = (ProcessRecord)data.get("app"); 1195 AppErrorResult res = (AppErrorResult) data.get("result"); 1196 if (proc != null && proc.crashDialog != null) { 1197 Slog.e(TAG, "App already has crash dialog: " + proc); 1198 if (res != null) { 1199 res.set(0); 1200 } 1201 return; 1202 } 1203 if (!showBackground && UserHandle.getAppId(proc.uid) 1204 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1205 && proc.pid != MY_PID) { 1206 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1207 if (res != null) { 1208 res.set(0); 1209 } 1210 return; 1211 } 1212 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1213 Dialog d = new AppErrorDialog(mContext, 1214 ActivityManagerService.this, res, proc); 1215 d.show(); 1216 proc.crashDialog = d; 1217 } else { 1218 // The device is asleep, so just pretend that the user 1219 // saw a crash dialog and hit "force quit". 1220 if (res != null) { 1221 res.set(0); 1222 } 1223 } 1224 } 1225 1226 ensureBootCompleted(); 1227 } break; 1228 case SHOW_NOT_RESPONDING_MSG: { 1229 synchronized (ActivityManagerService.this) { 1230 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1231 ProcessRecord proc = (ProcessRecord)data.get("app"); 1232 if (proc != null && proc.anrDialog != null) { 1233 Slog.e(TAG, "App already has anr dialog: " + proc); 1234 return; 1235 } 1236 1237 Intent intent = new Intent("android.intent.action.ANR"); 1238 if (!mProcessesReady) { 1239 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1240 | Intent.FLAG_RECEIVER_FOREGROUND); 1241 } 1242 broadcastIntentLocked(null, null, intent, 1243 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1244 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1245 1246 if (mShowDialogs) { 1247 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1248 mContext, proc, (ActivityRecord)data.get("activity"), 1249 msg.arg1 != 0); 1250 d.show(); 1251 proc.anrDialog = d; 1252 } else { 1253 // Just kill the app if there is no dialog to be shown. 1254 killAppAtUsersRequest(proc, null); 1255 } 1256 } 1257 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1261 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1262 synchronized (ActivityManagerService.this) { 1263 ProcessRecord proc = (ProcessRecord) data.get("app"); 1264 if (proc == null) { 1265 Slog.e(TAG, "App not found when showing strict mode dialog."); 1266 break; 1267 } 1268 if (proc.crashDialog != null) { 1269 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1270 return; 1271 } 1272 AppErrorResult res = (AppErrorResult) data.get("result"); 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new StrictModeViolationDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 res.set(0); 1282 } 1283 } 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_FACTORY_ERROR_MSG: { 1287 Dialog d = new FactoryErrorDialog( 1288 mContext, msg.getData().getCharSequence("msg")); 1289 d.show(); 1290 ensureBootCompleted(); 1291 } break; 1292 case UPDATE_CONFIGURATION_MSG: { 1293 final ContentResolver resolver = mContext.getContentResolver(); 1294 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1295 } break; 1296 case GC_BACKGROUND_PROCESSES_MSG: { 1297 synchronized (ActivityManagerService.this) { 1298 performAppGcsIfAppropriateLocked(); 1299 } 1300 } break; 1301 case WAIT_FOR_DEBUGGER_MSG: { 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord app = (ProcessRecord)msg.obj; 1304 if (msg.arg1 != 0) { 1305 if (!app.waitedForDebugger) { 1306 Dialog d = new AppWaitingForDebuggerDialog( 1307 ActivityManagerService.this, 1308 mContext, app); 1309 app.waitDialog = d; 1310 app.waitedForDebugger = true; 1311 d.show(); 1312 } 1313 } else { 1314 if (app.waitDialog != null) { 1315 app.waitDialog.dismiss(); 1316 app.waitDialog = null; 1317 } 1318 } 1319 } 1320 } break; 1321 case SERVICE_TIMEOUT_MSG: { 1322 if (mDidDexOpt) { 1323 mDidDexOpt = false; 1324 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1325 nmsg.obj = msg.obj; 1326 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1327 return; 1328 } 1329 mServices.serviceTimeout((ProcessRecord)msg.obj); 1330 } break; 1331 case UPDATE_TIME_ZONE: { 1332 synchronized (ActivityManagerService.this) { 1333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1334 ProcessRecord r = mLruProcesses.get(i); 1335 if (r.thread != null) { 1336 try { 1337 r.thread.updateTimeZone(); 1338 } catch (RemoteException ex) { 1339 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1340 } 1341 } 1342 } 1343 } 1344 } break; 1345 case CLEAR_DNS_CACHE_MSG: { 1346 synchronized (ActivityManagerService.this) { 1347 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1348 ProcessRecord r = mLruProcesses.get(i); 1349 if (r.thread != null) { 1350 try { 1351 r.thread.clearDnsCache(); 1352 } catch (RemoteException ex) { 1353 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1354 } 1355 } 1356 } 1357 } 1358 } break; 1359 case UPDATE_HTTP_PROXY_MSG: { 1360 ProxyInfo proxy = (ProxyInfo)msg.obj; 1361 String host = ""; 1362 String port = ""; 1363 String exclList = ""; 1364 Uri pacFileUrl = Uri.EMPTY; 1365 if (proxy != null) { 1366 host = proxy.getHost(); 1367 port = Integer.toString(proxy.getPort()); 1368 exclList = proxy.getExclusionListAsString(); 1369 pacFileUrl = proxy.getPacFileUrl(); 1370 } 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update http proxy for: " + 1379 r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case SHOW_UID_ERROR_MSG: { 1386 String title = "System UIDs Inconsistent"; 1387 String text = "UIDs on the system are inconsistent, you need to wipe your" 1388 + " data partition or your device will be unstable."; 1389 Log.e(TAG, title + ": " + text); 1390 if (mShowDialogs) { 1391 // XXX This is a temporary dialog, no need to localize. 1392 AlertDialog d = new BaseErrorDialog(mContext); 1393 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1394 d.setCancelable(false); 1395 d.setTitle(title); 1396 d.setMessage(text); 1397 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1398 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1399 mUidAlert = d; 1400 d.show(); 1401 } 1402 } break; 1403 case IM_FEELING_LUCKY_MSG: { 1404 if (mUidAlert != null) { 1405 mUidAlert.dismiss(); 1406 mUidAlert = null; 1407 } 1408 } break; 1409 case PROC_START_TIMEOUT_MSG: { 1410 if (mDidDexOpt) { 1411 mDidDexOpt = false; 1412 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1413 nmsg.obj = msg.obj; 1414 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1415 return; 1416 } 1417 ProcessRecord app = (ProcessRecord)msg.obj; 1418 synchronized (ActivityManagerService.this) { 1419 processStartTimedOutLocked(app); 1420 } 1421 } break; 1422 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 doPendingActivityLaunchesLocked(true); 1425 } 1426 } break; 1427 case KILL_APPLICATION_MSG: { 1428 synchronized (ActivityManagerService.this) { 1429 int appid = msg.arg1; 1430 boolean restart = (msg.arg2 == 1); 1431 Bundle bundle = (Bundle)msg.obj; 1432 String pkg = bundle.getString("pkg"); 1433 String reason = bundle.getString("reason"); 1434 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1435 false, UserHandle.USER_ALL, reason); 1436 } 1437 } break; 1438 case FINALIZE_PENDING_INTENT_MSG: { 1439 ((PendingIntentRecord)msg.obj).completeFinalize(); 1440 } break; 1441 case POST_HEAVY_NOTIFICATION_MSG: { 1442 INotificationManager inm = NotificationManager.getService(); 1443 if (inm == null) { 1444 return; 1445 } 1446 1447 ActivityRecord root = (ActivityRecord)msg.obj; 1448 ProcessRecord process = root.app; 1449 if (process == null) { 1450 return; 1451 } 1452 1453 try { 1454 Context context = mContext.createPackageContext(process.info.packageName, 0); 1455 String text = mContext.getString(R.string.heavy_weight_notification, 1456 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1457 Notification notification = new Notification(); 1458 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1459 notification.when = 0; 1460 notification.flags = Notification.FLAG_ONGOING_EVENT; 1461 notification.tickerText = text; 1462 notification.defaults = 0; // please be quiet 1463 notification.sound = null; 1464 notification.vibrate = null; 1465 notification.setLatestEventInfo(context, text, 1466 mContext.getText(R.string.heavy_weight_notification_detail), 1467 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1468 PendingIntent.FLAG_CANCEL_CURRENT, null, 1469 new UserHandle(root.userId))); 1470 1471 try { 1472 int[] outId = new int[1]; 1473 inm.enqueueNotificationWithTag("android", "android", null, 1474 R.string.heavy_weight_notification, 1475 notification, outId, root.userId); 1476 } catch (RuntimeException e) { 1477 Slog.w(ActivityManagerService.TAG, 1478 "Error showing notification for heavy-weight app", e); 1479 } catch (RemoteException e) { 1480 } 1481 } catch (NameNotFoundException e) { 1482 Slog.w(TAG, "Unable to create context for heavy notification", e); 1483 } 1484 } break; 1485 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1486 INotificationManager inm = NotificationManager.getService(); 1487 if (inm == null) { 1488 return; 1489 } 1490 try { 1491 inm.cancelNotificationWithTag("android", null, 1492 R.string.heavy_weight_notification, msg.arg1); 1493 } catch (RuntimeException e) { 1494 Slog.w(ActivityManagerService.TAG, 1495 "Error canceling notification for service", e); 1496 } catch (RemoteException e) { 1497 } 1498 } break; 1499 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1500 synchronized (ActivityManagerService.this) { 1501 checkExcessivePowerUsageLocked(true); 1502 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1503 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1504 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1505 } 1506 } break; 1507 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1508 synchronized (ActivityManagerService.this) { 1509 ActivityRecord ar = (ActivityRecord)msg.obj; 1510 if (mCompatModeDialog != null) { 1511 if (mCompatModeDialog.mAppInfo.packageName.equals( 1512 ar.info.applicationInfo.packageName)) { 1513 return; 1514 } 1515 mCompatModeDialog.dismiss(); 1516 mCompatModeDialog = null; 1517 } 1518 if (ar != null && false) { 1519 if (mCompatModePackages.getPackageAskCompatModeLocked( 1520 ar.packageName)) { 1521 int mode = mCompatModePackages.computeCompatModeLocked( 1522 ar.info.applicationInfo); 1523 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1524 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1525 mCompatModeDialog = new CompatModeDialog( 1526 ActivityManagerService.this, mContext, 1527 ar.info.applicationInfo); 1528 mCompatModeDialog.show(); 1529 } 1530 } 1531 } 1532 } 1533 break; 1534 } 1535 case DISPATCH_PROCESSES_CHANGED: { 1536 dispatchProcessesChanged(); 1537 break; 1538 } 1539 case DISPATCH_PROCESS_DIED: { 1540 final int pid = msg.arg1; 1541 final int uid = msg.arg2; 1542 dispatchProcessDied(pid, uid); 1543 break; 1544 } 1545 case REPORT_MEM_USAGE_MSG: { 1546 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1547 Thread thread = new Thread() { 1548 @Override public void run() { 1549 final SparseArray<ProcessMemInfo> infoMap 1550 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1551 for (int i=0, N=memInfos.size(); i<N; i++) { 1552 ProcessMemInfo mi = memInfos.get(i); 1553 infoMap.put(mi.pid, mi); 1554 } 1555 updateCpuStatsNow(); 1556 synchronized (mProcessCpuThread) { 1557 final int N = mProcessCpuTracker.countStats(); 1558 for (int i=0; i<N; i++) { 1559 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1560 if (st.vsize > 0) { 1561 long pss = Debug.getPss(st.pid, null); 1562 if (pss > 0) { 1563 if (infoMap.indexOfKey(st.pid) < 0) { 1564 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1565 ProcessList.NATIVE_ADJ, -1, "native", null); 1566 mi.pss = pss; 1567 memInfos.add(mi); 1568 } 1569 } 1570 } 1571 } 1572 } 1573 1574 long totalPss = 0; 1575 for (int i=0, N=memInfos.size(); i<N; i++) { 1576 ProcessMemInfo mi = memInfos.get(i); 1577 if (mi.pss == 0) { 1578 mi.pss = Debug.getPss(mi.pid, null); 1579 } 1580 totalPss += mi.pss; 1581 } 1582 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1583 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1584 if (lhs.oomAdj != rhs.oomAdj) { 1585 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1586 } 1587 if (lhs.pss != rhs.pss) { 1588 return lhs.pss < rhs.pss ? 1 : -1; 1589 } 1590 return 0; 1591 } 1592 }); 1593 1594 StringBuilder tag = new StringBuilder(128); 1595 StringBuilder stack = new StringBuilder(128); 1596 tag.append("Low on memory -- "); 1597 appendMemBucket(tag, totalPss, "total", false); 1598 appendMemBucket(stack, totalPss, "total", true); 1599 1600 StringBuilder logBuilder = new StringBuilder(1024); 1601 logBuilder.append("Low on memory:\n"); 1602 1603 boolean firstLine = true; 1604 int lastOomAdj = Integer.MIN_VALUE; 1605 for (int i=0, N=memInfos.size(); i<N; i++) { 1606 ProcessMemInfo mi = memInfos.get(i); 1607 1608 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1609 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1610 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1611 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1612 if (lastOomAdj != mi.oomAdj) { 1613 lastOomAdj = mi.oomAdj; 1614 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1615 tag.append(" / "); 1616 } 1617 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1618 if (firstLine) { 1619 stack.append(":"); 1620 firstLine = false; 1621 } 1622 stack.append("\n\t at "); 1623 } else { 1624 stack.append("$"); 1625 } 1626 } else { 1627 tag.append(" "); 1628 stack.append("$"); 1629 } 1630 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1631 appendMemBucket(tag, mi.pss, mi.name, false); 1632 } 1633 appendMemBucket(stack, mi.pss, mi.name, true); 1634 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1635 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1636 stack.append("("); 1637 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1638 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1639 stack.append(DUMP_MEM_OOM_LABEL[k]); 1640 stack.append(":"); 1641 stack.append(DUMP_MEM_OOM_ADJ[k]); 1642 } 1643 } 1644 stack.append(")"); 1645 } 1646 } 1647 1648 logBuilder.append(" "); 1649 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1650 logBuilder.append(' '); 1651 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1652 logBuilder.append(' '); 1653 ProcessList.appendRamKb(logBuilder, mi.pss); 1654 logBuilder.append(" kB: "); 1655 logBuilder.append(mi.name); 1656 logBuilder.append(" ("); 1657 logBuilder.append(mi.pid); 1658 logBuilder.append(") "); 1659 logBuilder.append(mi.adjType); 1660 logBuilder.append('\n'); 1661 if (mi.adjReason != null) { 1662 logBuilder.append(" "); 1663 logBuilder.append(mi.adjReason); 1664 logBuilder.append('\n'); 1665 } 1666 } 1667 1668 logBuilder.append(" "); 1669 ProcessList.appendRamKb(logBuilder, totalPss); 1670 logBuilder.append(" kB: TOTAL\n"); 1671 1672 long[] infos = new long[Debug.MEMINFO_COUNT]; 1673 Debug.getMemInfo(infos); 1674 logBuilder.append(" MemInfo: "); 1675 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1676 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1677 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1678 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1679 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1680 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1681 logBuilder.append(" ZRAM: "); 1682 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1683 logBuilder.append(" kB RAM, "); 1684 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1685 logBuilder.append(" kB swap total, "); 1686 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1687 logBuilder.append(" kB swap free\n"); 1688 } 1689 Slog.i(TAG, logBuilder.toString()); 1690 1691 StringBuilder dropBuilder = new StringBuilder(1024); 1692 /* 1693 StringWriter oomSw = new StringWriter(); 1694 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1695 StringWriter catSw = new StringWriter(); 1696 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1697 String[] emptyArgs = new String[] { }; 1698 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1699 oomPw.flush(); 1700 String oomString = oomSw.toString(); 1701 */ 1702 dropBuilder.append(stack); 1703 dropBuilder.append('\n'); 1704 dropBuilder.append('\n'); 1705 dropBuilder.append(logBuilder); 1706 dropBuilder.append('\n'); 1707 /* 1708 dropBuilder.append(oomString); 1709 dropBuilder.append('\n'); 1710 */ 1711 StringWriter catSw = new StringWriter(); 1712 synchronized (ActivityManagerService.this) { 1713 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1714 String[] emptyArgs = new String[] { }; 1715 catPw.println(); 1716 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1717 catPw.println(); 1718 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1719 false, false, null); 1720 catPw.println(); 1721 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1722 catPw.flush(); 1723 } 1724 dropBuilder.append(catSw.toString()); 1725 addErrorToDropBox("lowmem", null, "system_server", null, 1726 null, tag.toString(), dropBuilder.toString(), null, null); 1727 //Slog.i(TAG, "Sent to dropbox:"); 1728 //Slog.i(TAG, dropBuilder.toString()); 1729 synchronized (ActivityManagerService.this) { 1730 long now = SystemClock.uptimeMillis(); 1731 if (mLastMemUsageReportTime < now) { 1732 mLastMemUsageReportTime = now; 1733 } 1734 } 1735 } 1736 }; 1737 thread.start(); 1738 break; 1739 } 1740 case REPORT_USER_SWITCH_MSG: { 1741 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1742 break; 1743 } 1744 case CONTINUE_USER_SWITCH_MSG: { 1745 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1746 break; 1747 } 1748 case USER_SWITCH_TIMEOUT_MSG: { 1749 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1750 break; 1751 } 1752 case IMMERSIVE_MODE_LOCK_MSG: { 1753 final boolean nextState = (msg.arg1 != 0); 1754 if (mUpdateLock.isHeld() != nextState) { 1755 if (DEBUG_IMMERSIVE) { 1756 final ActivityRecord r = (ActivityRecord) msg.obj; 1757 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1758 } 1759 if (nextState) { 1760 mUpdateLock.acquire(); 1761 } else { 1762 mUpdateLock.release(); 1763 } 1764 } 1765 break; 1766 } 1767 case PERSIST_URI_GRANTS_MSG: { 1768 writeGrantedUriPermissions(); 1769 break; 1770 } 1771 case REQUEST_ALL_PSS_MSG: { 1772 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1773 break; 1774 } 1775 case START_PROFILES_MSG: { 1776 synchronized (ActivityManagerService.this) { 1777 startProfilesLocked(); 1778 } 1779 break; 1780 } 1781 case UPDATE_TIME: { 1782 synchronized (ActivityManagerService.this) { 1783 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1784 ProcessRecord r = mLruProcesses.get(i); 1785 if (r.thread != null) { 1786 try { 1787 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1788 } catch (RemoteException ex) { 1789 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1790 } 1791 } 1792 } 1793 } 1794 break; 1795 } 1796 case SYSTEM_USER_START_MSG: { 1797 mSystemServiceManager.startUser(msg.arg1); 1798 break; 1799 } 1800 case SYSTEM_USER_CURRENT_MSG: { 1801 mSystemServiceManager.switchUser(msg.arg1); 1802 break; 1803 } 1804 } 1805 } 1806 }; 1807 1808 static final int COLLECT_PSS_BG_MSG = 1; 1809 1810 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1811 @Override 1812 public void handleMessage(Message msg) { 1813 switch (msg.what) { 1814 case COLLECT_PSS_BG_MSG: { 1815 long start = SystemClock.uptimeMillis(); 1816 MemInfoReader memInfo = null; 1817 synchronized (ActivityManagerService.this) { 1818 if (mFullPssPending) { 1819 mFullPssPending = false; 1820 memInfo = new MemInfoReader(); 1821 } 1822 } 1823 if (memInfo != null) { 1824 updateCpuStatsNow(); 1825 long nativeTotalPss = 0; 1826 synchronized (mProcessCpuThread) { 1827 final int N = mProcessCpuTracker.countStats(); 1828 for (int j=0; j<N; j++) { 1829 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1830 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1831 // This is definitely an application process; skip it. 1832 continue; 1833 } 1834 synchronized (mPidsSelfLocked) { 1835 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1836 // This is one of our own processes; skip it. 1837 continue; 1838 } 1839 } 1840 nativeTotalPss += Debug.getPss(st.pid, null); 1841 } 1842 } 1843 memInfo.readMemInfo(); 1844 synchronized (this) { 1845 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1846 + (SystemClock.uptimeMillis()-start) + "ms"); 1847 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1848 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1849 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1850 +memInfo.getSlabSizeKb(), 1851 nativeTotalPss); 1852 } 1853 } 1854 1855 int i=0, num=0; 1856 long[] tmp = new long[1]; 1857 do { 1858 ProcessRecord proc; 1859 int procState; 1860 int pid; 1861 synchronized (ActivityManagerService.this) { 1862 if (i >= mPendingPssProcesses.size()) { 1863 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1864 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1865 mPendingPssProcesses.clear(); 1866 return; 1867 } 1868 proc = mPendingPssProcesses.get(i); 1869 procState = proc.pssProcState; 1870 if (proc.thread != null && procState == proc.setProcState) { 1871 pid = proc.pid; 1872 } else { 1873 proc = null; 1874 pid = 0; 1875 } 1876 i++; 1877 } 1878 if (proc != null) { 1879 long pss = Debug.getPss(pid, tmp); 1880 synchronized (ActivityManagerService.this) { 1881 if (proc.thread != null && proc.setProcState == procState 1882 && proc.pid == pid) { 1883 num++; 1884 proc.lastPssTime = SystemClock.uptimeMillis(); 1885 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1886 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1887 + ": " + pss + " lastPss=" + proc.lastPss 1888 + " state=" + ProcessList.makeProcStateString(procState)); 1889 if (proc.initialIdlePss == 0) { 1890 proc.initialIdlePss = pss; 1891 } 1892 proc.lastPss = pss; 1893 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1894 proc.lastCachedPss = pss; 1895 } 1896 } 1897 } 1898 } 1899 } while (true); 1900 } 1901 } 1902 } 1903 }; 1904 1905 /** 1906 * Monitor for package changes and update our internal state. 1907 */ 1908 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1909 @Override 1910 public void onPackageRemoved(String packageName, int uid) { 1911 // Remove all tasks with activities in the specified package from the list of recent tasks 1912 synchronized (ActivityManagerService.this) { 1913 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1914 TaskRecord tr = mRecentTasks.get(i); 1915 ComponentName cn = tr.intent.getComponent(); 1916 if (cn != null && cn.getPackageName().equals(packageName)) { 1917 // If the package name matches, remove the task and kill the process 1918 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1919 } 1920 } 1921 } 1922 } 1923 1924 @Override 1925 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1926 onPackageModified(packageName); 1927 return true; 1928 } 1929 1930 @Override 1931 public void onPackageModified(String packageName) { 1932 final PackageManager pm = mContext.getPackageManager(); 1933 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1934 new ArrayList<Pair<Intent, Integer>>(); 1935 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1936 // Copy the list of recent tasks so that we don't hold onto the lock on 1937 // ActivityManagerService for long periods while checking if components exist. 1938 synchronized (ActivityManagerService.this) { 1939 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1940 TaskRecord tr = mRecentTasks.get(i); 1941 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1942 } 1943 } 1944 // Check the recent tasks and filter out all tasks with components that no longer exist. 1945 Intent tmpI = new Intent(); 1946 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1947 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1948 ComponentName cn = p.first.getComponent(); 1949 if (cn != null && cn.getPackageName().equals(packageName)) { 1950 try { 1951 // Add the task to the list to remove if the component no longer exists 1952 tmpI.setComponent(cn); 1953 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1954 tasksToRemove.add(p.second); 1955 } 1956 } catch (Exception e) {} 1957 } 1958 } 1959 // Prune all the tasks with removed components from the list of recent tasks 1960 synchronized (ActivityManagerService.this) { 1961 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1962 // Remove the task but don't kill the process (since other components in that 1963 // package may still be running and in the background) 1964 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1965 } 1966 } 1967 } 1968 1969 @Override 1970 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1971 // Force stop the specified packages 1972 if (packages != null) { 1973 for (String pkg : packages) { 1974 synchronized (ActivityManagerService.this) { 1975 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1976 "finished booting")) { 1977 return true; 1978 } 1979 } 1980 } 1981 } 1982 return false; 1983 } 1984 }; 1985 1986 public void setSystemProcess() { 1987 try { 1988 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1989 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1990 ServiceManager.addService("meminfo", new MemBinder(this)); 1991 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1992 ServiceManager.addService("dbinfo", new DbBinder(this)); 1993 if (MONITOR_CPU_USAGE) { 1994 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1995 } 1996 ServiceManager.addService("permission", new PermissionController(this)); 1997 1998 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1999 "android", STOCK_PM_FLAGS); 2000 mSystemThread.installSystemApplicationInfo(info); 2001 2002 synchronized (this) { 2003 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2004 app.persistent = true; 2005 app.pid = MY_PID; 2006 app.maxAdj = ProcessList.SYSTEM_ADJ; 2007 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2008 mProcessNames.put(app.processName, app.uid, app); 2009 synchronized (mPidsSelfLocked) { 2010 mPidsSelfLocked.put(app.pid, app); 2011 } 2012 updateLruProcessLocked(app, false, null); 2013 updateOomAdjLocked(); 2014 } 2015 } catch (PackageManager.NameNotFoundException e) { 2016 throw new RuntimeException( 2017 "Unable to find android system package", e); 2018 } 2019 } 2020 2021 public void setWindowManager(WindowManagerService wm) { 2022 mWindowManager = wm; 2023 mStackSupervisor.setWindowManager(wm); 2024 } 2025 2026 public void startObservingNativeCrashes() { 2027 final NativeCrashListener ncl = new NativeCrashListener(this); 2028 ncl.start(); 2029 } 2030 2031 public IAppOpsService getAppOpsService() { 2032 return mAppOpsService; 2033 } 2034 2035 static class MemBinder extends Binder { 2036 ActivityManagerService mActivityManagerService; 2037 MemBinder(ActivityManagerService activityManagerService) { 2038 mActivityManagerService = activityManagerService; 2039 } 2040 2041 @Override 2042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2043 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2044 != PackageManager.PERMISSION_GRANTED) { 2045 pw.println("Permission Denial: can't dump meminfo from from pid=" 2046 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2047 + " without permission " + android.Manifest.permission.DUMP); 2048 return; 2049 } 2050 2051 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2052 } 2053 } 2054 2055 static class GraphicsBinder extends Binder { 2056 ActivityManagerService mActivityManagerService; 2057 GraphicsBinder(ActivityManagerService activityManagerService) { 2058 mActivityManagerService = activityManagerService; 2059 } 2060 2061 @Override 2062 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2063 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2064 != PackageManager.PERMISSION_GRANTED) { 2065 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2066 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2067 + " without permission " + android.Manifest.permission.DUMP); 2068 return; 2069 } 2070 2071 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2072 } 2073 } 2074 2075 static class DbBinder extends Binder { 2076 ActivityManagerService mActivityManagerService; 2077 DbBinder(ActivityManagerService activityManagerService) { 2078 mActivityManagerService = activityManagerService; 2079 } 2080 2081 @Override 2082 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2083 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2084 != PackageManager.PERMISSION_GRANTED) { 2085 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2086 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2087 + " without permission " + android.Manifest.permission.DUMP); 2088 return; 2089 } 2090 2091 mActivityManagerService.dumpDbInfo(fd, pw, args); 2092 } 2093 } 2094 2095 static class CpuBinder extends Binder { 2096 ActivityManagerService mActivityManagerService; 2097 CpuBinder(ActivityManagerService activityManagerService) { 2098 mActivityManagerService = activityManagerService; 2099 } 2100 2101 @Override 2102 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2103 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2104 != PackageManager.PERMISSION_GRANTED) { 2105 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2106 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2107 + " without permission " + android.Manifest.permission.DUMP); 2108 return; 2109 } 2110 2111 synchronized (mActivityManagerService.mProcessCpuThread) { 2112 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2113 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2114 SystemClock.uptimeMillis())); 2115 } 2116 } 2117 } 2118 2119 public static final class Lifecycle extends SystemService { 2120 private final ActivityManagerService mService; 2121 2122 public Lifecycle(Context context) { 2123 super(context); 2124 mService = new ActivityManagerService(context); 2125 } 2126 2127 @Override 2128 public void onStart() { 2129 mService.start(); 2130 } 2131 2132 public ActivityManagerService getService() { 2133 return mService; 2134 } 2135 } 2136 2137 // Note: This method is invoked on the main thread but may need to attach various 2138 // handlers to other threads. So take care to be explicit about the looper. 2139 public ActivityManagerService(Context systemContext) { 2140 mContext = systemContext; 2141 mFactoryTest = FactoryTest.getMode(); 2142 mSystemThread = ActivityThread.currentActivityThread(); 2143 2144 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2145 2146 mHandlerThread = new ServiceThread(TAG, 2147 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2148 mHandlerThread.start(); 2149 mHandler = new MainHandler(mHandlerThread.getLooper()); 2150 2151 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2152 "foreground", BROADCAST_FG_TIMEOUT, false); 2153 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2154 "background", BROADCAST_BG_TIMEOUT, true); 2155 mBroadcastQueues[0] = mFgBroadcastQueue; 2156 mBroadcastQueues[1] = mBgBroadcastQueue; 2157 2158 mServices = new ActiveServices(this); 2159 mProviderMap = new ProviderMap(this); 2160 2161 // TODO: Move creation of battery stats service outside of activity manager service. 2162 File dataDir = Environment.getDataDirectory(); 2163 File systemDir = new File(dataDir, "system"); 2164 systemDir.mkdirs(); 2165 mBatteryStatsService = new BatteryStatsService(new File( 2166 systemDir, "batterystats.bin").toString(), mHandler); 2167 mBatteryStatsService.getActiveStatistics().readLocked(); 2168 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2169 mOnBattery = DEBUG_POWER ? true 2170 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2171 mBatteryStatsService.getActiveStatistics().setCallback(this); 2172 2173 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2174 2175 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2176 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2177 2178 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2179 2180 // User 0 is the first and only user that runs at boot. 2181 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2182 mUserLru.add(Integer.valueOf(0)); 2183 updateStartedUserArrayLocked(); 2184 2185 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2186 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2187 2188 mConfiguration.setToDefaults(); 2189 mConfiguration.setLocale(Locale.getDefault()); 2190 2191 mConfigurationSeq = mConfiguration.seq = 1; 2192 mProcessCpuTracker.init(); 2193 2194 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2195 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2196 mStackSupervisor = new ActivityStackSupervisor(this); 2197 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2198 2199 mProcessCpuThread = new Thread("CpuTracker") { 2200 @Override 2201 public void run() { 2202 while (true) { 2203 try { 2204 try { 2205 synchronized(this) { 2206 final long now = SystemClock.uptimeMillis(); 2207 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2208 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2209 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2210 // + ", write delay=" + nextWriteDelay); 2211 if (nextWriteDelay < nextCpuDelay) { 2212 nextCpuDelay = nextWriteDelay; 2213 } 2214 if (nextCpuDelay > 0) { 2215 mProcessCpuMutexFree.set(true); 2216 this.wait(nextCpuDelay); 2217 } 2218 } 2219 } catch (InterruptedException e) { 2220 } 2221 updateCpuStatsNow(); 2222 } catch (Exception e) { 2223 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2224 } 2225 } 2226 } 2227 }; 2228 2229 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2230 2231 Watchdog.getInstance().addMonitor(this); 2232 Watchdog.getInstance().addThread(mHandler); 2233 } 2234 2235 public void setSystemServiceManager(SystemServiceManager mgr) { 2236 mSystemServiceManager = mgr; 2237 } 2238 2239 private void start() { 2240 mProcessCpuThread.start(); 2241 2242 mBatteryStatsService.publish(mContext); 2243 mUsageStatsService.publish(mContext); 2244 mAppOpsService.publish(mContext); 2245 Slog.d("AppOps", "AppOpsService published"); 2246 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2247 } 2248 2249 public void initPowerManagement() { 2250 mStackSupervisor.initPowerManagement(); 2251 mBatteryStatsService.initPowerManagement(); 2252 } 2253 2254 @Override 2255 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2256 throws RemoteException { 2257 if (code == SYSPROPS_TRANSACTION) { 2258 // We need to tell all apps about the system property change. 2259 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2260 synchronized(this) { 2261 final int NP = mProcessNames.getMap().size(); 2262 for (int ip=0; ip<NP; ip++) { 2263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2264 final int NA = apps.size(); 2265 for (int ia=0; ia<NA; ia++) { 2266 ProcessRecord app = apps.valueAt(ia); 2267 if (app.thread != null) { 2268 procs.add(app.thread.asBinder()); 2269 } 2270 } 2271 } 2272 } 2273 2274 int N = procs.size(); 2275 for (int i=0; i<N; i++) { 2276 Parcel data2 = Parcel.obtain(); 2277 try { 2278 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2279 } catch (RemoteException e) { 2280 } 2281 data2.recycle(); 2282 } 2283 } 2284 try { 2285 return super.onTransact(code, data, reply, flags); 2286 } catch (RuntimeException e) { 2287 // The activity manager only throws security exceptions, so let's 2288 // log all others. 2289 if (!(e instanceof SecurityException)) { 2290 Slog.wtf(TAG, "Activity Manager Crash", e); 2291 } 2292 throw e; 2293 } 2294 } 2295 2296 void updateCpuStats() { 2297 final long now = SystemClock.uptimeMillis(); 2298 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2299 return; 2300 } 2301 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2302 synchronized (mProcessCpuThread) { 2303 mProcessCpuThread.notify(); 2304 } 2305 } 2306 } 2307 2308 void updateCpuStatsNow() { 2309 synchronized (mProcessCpuThread) { 2310 mProcessCpuMutexFree.set(false); 2311 final long now = SystemClock.uptimeMillis(); 2312 boolean haveNewCpuStats = false; 2313 2314 if (MONITOR_CPU_USAGE && 2315 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2316 mLastCpuTime.set(now); 2317 haveNewCpuStats = true; 2318 mProcessCpuTracker.update(); 2319 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2320 //Slog.i(TAG, "Total CPU usage: " 2321 // + mProcessCpu.getTotalCpuPercent() + "%"); 2322 2323 // Slog the cpu usage if the property is set. 2324 if ("true".equals(SystemProperties.get("events.cpu"))) { 2325 int user = mProcessCpuTracker.getLastUserTime(); 2326 int system = mProcessCpuTracker.getLastSystemTime(); 2327 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2328 int irq = mProcessCpuTracker.getLastIrqTime(); 2329 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2330 int idle = mProcessCpuTracker.getLastIdleTime(); 2331 2332 int total = user + system + iowait + irq + softIrq + idle; 2333 if (total == 0) total = 1; 2334 2335 EventLog.writeEvent(EventLogTags.CPU, 2336 ((user+system+iowait+irq+softIrq) * 100) / total, 2337 (user * 100) / total, 2338 (system * 100) / total, 2339 (iowait * 100) / total, 2340 (irq * 100) / total, 2341 (softIrq * 100) / total); 2342 } 2343 } 2344 2345 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2346 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2347 synchronized(bstats) { 2348 synchronized(mPidsSelfLocked) { 2349 if (haveNewCpuStats) { 2350 if (mOnBattery) { 2351 int perc = bstats.startAddingCpuLocked(); 2352 int totalUTime = 0; 2353 int totalSTime = 0; 2354 final int N = mProcessCpuTracker.countStats(); 2355 for (int i=0; i<N; i++) { 2356 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2357 if (!st.working) { 2358 continue; 2359 } 2360 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2361 int otherUTime = (st.rel_utime*perc)/100; 2362 int otherSTime = (st.rel_stime*perc)/100; 2363 totalUTime += otherUTime; 2364 totalSTime += otherSTime; 2365 if (pr != null) { 2366 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2367 if (ps == null || !ps.isActive()) { 2368 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2369 pr.info.uid, pr.processName); 2370 } 2371 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2372 st.rel_stime-otherSTime); 2373 ps.addSpeedStepTimes(cpuSpeedTimes); 2374 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2375 } else { 2376 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2377 if (ps == null || !ps.isActive()) { 2378 st.batteryStats = ps = bstats.getProcessStatsLocked( 2379 bstats.mapUid(st.uid), st.name); 2380 } 2381 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2382 st.rel_stime-otherSTime); 2383 ps.addSpeedStepTimes(cpuSpeedTimes); 2384 } 2385 } 2386 bstats.finishAddingCpuLocked(perc, totalUTime, 2387 totalSTime, cpuSpeedTimes); 2388 } 2389 } 2390 } 2391 2392 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2393 mLastWriteTime = now; 2394 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2395 } 2396 } 2397 } 2398 } 2399 2400 @Override 2401 public void batteryNeedsCpuUpdate() { 2402 updateCpuStatsNow(); 2403 } 2404 2405 @Override 2406 public void batteryPowerChanged(boolean onBattery) { 2407 // When plugging in, update the CPU stats first before changing 2408 // the plug state. 2409 updateCpuStatsNow(); 2410 synchronized (this) { 2411 synchronized(mPidsSelfLocked) { 2412 mOnBattery = DEBUG_POWER ? true : onBattery; 2413 } 2414 } 2415 } 2416 2417 /** 2418 * Initialize the application bind args. These are passed to each 2419 * process when the bindApplication() IPC is sent to the process. They're 2420 * lazily setup to make sure the services are running when they're asked for. 2421 */ 2422 private HashMap<String, IBinder> getCommonServicesLocked() { 2423 if (mAppBindArgs == null) { 2424 mAppBindArgs = new HashMap<String, IBinder>(); 2425 2426 // Setup the application init args 2427 mAppBindArgs.put("package", ServiceManager.getService("package")); 2428 mAppBindArgs.put("window", ServiceManager.getService("window")); 2429 mAppBindArgs.put(Context.ALARM_SERVICE, 2430 ServiceManager.getService(Context.ALARM_SERVICE)); 2431 } 2432 return mAppBindArgs; 2433 } 2434 2435 final void setFocusedActivityLocked(ActivityRecord r) { 2436 if (mFocusedActivity != r) { 2437 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2438 mFocusedActivity = r; 2439 if (r.task != null && r.task.voiceInteractor != null) { 2440 startRunningVoiceLocked(); 2441 } else { 2442 finishRunningVoiceLocked(); 2443 } 2444 mStackSupervisor.setFocusedStack(r); 2445 if (r != null) { 2446 mWindowManager.setFocusedApp(r.appToken, true); 2447 } 2448 applyUpdateLockStateLocked(r); 2449 } 2450 } 2451 2452 final void clearFocusedActivity(ActivityRecord r) { 2453 if (mFocusedActivity == r) { 2454 mFocusedActivity = null; 2455 } 2456 } 2457 2458 @Override 2459 public void setFocusedStack(int stackId) { 2460 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2461 synchronized (ActivityManagerService.this) { 2462 ActivityStack stack = mStackSupervisor.getStack(stackId); 2463 if (stack != null) { 2464 ActivityRecord r = stack.topRunningActivityLocked(null); 2465 if (r != null) { 2466 setFocusedActivityLocked(r); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void notifyActivityDrawn(IBinder token) { 2474 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2475 synchronized (this) { 2476 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2477 if (r != null) { 2478 r.task.stack.notifyActivityDrawnLocked(r); 2479 } 2480 } 2481 } 2482 2483 final void applyUpdateLockStateLocked(ActivityRecord r) { 2484 // Modifications to the UpdateLock state are done on our handler, outside 2485 // the activity manager's locks. The new state is determined based on the 2486 // state *now* of the relevant activity record. The object is passed to 2487 // the handler solely for logging detail, not to be consulted/modified. 2488 final boolean nextState = r != null && r.immersive; 2489 mHandler.sendMessage( 2490 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2491 } 2492 2493 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2494 Message msg = Message.obtain(); 2495 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2496 msg.obj = r.task.askedCompatMode ? null : r; 2497 mHandler.sendMessage(msg); 2498 } 2499 2500 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2501 String what, Object obj, ProcessRecord srcApp) { 2502 app.lastActivityTime = now; 2503 2504 if (app.activities.size() > 0) { 2505 // Don't want to touch dependent processes that are hosting activities. 2506 return index; 2507 } 2508 2509 int lrui = mLruProcesses.lastIndexOf(app); 2510 if (lrui < 0) { 2511 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2512 + what + " " + obj + " from " + srcApp); 2513 return index; 2514 } 2515 2516 if (lrui >= index) { 2517 // Don't want to cause this to move dependent processes *back* in the 2518 // list as if they were less frequently used. 2519 return index; 2520 } 2521 2522 if (lrui >= mLruProcessActivityStart) { 2523 // Don't want to touch dependent processes that are hosting activities. 2524 return index; 2525 } 2526 2527 mLruProcesses.remove(lrui); 2528 if (index > 0) { 2529 index--; 2530 } 2531 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2532 + " in LRU list: " + app); 2533 mLruProcesses.add(index, app); 2534 return index; 2535 } 2536 2537 final void removeLruProcessLocked(ProcessRecord app) { 2538 int lrui = mLruProcesses.lastIndexOf(app); 2539 if (lrui >= 0) { 2540 if (lrui <= mLruProcessActivityStart) { 2541 mLruProcessActivityStart--; 2542 } 2543 if (lrui <= mLruProcessServiceStart) { 2544 mLruProcessServiceStart--; 2545 } 2546 mLruProcesses.remove(lrui); 2547 } 2548 } 2549 2550 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2551 ProcessRecord client) { 2552 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2553 || app.treatLikeActivity; 2554 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2555 if (!activityChange && hasActivity) { 2556 // The process has activities, so we are only allowing activity-based adjustments 2557 // to move it. It should be kept in the front of the list with other 2558 // processes that have activities, and we don't want those to change their 2559 // order except due to activity operations. 2560 return; 2561 } 2562 2563 mLruSeq++; 2564 final long now = SystemClock.uptimeMillis(); 2565 app.lastActivityTime = now; 2566 2567 // First a quick reject: if the app is already at the position we will 2568 // put it, then there is nothing to do. 2569 if (hasActivity) { 2570 final int N = mLruProcesses.size(); 2571 if (N > 0 && mLruProcesses.get(N-1) == app) { 2572 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2573 return; 2574 } 2575 } else { 2576 if (mLruProcessServiceStart > 0 2577 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2579 return; 2580 } 2581 } 2582 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 2585 if (app.persistent && lrui >= 0) { 2586 // We don't care about the position of persistent processes, as long as 2587 // they are in the list. 2588 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2589 return; 2590 } 2591 2592 /* In progress: compute new position first, so we can avoid doing work 2593 if the process is not actually going to move. Not yet working. 2594 int addIndex; 2595 int nextIndex; 2596 boolean inActivity = false, inService = false; 2597 if (hasActivity) { 2598 // Process has activities, put it at the very tipsy-top. 2599 addIndex = mLruProcesses.size(); 2600 nextIndex = mLruProcessServiceStart; 2601 inActivity = true; 2602 } else if (hasService) { 2603 // Process has services, put it at the top of the service list. 2604 addIndex = mLruProcessActivityStart; 2605 nextIndex = mLruProcessServiceStart; 2606 inActivity = true; 2607 inService = true; 2608 } else { 2609 // Process not otherwise of interest, it goes to the top of the non-service area. 2610 addIndex = mLruProcessServiceStart; 2611 if (client != null) { 2612 int clientIndex = mLruProcesses.lastIndexOf(client); 2613 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2614 + app); 2615 if (clientIndex >= 0 && addIndex > clientIndex) { 2616 addIndex = clientIndex; 2617 } 2618 } 2619 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2620 } 2621 2622 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2623 + mLruProcessActivityStart + "): " + app); 2624 */ 2625 2626 if (lrui >= 0) { 2627 if (lrui < mLruProcessActivityStart) { 2628 mLruProcessActivityStart--; 2629 } 2630 if (lrui < mLruProcessServiceStart) { 2631 mLruProcessServiceStart--; 2632 } 2633 /* 2634 if (addIndex > lrui) { 2635 addIndex--; 2636 } 2637 if (nextIndex > lrui) { 2638 nextIndex--; 2639 } 2640 */ 2641 mLruProcesses.remove(lrui); 2642 } 2643 2644 /* 2645 mLruProcesses.add(addIndex, app); 2646 if (inActivity) { 2647 mLruProcessActivityStart++; 2648 } 2649 if (inService) { 2650 mLruProcessActivityStart++; 2651 } 2652 */ 2653 2654 int nextIndex; 2655 if (hasActivity) { 2656 final int N = mLruProcesses.size(); 2657 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2658 // Process doesn't have activities, but has clients with 2659 // activities... move it up, but one below the top (the top 2660 // should always have a real activity). 2661 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2662 mLruProcesses.add(N-1, app); 2663 // To keep it from spamming the LRU list (by making a bunch of clients), 2664 // we will push down any other entries owned by the app. 2665 final int uid = app.info.uid; 2666 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2667 ProcessRecord subProc = mLruProcesses.get(i); 2668 if (subProc.info.uid == uid) { 2669 // We want to push this one down the list. If the process after 2670 // it is for the same uid, however, don't do so, because we don't 2671 // want them internally to be re-ordered. 2672 if (mLruProcesses.get(i-1).info.uid != uid) { 2673 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2674 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2675 ProcessRecord tmp = mLruProcesses.get(i); 2676 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2677 mLruProcesses.set(i-1, tmp); 2678 i--; 2679 } 2680 } else { 2681 // A gap, we can stop here. 2682 break; 2683 } 2684 } 2685 } else { 2686 // Process has activities, put it at the very tipsy-top. 2687 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2688 mLruProcesses.add(app); 2689 } 2690 nextIndex = mLruProcessServiceStart; 2691 } else if (hasService) { 2692 // Process has services, put it at the top of the service list. 2693 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2694 mLruProcesses.add(mLruProcessActivityStart, app); 2695 nextIndex = mLruProcessServiceStart; 2696 mLruProcessActivityStart++; 2697 } else { 2698 // Process not otherwise of interest, it goes to the top of the non-service area. 2699 int index = mLruProcessServiceStart; 2700 if (client != null) { 2701 // If there is a client, don't allow the process to be moved up higher 2702 // in the list than that client. 2703 int clientIndex = mLruProcesses.lastIndexOf(client); 2704 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2705 + " when updating " + app); 2706 if (clientIndex <= lrui) { 2707 // Don't allow the client index restriction to push it down farther in the 2708 // list than it already is. 2709 clientIndex = lrui; 2710 } 2711 if (clientIndex >= 0 && index > clientIndex) { 2712 index = clientIndex; 2713 } 2714 } 2715 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2716 mLruProcesses.add(index, app); 2717 nextIndex = index-1; 2718 mLruProcessActivityStart++; 2719 mLruProcessServiceStart++; 2720 } 2721 2722 // If the app is currently using a content provider or service, 2723 // bump those processes as well. 2724 for (int j=app.connections.size()-1; j>=0; j--) { 2725 ConnectionRecord cr = app.connections.valueAt(j); 2726 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2727 && cr.binding.service.app != null 2728 && cr.binding.service.app.lruSeq != mLruSeq 2729 && !cr.binding.service.app.persistent) { 2730 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2731 "service connection", cr, app); 2732 } 2733 } 2734 for (int j=app.conProviders.size()-1; j>=0; j--) { 2735 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2736 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2737 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2738 "provider reference", cpr, app); 2739 } 2740 } 2741 } 2742 2743 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2744 if (uid == Process.SYSTEM_UID) { 2745 // The system gets to run in any process. If there are multiple 2746 // processes with the same uid, just pick the first (this 2747 // should never happen). 2748 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2749 if (procs == null) return null; 2750 final int N = procs.size(); 2751 for (int i = 0; i < N; i++) { 2752 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2753 } 2754 } 2755 ProcessRecord proc = mProcessNames.get(processName, uid); 2756 if (false && proc != null && !keepIfLarge 2757 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2758 && proc.lastCachedPss >= 4000) { 2759 // Turn this condition on to cause killing to happen regularly, for testing. 2760 if (proc.baseProcessTracker != null) { 2761 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2762 } 2763 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2764 + "k from cached"); 2765 } else if (proc != null && !keepIfLarge 2766 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2767 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2768 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2769 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2770 if (proc.baseProcessTracker != null) { 2771 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2772 } 2773 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2774 + "k from cached"); 2775 } 2776 } 2777 return proc; 2778 } 2779 2780 void ensurePackageDexOpt(String packageName) { 2781 IPackageManager pm = AppGlobals.getPackageManager(); 2782 try { 2783 if (pm.performDexOpt(packageName)) { 2784 mDidDexOpt = true; 2785 } 2786 } catch (RemoteException e) { 2787 } 2788 } 2789 2790 boolean isNextTransitionForward() { 2791 int transit = mWindowManager.getPendingAppTransition(); 2792 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2793 || transit == AppTransition.TRANSIT_TASK_OPEN 2794 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2795 } 2796 2797 final ProcessRecord startProcessLocked(String processName, 2798 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2799 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2800 boolean isolated, boolean keepIfLarge) { 2801 ProcessRecord app; 2802 if (!isolated) { 2803 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2804 } else { 2805 // If this is an isolated process, it can't re-use an existing process. 2806 app = null; 2807 } 2808 // We don't have to do anything more if: 2809 // (1) There is an existing application record; and 2810 // (2) The caller doesn't think it is dead, OR there is no thread 2811 // object attached to it so we know it couldn't have crashed; and 2812 // (3) There is a pid assigned to it, so it is either starting or 2813 // already running. 2814 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2815 + " app=" + app + " knownToBeDead=" + knownToBeDead 2816 + " thread=" + (app != null ? app.thread : null) 2817 + " pid=" + (app != null ? app.pid : -1)); 2818 if (app != null && app.pid > 0) { 2819 if (!knownToBeDead || app.thread == null) { 2820 // We already have the app running, or are waiting for it to 2821 // come up (we have a pid but not yet its thread), so keep it. 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 return app; 2826 } 2827 2828 // An application record is attached to a previous process, 2829 // clean it up now. 2830 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2831 handleAppDiedLocked(app, true, true); 2832 } 2833 2834 String hostingNameStr = hostingName != null 2835 ? hostingName.flattenToShortString() : null; 2836 2837 if (!isolated) { 2838 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2839 // If we are in the background, then check to see if this process 2840 // is bad. If so, we will just silently fail. 2841 if (mBadProcesses.get(info.processName, info.uid) != null) { 2842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2843 + "/" + info.processName); 2844 return null; 2845 } 2846 } else { 2847 // When the user is explicitly starting a process, then clear its 2848 // crash count so that we won't make it bad until they see at 2849 // least one crash dialog again, and make the process good again 2850 // if it had been bad. 2851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2852 + "/" + info.processName); 2853 mProcessCrashTimes.remove(info.processName, info.uid); 2854 if (mBadProcesses.get(info.processName, info.uid) != null) { 2855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2856 UserHandle.getUserId(info.uid), info.uid, 2857 info.processName); 2858 mBadProcesses.remove(info.processName, info.uid); 2859 if (app != null) { 2860 app.bad = false; 2861 } 2862 } 2863 } 2864 } 2865 2866 if (app == null) { 2867 app = newProcessRecordLocked(info, processName, isolated); 2868 if (app == null) { 2869 Slog.w(TAG, "Failed making new process record for " 2870 + processName + "/" + info.uid + " isolated=" + isolated); 2871 return null; 2872 } 2873 mProcessNames.put(processName, app.uid, app); 2874 if (isolated) { 2875 mIsolatedProcesses.put(app.uid, app); 2876 } 2877 } else { 2878 // If this is a new package in the process, add the package to the list 2879 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2880 } 2881 2882 // If the system is not ready yet, then hold off on starting this 2883 // process until it is. 2884 if (!mProcessesReady 2885 && !isAllowedWhileBooting(info) 2886 && !allowWhileBooting) { 2887 if (!mProcessesOnHold.contains(app)) { 2888 mProcessesOnHold.add(app); 2889 } 2890 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2891 return app; 2892 } 2893 2894 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2895 return (app.pid != 0) ? app : null; 2896 } 2897 2898 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2899 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2900 } 2901 2902 private final void startProcessLocked(ProcessRecord app, 2903 String hostingType, String hostingNameStr, String abiOverride) { 2904 if (app.pid > 0 && app.pid != MY_PID) { 2905 synchronized (mPidsSelfLocked) { 2906 mPidsSelfLocked.remove(app.pid); 2907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2908 } 2909 app.setPid(0); 2910 } 2911 2912 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2913 "startProcessLocked removing on hold: " + app); 2914 mProcessesOnHold.remove(app); 2915 2916 updateCpuStats(); 2917 2918 try { 2919 int uid = app.uid; 2920 2921 int[] gids = null; 2922 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2923 if (!app.isolated) { 2924 int[] permGids = null; 2925 try { 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 if (pm.checkPermission( 2931 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2932 app.info.packageName) == PERMISSION_GRANTED) { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2934 } else { 2935 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2936 } 2937 } 2938 } catch (PackageManager.NameNotFoundException e) { 2939 Slog.w(TAG, "Unable to retrieve gids", e); 2940 } 2941 2942 /* 2943 * Add shared application and profile GIDs so applications can share some 2944 * resources like shared libraries and access user-wide resources 2945 */ 2946 if (permGids == null) { 2947 gids = new int[2]; 2948 } else { 2949 gids = new int[permGids.length + 2]; 2950 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2951 } 2952 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2953 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2954 } 2955 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2956 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2957 && mTopComponent != null 2958 && app.processName.equals(mTopComponent.getPackageName())) { 2959 uid = 0; 2960 } 2961 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2962 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2963 uid = 0; 2964 } 2965 } 2966 int debugFlags = 0; 2967 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2968 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2969 // Also turn on CheckJNI for debuggable apps. It's quite 2970 // awkward to turn on otherwise. 2971 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2972 } 2973 // Run the app in safe mode if its manifest requests so or the 2974 // system is booted in safe mode. 2975 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2976 mSafeMode == true) { 2977 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2978 } 2979 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2981 } 2982 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2984 } 2985 if ("1".equals(SystemProperties.get("debug.assert"))) { 2986 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2987 } 2988 2989 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2990 if (requiredAbi == null) { 2991 requiredAbi = Build.SUPPORTED_ABIS[0]; 2992 } 2993 2994 // Start the process. It will either succeed and return a result containing 2995 // the PID of the new process, or else throw a RuntimeException. 2996 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2997 app.processName, uid, uid, gids, debugFlags, mountExternal, 2998 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2999 3000 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 3001 synchronized (bs) { 3002 if (bs.isOnBattery()) { 3003 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 3004 } 3005 } 3006 3007 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3008 UserHandle.getUserId(uid), startResult.pid, uid, 3009 app.processName, hostingType, 3010 hostingNameStr != null ? hostingNameStr : ""); 3011 3012 if (app.persistent) { 3013 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3014 } 3015 3016 StringBuilder buf = mStringBuilder; 3017 buf.setLength(0); 3018 buf.append("Start proc "); 3019 buf.append(app.processName); 3020 buf.append(" for "); 3021 buf.append(hostingType); 3022 if (hostingNameStr != null) { 3023 buf.append(" "); 3024 buf.append(hostingNameStr); 3025 } 3026 buf.append(": pid="); 3027 buf.append(startResult.pid); 3028 buf.append(" uid="); 3029 buf.append(uid); 3030 buf.append(" gids={"); 3031 if (gids != null) { 3032 for (int gi=0; gi<gids.length; gi++) { 3033 if (gi != 0) buf.append(", "); 3034 buf.append(gids[gi]); 3035 3036 } 3037 } 3038 buf.append("}"); 3039 if (requiredAbi != null) { 3040 buf.append(" abi="); 3041 buf.append(requiredAbi); 3042 } 3043 Slog.i(TAG, buf.toString()); 3044 app.setPid(startResult.pid); 3045 app.usingWrapper = startResult.usingWrapper; 3046 app.removed = false; 3047 app.killedByAm = false; 3048 synchronized (mPidsSelfLocked) { 3049 this.mPidsSelfLocked.put(startResult.pid, app); 3050 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3051 msg.obj = app; 3052 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3053 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3054 } 3055 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3056 app.processName, app.info.uid); 3057 if (app.isolated) { 3058 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3059 } 3060 } catch (RuntimeException e) { 3061 // XXX do better error recovery. 3062 app.setPid(0); 3063 Slog.e(TAG, "Failure starting process " + app.processName, e); 3064 } 3065 } 3066 3067 void updateUsageStats(ActivityRecord component, boolean resumed) { 3068 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3069 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3070 if (resumed) { 3071 mUsageStatsService.noteResumeComponent(component.realActivity); 3072 synchronized (stats) { 3073 stats.noteActivityResumedLocked(component.app.uid); 3074 } 3075 } else { 3076 mUsageStatsService.notePauseComponent(component.realActivity); 3077 synchronized (stats) { 3078 stats.noteActivityPausedLocked(component.app.uid); 3079 } 3080 } 3081 } 3082 3083 Intent getHomeIntent() { 3084 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3085 intent.setComponent(mTopComponent); 3086 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3087 intent.addCategory(Intent.CATEGORY_HOME); 3088 } 3089 return intent; 3090 } 3091 3092 boolean startHomeActivityLocked(int userId) { 3093 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3094 && mTopAction == null) { 3095 // We are running in factory test mode, but unable to find 3096 // the factory test app, so just sit around displaying the 3097 // error message and don't try to start anything. 3098 return false; 3099 } 3100 Intent intent = getHomeIntent(); 3101 ActivityInfo aInfo = 3102 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3103 if (aInfo != null) { 3104 intent.setComponent(new ComponentName( 3105 aInfo.applicationInfo.packageName, aInfo.name)); 3106 // Don't do this if the home app is currently being 3107 // instrumented. 3108 aInfo = new ActivityInfo(aInfo); 3109 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3110 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3111 aInfo.applicationInfo.uid, true); 3112 if (app == null || app.instrumentationClass == null) { 3113 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3114 mStackSupervisor.startHomeActivity(intent, aInfo); 3115 } 3116 } 3117 3118 return true; 3119 } 3120 3121 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3122 ActivityInfo ai = null; 3123 ComponentName comp = intent.getComponent(); 3124 try { 3125 if (comp != null) { 3126 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3127 } else { 3128 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3129 intent, 3130 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3131 flags, userId); 3132 3133 if (info != null) { 3134 ai = info.activityInfo; 3135 } 3136 } 3137 } catch (RemoteException e) { 3138 // ignore 3139 } 3140 3141 return ai; 3142 } 3143 3144 /** 3145 * Starts the "new version setup screen" if appropriate. 3146 */ 3147 void startSetupActivityLocked() { 3148 // Only do this once per boot. 3149 if (mCheckedForSetup) { 3150 return; 3151 } 3152 3153 // We will show this screen if the current one is a different 3154 // version than the last one shown, and we are not running in 3155 // low-level factory test mode. 3156 final ContentResolver resolver = mContext.getContentResolver(); 3157 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3158 Settings.Global.getInt(resolver, 3159 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3160 mCheckedForSetup = true; 3161 3162 // See if we should be showing the platform update setup UI. 3163 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3164 List<ResolveInfo> ris = mContext.getPackageManager() 3165 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3166 3167 // We don't allow third party apps to replace this. 3168 ResolveInfo ri = null; 3169 for (int i=0; ris != null && i<ris.size(); i++) { 3170 if ((ris.get(i).activityInfo.applicationInfo.flags 3171 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3172 ri = ris.get(i); 3173 break; 3174 } 3175 } 3176 3177 if (ri != null) { 3178 String vers = ri.activityInfo.metaData != null 3179 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3180 : null; 3181 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3182 vers = ri.activityInfo.applicationInfo.metaData.getString( 3183 Intent.METADATA_SETUP_VERSION); 3184 } 3185 String lastVers = Settings.Secure.getString( 3186 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3187 if (vers != null && !vers.equals(lastVers)) { 3188 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3189 intent.setComponent(new ComponentName( 3190 ri.activityInfo.packageName, ri.activityInfo.name)); 3191 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3192 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3193 } 3194 } 3195 } 3196 } 3197 3198 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3199 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3200 } 3201 3202 void enforceNotIsolatedCaller(String caller) { 3203 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3204 throw new SecurityException("Isolated process not allowed to call " + caller); 3205 } 3206 } 3207 3208 @Override 3209 public int getFrontActivityScreenCompatMode() { 3210 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3211 synchronized (this) { 3212 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3213 } 3214 } 3215 3216 @Override 3217 public void setFrontActivityScreenCompatMode(int mode) { 3218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3219 "setFrontActivityScreenCompatMode"); 3220 synchronized (this) { 3221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3222 } 3223 } 3224 3225 @Override 3226 public int getPackageScreenCompatMode(String packageName) { 3227 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3228 synchronized (this) { 3229 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3230 } 3231 } 3232 3233 @Override 3234 public void setPackageScreenCompatMode(String packageName, int mode) { 3235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3236 "setPackageScreenCompatMode"); 3237 synchronized (this) { 3238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3239 } 3240 } 3241 3242 @Override 3243 public boolean getPackageAskScreenCompat(String packageName) { 3244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3245 synchronized (this) { 3246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3247 } 3248 } 3249 3250 @Override 3251 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setPackageAskScreenCompat"); 3254 synchronized (this) { 3255 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3256 } 3257 } 3258 3259 private void dispatchProcessesChanged() { 3260 int N; 3261 synchronized (this) { 3262 N = mPendingProcessChanges.size(); 3263 if (mActiveProcessChanges.length < N) { 3264 mActiveProcessChanges = new ProcessChangeItem[N]; 3265 } 3266 mPendingProcessChanges.toArray(mActiveProcessChanges); 3267 mAvailProcessChanges.addAll(mPendingProcessChanges); 3268 mPendingProcessChanges.clear(); 3269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3270 } 3271 3272 int i = mProcessObservers.beginBroadcast(); 3273 while (i > 0) { 3274 i--; 3275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3276 if (observer != null) { 3277 try { 3278 for (int j=0; j<N; j++) { 3279 ProcessChangeItem item = mActiveProcessChanges[j]; 3280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3282 + item.pid + " uid=" + item.uid + ": " 3283 + item.foregroundActivities); 3284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3285 item.foregroundActivities); 3286 } 3287 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3289 + item.pid + " uid=" + item.uid + ": " + item.processState); 3290 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3291 } 3292 } 3293 } catch (RemoteException e) { 3294 } 3295 } 3296 } 3297 mProcessObservers.finishBroadcast(); 3298 } 3299 3300 private void dispatchProcessDied(int pid, int uid) { 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 observer.onProcessDied(pid, uid); 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 final void doPendingActivityLaunchesLocked(boolean doResume) { 3316 final int N = mPendingActivityLaunches.size(); 3317 if (N <= 0) { 3318 return; 3319 } 3320 for (int i=0; i<N; i++) { 3321 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3322 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3323 doResume && i == (N-1), null); 3324 } 3325 mPendingActivityLaunches.clear(); 3326 } 3327 3328 @Override 3329 public final int startActivity(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, 3331 String resultWho, int requestCode, int startFlags, 3332 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3333 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3334 resultWho, requestCode, 3335 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3336 } 3337 3338 @Override 3339 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3340 Intent intent, String resolvedType, IBinder resultTo, 3341 String resultWho, int requestCode, int startFlags, 3342 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3343 enforceNotIsolatedCaller("startActivity"); 3344 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3345 false, true, "startActivity", null); 3346 // TODO: Switch to user app stacks here. 3347 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3348 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3349 null, null, options, userId, null); 3350 } 3351 3352 @Override 3353 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, 3355 String resultWho, int requestCode, int startFlags, String profileFile, 3356 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3357 enforceNotIsolatedCaller("startActivityAndWait"); 3358 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3359 false, true, "startActivityAndWait", null); 3360 WaitResult res = new WaitResult(); 3361 // TODO: Switch to user app stacks here. 3362 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3363 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3364 res, null, options, UserHandle.getCallingUserId(), null); 3365 return res; 3366 } 3367 3368 @Override 3369 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, 3371 String resultWho, int requestCode, int startFlags, Configuration config, 3372 Bundle options, int userId) { 3373 enforceNotIsolatedCaller("startActivityWithConfig"); 3374 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3375 false, true, "startActivityWithConfig", null); 3376 // TODO: Switch to user app stacks here. 3377 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3378 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3379 null, null, null, config, options, userId, null); 3380 return ret; 3381 } 3382 3383 @Override 3384 public int startActivityIntentSender(IApplicationThread caller, 3385 IntentSender intent, Intent fillInIntent, String resolvedType, 3386 IBinder resultTo, String resultWho, int requestCode, 3387 int flagsMask, int flagsValues, Bundle options) { 3388 enforceNotIsolatedCaller("startActivityIntentSender"); 3389 // Refuse possible leaked file descriptors 3390 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3391 throw new IllegalArgumentException("File descriptors passed in Intent"); 3392 } 3393 3394 IIntentSender sender = intent.getTarget(); 3395 if (!(sender instanceof PendingIntentRecord)) { 3396 throw new IllegalArgumentException("Bad PendingIntent object"); 3397 } 3398 3399 PendingIntentRecord pir = (PendingIntentRecord)sender; 3400 3401 synchronized (this) { 3402 // If this is coming from the currently resumed activity, it is 3403 // effectively saying that app switches are allowed at this point. 3404 final ActivityStack stack = getFocusedStack(); 3405 if (stack.mResumedActivity != null && 3406 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3407 mAppSwitchesAllowedTime = 0; 3408 } 3409 } 3410 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3411 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3412 return ret; 3413 } 3414 3415 @Override 3416 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3417 Intent intent, String resolvedType, IVoiceInteractionSession session, 3418 IVoiceInteractor interactor, int startFlags, String profileFile, 3419 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3420 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3421 != PackageManager.PERMISSION_GRANTED) { 3422 String msg = "Permission Denial: startVoiceActivity() from pid=" 3423 + Binder.getCallingPid() 3424 + ", uid=" + Binder.getCallingUid() 3425 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3426 Slog.w(TAG, msg); 3427 throw new SecurityException(msg); 3428 } 3429 if (session == null || interactor == null) { 3430 throw new NullPointerException("null session or interactor"); 3431 } 3432 userId = handleIncomingUser(callingPid, callingUid, userId, 3433 false, true, "startVoiceActivity", null); 3434 // TODO: Switch to user app stacks here. 3435 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3436 resolvedType, session, interactor, null, null, 0, startFlags, 3437 profileFile, profileFd, null, null, options, userId, null); 3438 } 3439 3440 @Override 3441 public boolean startNextMatchingActivity(IBinder callingActivity, 3442 Intent intent, Bundle options) { 3443 // Refuse possible leaked file descriptors 3444 if (intent != null && intent.hasFileDescriptors() == true) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 synchronized (this) { 3449 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3450 if (r == null) { 3451 ActivityOptions.abort(options); 3452 return false; 3453 } 3454 if (r.app == null || r.app.thread == null) { 3455 // The caller is not running... d'oh! 3456 ActivityOptions.abort(options); 3457 return false; 3458 } 3459 intent = new Intent(intent); 3460 // The caller is not allowed to change the data. 3461 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3462 // And we are resetting to find the next component... 3463 intent.setComponent(null); 3464 3465 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3466 3467 ActivityInfo aInfo = null; 3468 try { 3469 List<ResolveInfo> resolves = 3470 AppGlobals.getPackageManager().queryIntentActivities( 3471 intent, r.resolvedType, 3472 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3473 UserHandle.getCallingUserId()); 3474 3475 // Look for the original activity in the list... 3476 final int N = resolves != null ? resolves.size() : 0; 3477 for (int i=0; i<N; i++) { 3478 ResolveInfo rInfo = resolves.get(i); 3479 if (rInfo.activityInfo.packageName.equals(r.packageName) 3480 && rInfo.activityInfo.name.equals(r.info.name)) { 3481 // We found the current one... the next matching is 3482 // after it. 3483 i++; 3484 if (i<N) { 3485 aInfo = resolves.get(i).activityInfo; 3486 } 3487 if (debug) { 3488 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3489 + "/" + r.info.name); 3490 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3491 + "/" + aInfo.name); 3492 } 3493 break; 3494 } 3495 } 3496 } catch (RemoteException e) { 3497 } 3498 3499 if (aInfo == null) { 3500 // Nobody who is next! 3501 ActivityOptions.abort(options); 3502 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3503 return false; 3504 } 3505 3506 intent.setComponent(new ComponentName( 3507 aInfo.applicationInfo.packageName, aInfo.name)); 3508 intent.setFlags(intent.getFlags()&~( 3509 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3510 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3511 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3512 Intent.FLAG_ACTIVITY_NEW_TASK)); 3513 3514 // Okay now we need to start the new activity, replacing the 3515 // currently running activity. This is a little tricky because 3516 // we want to start the new one as if the current one is finished, 3517 // but not finish the current one first so that there is no flicker. 3518 // And thus... 3519 final boolean wasFinishing = r.finishing; 3520 r.finishing = true; 3521 3522 // Propagate reply information over to the new activity. 3523 final ActivityRecord resultTo = r.resultTo; 3524 final String resultWho = r.resultWho; 3525 final int requestCode = r.requestCode; 3526 r.resultTo = null; 3527 if (resultTo != null) { 3528 resultTo.removeResultsLocked(r, resultWho, requestCode); 3529 } 3530 3531 final long origId = Binder.clearCallingIdentity(); 3532 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3533 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3534 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3535 options, false, null, null); 3536 Binder.restoreCallingIdentity(origId); 3537 3538 r.finishing = wasFinishing; 3539 if (res != ActivityManager.START_SUCCESS) { 3540 return false; 3541 } 3542 return true; 3543 } 3544 } 3545 3546 final int startActivityInPackage(int uid, String callingPackage, 3547 Intent intent, String resolvedType, IBinder resultTo, 3548 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3549 IActivityContainer container) { 3550 3551 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3552 false, true, "startActivityInPackage", null); 3553 3554 // TODO: Switch to user app stacks here. 3555 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3556 null, null, resultTo, resultWho, requestCode, startFlags, 3557 null, null, null, null, options, userId, container); 3558 return ret; 3559 } 3560 3561 @Override 3562 public final int startActivities(IApplicationThread caller, String callingPackage, 3563 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3564 int userId) { 3565 enforceNotIsolatedCaller("startActivities"); 3566 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3567 false, true, "startActivity", null); 3568 // TODO: Switch to user app stacks here. 3569 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3570 resolvedTypes, resultTo, options, userId); 3571 return ret; 3572 } 3573 3574 final int startActivitiesInPackage(int uid, String callingPackage, 3575 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3576 Bundle options, int userId) { 3577 3578 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3579 false, true, "startActivityInPackage", null); 3580 // TODO: Switch to user app stacks here. 3581 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3582 resultTo, options, userId); 3583 return ret; 3584 } 3585 3586 final void addRecentTaskLocked(TaskRecord task) { 3587 int N = mRecentTasks.size(); 3588 // Quick case: check if the top-most recent task is the same. 3589 if (N > 0 && mRecentTasks.get(0) == task) { 3590 return; 3591 } 3592 // Another quick case: never add voice sessions. 3593 if (task.voiceSession != null) { 3594 return; 3595 } 3596 // Remove any existing entries that are the same kind of task. 3597 final Intent intent = task.intent; 3598 final boolean document = intent != null && intent.isDocument(); 3599 final ComponentName comp = intent.getComponent(); 3600 3601 int maxRecents = task.maxRecents - 1; 3602 for (int i=0; i<N; i++) { 3603 TaskRecord tr = mRecentTasks.get(i); 3604 if (task != tr) { 3605 if (task.userId != tr.userId) { 3606 continue; 3607 } 3608 if (i > MAX_RECENT_BITMAPS) { 3609 tr.freeLastThumbnail(); 3610 } 3611 final Intent trIntent = tr.intent; 3612 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3613 (intent == null || !intent.filterEquals(trIntent))) { 3614 continue; 3615 } 3616 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3617 if (document && trIsDocument) { 3618 // These are the same document activity (not necessarily the same doc). 3619 if (maxRecents > 0) { 3620 --maxRecents; 3621 continue; 3622 } 3623 // Hit the maximum number of documents for this task. Fall through 3624 // and remove this document from recents. 3625 } else if (document || trIsDocument) { 3626 // Only one of these is a document. Not the droid we're looking for. 3627 continue; 3628 } 3629 } 3630 3631 // Either task and tr are the same or, their affinities match or their intents match 3632 // and neither of them is a document, or they are documents using the same activity 3633 // and their maxRecents has been reached. 3634 tr.disposeThumbnail(); 3635 mRecentTasks.remove(i); 3636 i--; 3637 N--; 3638 if (task.intent == null) { 3639 // If the new recent task we are adding is not fully 3640 // specified, then replace it with the existing recent task. 3641 task = tr; 3642 } 3643 mTaskPersister.notify(tr, false); 3644 } 3645 if (N >= MAX_RECENT_TASKS) { 3646 mRecentTasks.remove(N-1).disposeThumbnail(); 3647 } 3648 mRecentTasks.add(0, task); 3649 } 3650 3651 @Override 3652 public void reportActivityFullyDrawn(IBinder token) { 3653 synchronized (this) { 3654 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3655 if (r == null) { 3656 return; 3657 } 3658 r.reportFullyDrawnLocked(); 3659 } 3660 } 3661 3662 @Override 3663 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3664 synchronized (this) { 3665 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3666 if (r == null) { 3667 return; 3668 } 3669 final long origId = Binder.clearCallingIdentity(); 3670 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3671 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3672 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3673 if (config != null) { 3674 r.frozenBeforeDestroy = true; 3675 if (!updateConfigurationLocked(config, r, false, false)) { 3676 mStackSupervisor.resumeTopActivitiesLocked(); 3677 } 3678 } 3679 Binder.restoreCallingIdentity(origId); 3680 } 3681 } 3682 3683 @Override 3684 public int getRequestedOrientation(IBinder token) { 3685 synchronized (this) { 3686 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3687 if (r == null) { 3688 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3689 } 3690 return mWindowManager.getAppOrientation(r.appToken); 3691 } 3692 } 3693 3694 /** 3695 * This is the internal entry point for handling Activity.finish(). 3696 * 3697 * @param token The Binder token referencing the Activity we want to finish. 3698 * @param resultCode Result code, if any, from this Activity. 3699 * @param resultData Result data (Intent), if any, from this Activity. 3700 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3701 * the root Activity in the task. 3702 * 3703 * @return Returns true if the activity successfully finished, or false if it is still running. 3704 */ 3705 @Override 3706 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3707 boolean finishTask) { 3708 // Refuse possible leaked file descriptors 3709 if (resultData != null && resultData.hasFileDescriptors() == true) { 3710 throw new IllegalArgumentException("File descriptors passed in Intent"); 3711 } 3712 3713 synchronized(this) { 3714 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3715 if (r == null) { 3716 return true; 3717 } 3718 // Keep track of the root activity of the task before we finish it 3719 TaskRecord tr = r.task; 3720 ActivityRecord rootR = tr.getRootActivity(); 3721 // Do not allow task to finish in Lock Task mode. 3722 if (tr == mStackSupervisor.mLockTaskModeTask) { 3723 if (rootR == r) { 3724 mStackSupervisor.showLockTaskToast(); 3725 return false; 3726 } 3727 } 3728 if (mController != null) { 3729 // Find the first activity that is not finishing. 3730 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3731 if (next != null) { 3732 // ask watcher if this is allowed 3733 boolean resumeOK = true; 3734 try { 3735 resumeOK = mController.activityResuming(next.packageName); 3736 } catch (RemoteException e) { 3737 mController = null; 3738 Watchdog.getInstance().setActivityController(null); 3739 } 3740 3741 if (!resumeOK) { 3742 return false; 3743 } 3744 } 3745 } 3746 final long origId = Binder.clearCallingIdentity(); 3747 try { 3748 boolean res; 3749 if (finishTask && r == rootR) { 3750 // If requested, remove the task that is associated to this activity only if it 3751 // was the root activity in the task. The result code and data is ignored because 3752 // we don't support returning them across task boundaries. 3753 res = removeTaskByIdLocked(tr.taskId, 0); 3754 } else { 3755 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3756 resultData, "app-request", true); 3757 } 3758 return res; 3759 } finally { 3760 Binder.restoreCallingIdentity(origId); 3761 } 3762 } 3763 } 3764 3765 @Override 3766 public final void finishHeavyWeightApp() { 3767 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3768 != PackageManager.PERMISSION_GRANTED) { 3769 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3770 + Binder.getCallingPid() 3771 + ", uid=" + Binder.getCallingUid() 3772 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3773 Slog.w(TAG, msg); 3774 throw new SecurityException(msg); 3775 } 3776 3777 synchronized(this) { 3778 if (mHeavyWeightProcess == null) { 3779 return; 3780 } 3781 3782 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3783 mHeavyWeightProcess.activities); 3784 for (int i=0; i<activities.size(); i++) { 3785 ActivityRecord r = activities.get(i); 3786 if (!r.finishing) { 3787 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3788 null, "finish-heavy", true); 3789 } 3790 } 3791 3792 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3793 mHeavyWeightProcess.userId, 0)); 3794 mHeavyWeightProcess = null; 3795 } 3796 } 3797 3798 @Override 3799 public void crashApplication(int uid, int initialPid, String packageName, 3800 String message) { 3801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3802 != PackageManager.PERMISSION_GRANTED) { 3803 String msg = "Permission Denial: crashApplication() from pid=" 3804 + Binder.getCallingPid() 3805 + ", uid=" + Binder.getCallingUid() 3806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3807 Slog.w(TAG, msg); 3808 throw new SecurityException(msg); 3809 } 3810 3811 synchronized(this) { 3812 ProcessRecord proc = null; 3813 3814 // Figure out which process to kill. We don't trust that initialPid 3815 // still has any relation to current pids, so must scan through the 3816 // list. 3817 synchronized (mPidsSelfLocked) { 3818 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3819 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3820 if (p.uid != uid) { 3821 continue; 3822 } 3823 if (p.pid == initialPid) { 3824 proc = p; 3825 break; 3826 } 3827 if (p.pkgList.containsKey(packageName)) { 3828 proc = p; 3829 } 3830 } 3831 } 3832 3833 if (proc == null) { 3834 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3835 + " initialPid=" + initialPid 3836 + " packageName=" + packageName); 3837 return; 3838 } 3839 3840 if (proc.thread != null) { 3841 if (proc.pid == Process.myPid()) { 3842 Log.w(TAG, "crashApplication: trying to crash self!"); 3843 return; 3844 } 3845 long ident = Binder.clearCallingIdentity(); 3846 try { 3847 proc.thread.scheduleCrash(message); 3848 } catch (RemoteException e) { 3849 } 3850 Binder.restoreCallingIdentity(ident); 3851 } 3852 } 3853 } 3854 3855 @Override 3856 public final void finishSubActivity(IBinder token, String resultWho, 3857 int requestCode) { 3858 synchronized(this) { 3859 final long origId = Binder.clearCallingIdentity(); 3860 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3861 if (r != null) { 3862 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3863 } 3864 Binder.restoreCallingIdentity(origId); 3865 } 3866 } 3867 3868 @Override 3869 public boolean finishActivityAffinity(IBinder token) { 3870 synchronized(this) { 3871 final long origId = Binder.clearCallingIdentity(); 3872 try { 3873 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3874 3875 ActivityRecord rootR = r.task.getRootActivity(); 3876 // Do not allow task to finish in Lock Task mode. 3877 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3878 if (rootR == r) { 3879 mStackSupervisor.showLockTaskToast(); 3880 return false; 3881 } 3882 } 3883 boolean res = false; 3884 if (r != null) { 3885 res = r.task.stack.finishActivityAffinityLocked(r); 3886 } 3887 return res; 3888 } finally { 3889 Binder.restoreCallingIdentity(origId); 3890 } 3891 } 3892 } 3893 3894 @Override 3895 public void finishVoiceTask(IVoiceInteractionSession session) { 3896 synchronized(this) { 3897 final long origId = Binder.clearCallingIdentity(); 3898 try { 3899 mStackSupervisor.finishVoiceTask(session); 3900 } finally { 3901 Binder.restoreCallingIdentity(origId); 3902 } 3903 } 3904 3905 } 3906 3907 @Override 3908 public boolean willActivityBeVisible(IBinder token) { 3909 synchronized(this) { 3910 ActivityStack stack = ActivityRecord.getStackLocked(token); 3911 if (stack != null) { 3912 return stack.willActivityBeVisibleLocked(token); 3913 } 3914 return false; 3915 } 3916 } 3917 3918 @Override 3919 public void overridePendingTransition(IBinder token, String packageName, 3920 int enterAnim, int exitAnim) { 3921 synchronized(this) { 3922 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3923 if (self == null) { 3924 return; 3925 } 3926 3927 final long origId = Binder.clearCallingIdentity(); 3928 3929 if (self.state == ActivityState.RESUMED 3930 || self.state == ActivityState.PAUSING) { 3931 mWindowManager.overridePendingAppTransition(packageName, 3932 enterAnim, exitAnim, null); 3933 } 3934 3935 Binder.restoreCallingIdentity(origId); 3936 } 3937 } 3938 3939 /** 3940 * Main function for removing an existing process from the activity manager 3941 * as a result of that process going away. Clears out all connections 3942 * to the process. 3943 */ 3944 private final void handleAppDiedLocked(ProcessRecord app, 3945 boolean restarting, boolean allowRestart) { 3946 int pid = app.pid; 3947 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3948 if (!restarting) { 3949 removeLruProcessLocked(app); 3950 if (pid > 0) { 3951 ProcessList.remove(pid); 3952 } 3953 } 3954 3955 if (mProfileProc == app) { 3956 clearProfilerLocked(); 3957 } 3958 3959 // Remove this application's activities from active lists. 3960 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3961 3962 app.activities.clear(); 3963 3964 if (app.instrumentationClass != null) { 3965 Slog.w(TAG, "Crash of app " + app.processName 3966 + " running instrumentation " + app.instrumentationClass); 3967 Bundle info = new Bundle(); 3968 info.putString("shortMsg", "Process crashed."); 3969 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3970 } 3971 3972 if (!restarting) { 3973 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3974 // If there was nothing to resume, and we are not already 3975 // restarting this process, but there is a visible activity that 3976 // is hosted by the process... then make sure all visible 3977 // activities are running, taking care of restarting this 3978 // process. 3979 if (hasVisibleActivities) { 3980 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3981 } 3982 } 3983 } 3984 } 3985 3986 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3987 IBinder threadBinder = thread.asBinder(); 3988 // Find the application record. 3989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3990 ProcessRecord rec = mLruProcesses.get(i); 3991 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3992 return i; 3993 } 3994 } 3995 return -1; 3996 } 3997 3998 final ProcessRecord getRecordForAppLocked( 3999 IApplicationThread thread) { 4000 if (thread == null) { 4001 return null; 4002 } 4003 4004 int appIndex = getLRURecordIndexForAppLocked(thread); 4005 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4006 } 4007 4008 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4009 // If there are no longer any background processes running, 4010 // and the app that died was not running instrumentation, 4011 // then tell everyone we are now low on memory. 4012 boolean haveBg = false; 4013 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4014 ProcessRecord rec = mLruProcesses.get(i); 4015 if (rec.thread != null 4016 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4017 haveBg = true; 4018 break; 4019 } 4020 } 4021 4022 if (!haveBg) { 4023 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4024 if (doReport) { 4025 long now = SystemClock.uptimeMillis(); 4026 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4027 doReport = false; 4028 } else { 4029 mLastMemUsageReportTime = now; 4030 } 4031 } 4032 final ArrayList<ProcessMemInfo> memInfos 4033 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4034 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4035 long now = SystemClock.uptimeMillis(); 4036 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4037 ProcessRecord rec = mLruProcesses.get(i); 4038 if (rec == dyingProc || rec.thread == null) { 4039 continue; 4040 } 4041 if (doReport) { 4042 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4043 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4044 } 4045 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4046 // The low memory report is overriding any current 4047 // state for a GC request. Make sure to do 4048 // heavy/important/visible/foreground processes first. 4049 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4050 rec.lastRequestedGc = 0; 4051 } else { 4052 rec.lastRequestedGc = rec.lastLowMemory; 4053 } 4054 rec.reportLowMemory = true; 4055 rec.lastLowMemory = now; 4056 mProcessesToGc.remove(rec); 4057 addProcessToGcListLocked(rec); 4058 } 4059 } 4060 if (doReport) { 4061 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4062 mHandler.sendMessage(msg); 4063 } 4064 scheduleAppGcsLocked(); 4065 } 4066 } 4067 4068 final void appDiedLocked(ProcessRecord app, int pid, 4069 IApplicationThread thread) { 4070 4071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4072 synchronized (stats) { 4073 stats.noteProcessDiedLocked(app.info.uid, pid); 4074 } 4075 4076 // Clean up already done if the process has been re-started. 4077 if (app.pid == pid && app.thread != null && 4078 app.thread.asBinder() == thread.asBinder()) { 4079 boolean doLowMem = app.instrumentationClass == null; 4080 boolean doOomAdj = doLowMem; 4081 if (!app.killedByAm) { 4082 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4083 + ") has died."); 4084 mAllowLowerMemLevel = true; 4085 } else { 4086 // Note that we always want to do oom adj to update our state with the 4087 // new number of procs. 4088 mAllowLowerMemLevel = false; 4089 doLowMem = false; 4090 } 4091 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4092 if (DEBUG_CLEANUP) Slog.v( 4093 TAG, "Dying app: " + app + ", pid: " + pid 4094 + ", thread: " + thread.asBinder()); 4095 handleAppDiedLocked(app, false, true); 4096 4097 if (doOomAdj) { 4098 updateOomAdjLocked(); 4099 } 4100 if (doLowMem) { 4101 doLowMemReportIfNeededLocked(app); 4102 } 4103 } else if (app.pid != pid) { 4104 // A new process has already been started. 4105 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4106 + ") has died and restarted (pid " + app.pid + ")."); 4107 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4108 } else if (DEBUG_PROCESSES) { 4109 Slog.d(TAG, "Received spurious death notification for thread " 4110 + thread.asBinder()); 4111 } 4112 } 4113 4114 /** 4115 * If a stack trace dump file is configured, dump process stack traces. 4116 * @param clearTraces causes the dump file to be erased prior to the new 4117 * traces being written, if true; when false, the new traces will be 4118 * appended to any existing file content. 4119 * @param firstPids of dalvik VM processes to dump stack traces for first 4120 * @param lastPids of dalvik VM processes to dump stack traces for last 4121 * @param nativeProcs optional list of native process names to dump stack crawls 4122 * @return file containing stack traces, or null if no dump file is configured 4123 */ 4124 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4125 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4126 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4127 if (tracesPath == null || tracesPath.length() == 0) { 4128 return null; 4129 } 4130 4131 File tracesFile = new File(tracesPath); 4132 try { 4133 File tracesDir = tracesFile.getParentFile(); 4134 if (!tracesDir.exists()) { 4135 tracesFile.mkdirs(); 4136 if (!SELinux.restorecon(tracesDir)) { 4137 return null; 4138 } 4139 } 4140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4141 4142 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4143 tracesFile.createNewFile(); 4144 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4145 } catch (IOException e) { 4146 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4147 return null; 4148 } 4149 4150 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4151 return tracesFile; 4152 } 4153 4154 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4155 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4156 // Use a FileObserver to detect when traces finish writing. 4157 // The order of traces is considered important to maintain for legibility. 4158 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4159 @Override 4160 public synchronized void onEvent(int event, String path) { notify(); } 4161 }; 4162 4163 try { 4164 observer.startWatching(); 4165 4166 // First collect all of the stacks of the most important pids. 4167 if (firstPids != null) { 4168 try { 4169 int num = firstPids.size(); 4170 for (int i = 0; i < num; i++) { 4171 synchronized (observer) { 4172 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4173 observer.wait(200); // Wait for write-close, give up after 200msec 4174 } 4175 } 4176 } catch (InterruptedException e) { 4177 Log.wtf(TAG, e); 4178 } 4179 } 4180 4181 // Next collect the stacks of the native pids 4182 if (nativeProcs != null) { 4183 int[] pids = Process.getPidsForCommands(nativeProcs); 4184 if (pids != null) { 4185 for (int pid : pids) { 4186 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4187 } 4188 } 4189 } 4190 4191 // Lastly, measure CPU usage. 4192 if (processCpuTracker != null) { 4193 processCpuTracker.init(); 4194 System.gc(); 4195 processCpuTracker.update(); 4196 try { 4197 synchronized (processCpuTracker) { 4198 processCpuTracker.wait(500); // measure over 1/2 second. 4199 } 4200 } catch (InterruptedException e) { 4201 } 4202 processCpuTracker.update(); 4203 4204 // We'll take the stack crawls of just the top apps using CPU. 4205 final int N = processCpuTracker.countWorkingStats(); 4206 int numProcs = 0; 4207 for (int i=0; i<N && numProcs<5; i++) { 4208 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4209 if (lastPids.indexOfKey(stats.pid) >= 0) { 4210 numProcs++; 4211 try { 4212 synchronized (observer) { 4213 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4214 observer.wait(200); // Wait for write-close, give up after 200msec 4215 } 4216 } catch (InterruptedException e) { 4217 Log.wtf(TAG, e); 4218 } 4219 4220 } 4221 } 4222 } 4223 } finally { 4224 observer.stopWatching(); 4225 } 4226 } 4227 4228 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4229 if (true || IS_USER_BUILD) { 4230 return; 4231 } 4232 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4233 if (tracesPath == null || tracesPath.length() == 0) { 4234 return; 4235 } 4236 4237 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4238 StrictMode.allowThreadDiskWrites(); 4239 try { 4240 final File tracesFile = new File(tracesPath); 4241 final File tracesDir = tracesFile.getParentFile(); 4242 final File tracesTmp = new File(tracesDir, "__tmp__"); 4243 try { 4244 if (!tracesDir.exists()) { 4245 tracesFile.mkdirs(); 4246 if (!SELinux.restorecon(tracesDir.getPath())) { 4247 return; 4248 } 4249 } 4250 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4251 4252 if (tracesFile.exists()) { 4253 tracesTmp.delete(); 4254 tracesFile.renameTo(tracesTmp); 4255 } 4256 StringBuilder sb = new StringBuilder(); 4257 Time tobj = new Time(); 4258 tobj.set(System.currentTimeMillis()); 4259 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4260 sb.append(": "); 4261 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4262 sb.append(" since "); 4263 sb.append(msg); 4264 FileOutputStream fos = new FileOutputStream(tracesFile); 4265 fos.write(sb.toString().getBytes()); 4266 if (app == null) { 4267 fos.write("\n*** No application process!".getBytes()); 4268 } 4269 fos.close(); 4270 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4271 } catch (IOException e) { 4272 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4273 return; 4274 } 4275 4276 if (app != null) { 4277 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4278 firstPids.add(app.pid); 4279 dumpStackTraces(tracesPath, firstPids, null, null, null); 4280 } 4281 4282 File lastTracesFile = null; 4283 File curTracesFile = null; 4284 for (int i=9; i>=0; i--) { 4285 String name = String.format(Locale.US, "slow%02d.txt", i); 4286 curTracesFile = new File(tracesDir, name); 4287 if (curTracesFile.exists()) { 4288 if (lastTracesFile != null) { 4289 curTracesFile.renameTo(lastTracesFile); 4290 } else { 4291 curTracesFile.delete(); 4292 } 4293 } 4294 lastTracesFile = curTracesFile; 4295 } 4296 tracesFile.renameTo(curTracesFile); 4297 if (tracesTmp.exists()) { 4298 tracesTmp.renameTo(tracesFile); 4299 } 4300 } finally { 4301 StrictMode.setThreadPolicy(oldPolicy); 4302 } 4303 } 4304 4305 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4306 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4307 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4308 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4309 4310 if (mController != null) { 4311 try { 4312 // 0 == continue, -1 = kill process immediately 4313 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4314 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4315 } catch (RemoteException e) { 4316 mController = null; 4317 Watchdog.getInstance().setActivityController(null); 4318 } 4319 } 4320 4321 long anrTime = SystemClock.uptimeMillis(); 4322 if (MONITOR_CPU_USAGE) { 4323 updateCpuStatsNow(); 4324 } 4325 4326 synchronized (this) { 4327 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4328 if (mShuttingDown) { 4329 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4330 return; 4331 } else if (app.notResponding) { 4332 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4333 return; 4334 } else if (app.crashing) { 4335 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4336 return; 4337 } 4338 4339 // In case we come through here for the same app before completing 4340 // this one, mark as anring now so we will bail out. 4341 app.notResponding = true; 4342 4343 // Log the ANR to the event log. 4344 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4345 app.processName, app.info.flags, annotation); 4346 4347 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4348 firstPids.add(app.pid); 4349 4350 int parentPid = app.pid; 4351 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4352 if (parentPid != app.pid) firstPids.add(parentPid); 4353 4354 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4355 4356 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4357 ProcessRecord r = mLruProcesses.get(i); 4358 if (r != null && r.thread != null) { 4359 int pid = r.pid; 4360 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4361 if (r.persistent) { 4362 firstPids.add(pid); 4363 } else { 4364 lastPids.put(pid, Boolean.TRUE); 4365 } 4366 } 4367 } 4368 } 4369 } 4370 4371 // Log the ANR to the main log. 4372 StringBuilder info = new StringBuilder(); 4373 info.setLength(0); 4374 info.append("ANR in ").append(app.processName); 4375 if (activity != null && activity.shortComponentName != null) { 4376 info.append(" (").append(activity.shortComponentName).append(")"); 4377 } 4378 info.append("\n"); 4379 info.append("PID: ").append(app.pid).append("\n"); 4380 if (annotation != null) { 4381 info.append("Reason: ").append(annotation).append("\n"); 4382 } 4383 if (parent != null && parent != activity) { 4384 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4385 } 4386 4387 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4388 4389 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4390 NATIVE_STACKS_OF_INTEREST); 4391 4392 String cpuInfo = null; 4393 if (MONITOR_CPU_USAGE) { 4394 updateCpuStatsNow(); 4395 synchronized (mProcessCpuThread) { 4396 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4397 } 4398 info.append(processCpuTracker.printCurrentLoad()); 4399 info.append(cpuInfo); 4400 } 4401 4402 info.append(processCpuTracker.printCurrentState(anrTime)); 4403 4404 Slog.e(TAG, info.toString()); 4405 if (tracesFile == null) { 4406 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4407 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4408 } 4409 4410 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4411 cpuInfo, tracesFile, null); 4412 4413 if (mController != null) { 4414 try { 4415 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4416 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4417 if (res != 0) { 4418 if (res < 0 && app.pid != MY_PID) { 4419 Process.killProcess(app.pid); 4420 } else { 4421 synchronized (this) { 4422 mServices.scheduleServiceTimeoutLocked(app); 4423 } 4424 } 4425 return; 4426 } 4427 } catch (RemoteException e) { 4428 mController = null; 4429 Watchdog.getInstance().setActivityController(null); 4430 } 4431 } 4432 4433 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4434 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4435 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4436 4437 synchronized (this) { 4438 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4439 killUnneededProcessLocked(app, "background ANR"); 4440 return; 4441 } 4442 4443 // Set the app's notResponding state, and look up the errorReportReceiver 4444 makeAppNotRespondingLocked(app, 4445 activity != null ? activity.shortComponentName : null, 4446 annotation != null ? "ANR " + annotation : "ANR", 4447 info.toString()); 4448 4449 // Bring up the infamous App Not Responding dialog 4450 Message msg = Message.obtain(); 4451 HashMap<String, Object> map = new HashMap<String, Object>(); 4452 msg.what = SHOW_NOT_RESPONDING_MSG; 4453 msg.obj = map; 4454 msg.arg1 = aboveSystem ? 1 : 0; 4455 map.put("app", app); 4456 if (activity != null) { 4457 map.put("activity", activity); 4458 } 4459 4460 mHandler.sendMessage(msg); 4461 } 4462 } 4463 4464 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4465 if (!mLaunchWarningShown) { 4466 mLaunchWarningShown = true; 4467 mHandler.post(new Runnable() { 4468 @Override 4469 public void run() { 4470 synchronized (ActivityManagerService.this) { 4471 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4472 d.show(); 4473 mHandler.postDelayed(new Runnable() { 4474 @Override 4475 public void run() { 4476 synchronized (ActivityManagerService.this) { 4477 d.dismiss(); 4478 mLaunchWarningShown = false; 4479 } 4480 } 4481 }, 4000); 4482 } 4483 } 4484 }); 4485 } 4486 } 4487 4488 @Override 4489 public boolean clearApplicationUserData(final String packageName, 4490 final IPackageDataObserver observer, int userId) { 4491 enforceNotIsolatedCaller("clearApplicationUserData"); 4492 int uid = Binder.getCallingUid(); 4493 int pid = Binder.getCallingPid(); 4494 userId = handleIncomingUser(pid, uid, 4495 userId, false, true, "clearApplicationUserData", null); 4496 long callingId = Binder.clearCallingIdentity(); 4497 try { 4498 IPackageManager pm = AppGlobals.getPackageManager(); 4499 int pkgUid = -1; 4500 synchronized(this) { 4501 try { 4502 pkgUid = pm.getPackageUid(packageName, userId); 4503 } catch (RemoteException e) { 4504 } 4505 if (pkgUid == -1) { 4506 Slog.w(TAG, "Invalid packageName: " + packageName); 4507 if (observer != null) { 4508 try { 4509 observer.onRemoveCompleted(packageName, false); 4510 } catch (RemoteException e) { 4511 Slog.i(TAG, "Observer no longer exists."); 4512 } 4513 } 4514 return false; 4515 } 4516 if (uid == pkgUid || checkComponentPermission( 4517 android.Manifest.permission.CLEAR_APP_USER_DATA, 4518 pid, uid, -1, true) 4519 == PackageManager.PERMISSION_GRANTED) { 4520 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4521 } else { 4522 throw new SecurityException("PID " + pid + " does not have permission " 4523 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4524 + " of package " + packageName); 4525 } 4526 } 4527 4528 try { 4529 // Clear application user data 4530 pm.clearApplicationUserData(packageName, observer, userId); 4531 4532 // Remove all permissions granted from/to this package 4533 removeUriPermissionsForPackageLocked(packageName, userId, true); 4534 4535 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4536 Uri.fromParts("package", packageName, null)); 4537 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4538 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4539 null, null, 0, null, null, null, false, false, userId); 4540 } catch (RemoteException e) { 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 return true; 4546 } 4547 4548 @Override 4549 public void killBackgroundProcesses(final String packageName, int userId) { 4550 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4551 != PackageManager.PERMISSION_GRANTED && 4552 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4553 != PackageManager.PERMISSION_GRANTED) { 4554 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4555 + Binder.getCallingPid() 4556 + ", uid=" + Binder.getCallingUid() 4557 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4558 Slog.w(TAG, msg); 4559 throw new SecurityException(msg); 4560 } 4561 4562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4563 userId, true, true, "killBackgroundProcesses", null); 4564 long callingId = Binder.clearCallingIdentity(); 4565 try { 4566 IPackageManager pm = AppGlobals.getPackageManager(); 4567 synchronized(this) { 4568 int appId = -1; 4569 try { 4570 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4571 } catch (RemoteException e) { 4572 } 4573 if (appId == -1) { 4574 Slog.w(TAG, "Invalid packageName: " + packageName); 4575 return; 4576 } 4577 killPackageProcessesLocked(packageName, appId, userId, 4578 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4579 } 4580 } finally { 4581 Binder.restoreCallingIdentity(callingId); 4582 } 4583 } 4584 4585 @Override 4586 public void killAllBackgroundProcesses() { 4587 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4588 != PackageManager.PERMISSION_GRANTED) { 4589 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4590 + Binder.getCallingPid() 4591 + ", uid=" + Binder.getCallingUid() 4592 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4593 Slog.w(TAG, msg); 4594 throw new SecurityException(msg); 4595 } 4596 4597 long callingId = Binder.clearCallingIdentity(); 4598 try { 4599 synchronized(this) { 4600 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4601 final int NP = mProcessNames.getMap().size(); 4602 for (int ip=0; ip<NP; ip++) { 4603 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4604 final int NA = apps.size(); 4605 for (int ia=0; ia<NA; ia++) { 4606 ProcessRecord app = apps.valueAt(ia); 4607 if (app.persistent) { 4608 // we don't kill persistent processes 4609 continue; 4610 } 4611 if (app.removed) { 4612 procs.add(app); 4613 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4614 app.removed = true; 4615 procs.add(app); 4616 } 4617 } 4618 } 4619 4620 int N = procs.size(); 4621 for (int i=0; i<N; i++) { 4622 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4623 } 4624 mAllowLowerMemLevel = true; 4625 updateOomAdjLocked(); 4626 doLowMemReportIfNeededLocked(null); 4627 } 4628 } finally { 4629 Binder.restoreCallingIdentity(callingId); 4630 } 4631 } 4632 4633 @Override 4634 public void forceStopPackage(final String packageName, int userId) { 4635 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4636 != PackageManager.PERMISSION_GRANTED) { 4637 String msg = "Permission Denial: forceStopPackage() from pid=" 4638 + Binder.getCallingPid() 4639 + ", uid=" + Binder.getCallingUid() 4640 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4641 Slog.w(TAG, msg); 4642 throw new SecurityException(msg); 4643 } 4644 final int callingPid = Binder.getCallingPid(); 4645 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4646 userId, true, true, "forceStopPackage", null); 4647 long callingId = Binder.clearCallingIdentity(); 4648 try { 4649 IPackageManager pm = AppGlobals.getPackageManager(); 4650 synchronized(this) { 4651 int[] users = userId == UserHandle.USER_ALL 4652 ? getUsersLocked() : new int[] { userId }; 4653 for (int user : users) { 4654 int pkgUid = -1; 4655 try { 4656 pkgUid = pm.getPackageUid(packageName, user); 4657 } catch (RemoteException e) { 4658 } 4659 if (pkgUid == -1) { 4660 Slog.w(TAG, "Invalid packageName: " + packageName); 4661 continue; 4662 } 4663 try { 4664 pm.setPackageStoppedState(packageName, true, user); 4665 } catch (RemoteException e) { 4666 } catch (IllegalArgumentException e) { 4667 Slog.w(TAG, "Failed trying to unstop package " 4668 + packageName + ": " + e); 4669 } 4670 if (isUserRunningLocked(user, false)) { 4671 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4672 } 4673 } 4674 } 4675 } finally { 4676 Binder.restoreCallingIdentity(callingId); 4677 } 4678 } 4679 4680 /* 4681 * The pkg name and app id have to be specified. 4682 */ 4683 @Override 4684 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4685 if (pkg == null) { 4686 return; 4687 } 4688 // Make sure the uid is valid. 4689 if (appid < 0) { 4690 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4691 return; 4692 } 4693 int callerUid = Binder.getCallingUid(); 4694 // Only the system server can kill an application 4695 if (callerUid == Process.SYSTEM_UID) { 4696 // Post an aysnc message to kill the application 4697 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4698 msg.arg1 = appid; 4699 msg.arg2 = 0; 4700 Bundle bundle = new Bundle(); 4701 bundle.putString("pkg", pkg); 4702 bundle.putString("reason", reason); 4703 msg.obj = bundle; 4704 mHandler.sendMessage(msg); 4705 } else { 4706 throw new SecurityException(callerUid + " cannot kill pkg: " + 4707 pkg); 4708 } 4709 } 4710 4711 @Override 4712 public void closeSystemDialogs(String reason) { 4713 enforceNotIsolatedCaller("closeSystemDialogs"); 4714 4715 final int pid = Binder.getCallingPid(); 4716 final int uid = Binder.getCallingUid(); 4717 final long origId = Binder.clearCallingIdentity(); 4718 try { 4719 synchronized (this) { 4720 // Only allow this from foreground processes, so that background 4721 // applications can't abuse it to prevent system UI from being shown. 4722 if (uid >= Process.FIRST_APPLICATION_UID) { 4723 ProcessRecord proc; 4724 synchronized (mPidsSelfLocked) { 4725 proc = mPidsSelfLocked.get(pid); 4726 } 4727 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4728 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4729 + " from background process " + proc); 4730 return; 4731 } 4732 } 4733 closeSystemDialogsLocked(reason); 4734 } 4735 } finally { 4736 Binder.restoreCallingIdentity(origId); 4737 } 4738 } 4739 4740 void closeSystemDialogsLocked(String reason) { 4741 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4743 | Intent.FLAG_RECEIVER_FOREGROUND); 4744 if (reason != null) { 4745 intent.putExtra("reason", reason); 4746 } 4747 mWindowManager.closeSystemDialogs(reason); 4748 4749 mStackSupervisor.closeSystemDialogsLocked(); 4750 4751 broadcastIntentLocked(null, null, intent, null, 4752 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4753 Process.SYSTEM_UID, UserHandle.USER_ALL); 4754 } 4755 4756 @Override 4757 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4758 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4759 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4760 for (int i=pids.length-1; i>=0; i--) { 4761 ProcessRecord proc; 4762 int oomAdj; 4763 synchronized (this) { 4764 synchronized (mPidsSelfLocked) { 4765 proc = mPidsSelfLocked.get(pids[i]); 4766 oomAdj = proc != null ? proc.setAdj : 0; 4767 } 4768 } 4769 infos[i] = new Debug.MemoryInfo(); 4770 Debug.getMemoryInfo(pids[i], infos[i]); 4771 if (proc != null) { 4772 synchronized (this) { 4773 if (proc.thread != null && proc.setAdj == oomAdj) { 4774 // Record this for posterity if the process has been stable. 4775 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4776 infos[i].getTotalUss(), false, proc.pkgList); 4777 } 4778 } 4779 } 4780 } 4781 return infos; 4782 } 4783 4784 @Override 4785 public long[] getProcessPss(int[] pids) { 4786 enforceNotIsolatedCaller("getProcessPss"); 4787 long[] pss = new long[pids.length]; 4788 for (int i=pids.length-1; i>=0; i--) { 4789 ProcessRecord proc; 4790 int oomAdj; 4791 synchronized (this) { 4792 synchronized (mPidsSelfLocked) { 4793 proc = mPidsSelfLocked.get(pids[i]); 4794 oomAdj = proc != null ? proc.setAdj : 0; 4795 } 4796 } 4797 long[] tmpUss = new long[1]; 4798 pss[i] = Debug.getPss(pids[i], tmpUss); 4799 if (proc != null) { 4800 synchronized (this) { 4801 if (proc.thread != null && proc.setAdj == oomAdj) { 4802 // Record this for posterity if the process has been stable. 4803 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4804 } 4805 } 4806 } 4807 } 4808 return pss; 4809 } 4810 4811 @Override 4812 public void killApplicationProcess(String processName, int uid) { 4813 if (processName == null) { 4814 return; 4815 } 4816 4817 int callerUid = Binder.getCallingUid(); 4818 // Only the system server can kill an application 4819 if (callerUid == Process.SYSTEM_UID) { 4820 synchronized (this) { 4821 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4822 if (app != null && app.thread != null) { 4823 try { 4824 app.thread.scheduleSuicide(); 4825 } catch (RemoteException e) { 4826 // If the other end already died, then our work here is done. 4827 } 4828 } else { 4829 Slog.w(TAG, "Process/uid not found attempting kill of " 4830 + processName + " / " + uid); 4831 } 4832 } 4833 } else { 4834 throw new SecurityException(callerUid + " cannot kill app process: " + 4835 processName); 4836 } 4837 } 4838 4839 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4840 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4841 false, true, false, false, UserHandle.getUserId(uid), reason); 4842 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4843 Uri.fromParts("package", packageName, null)); 4844 if (!mProcessesReady) { 4845 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4846 | Intent.FLAG_RECEIVER_FOREGROUND); 4847 } 4848 intent.putExtra(Intent.EXTRA_UID, uid); 4849 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4850 broadcastIntentLocked(null, null, intent, 4851 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4852 false, false, 4853 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4854 } 4855 4856 private void forceStopUserLocked(int userId, String reason) { 4857 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4858 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4859 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4860 | Intent.FLAG_RECEIVER_FOREGROUND); 4861 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4862 broadcastIntentLocked(null, null, intent, 4863 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4864 false, false, 4865 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4866 } 4867 4868 private final boolean killPackageProcessesLocked(String packageName, int appId, 4869 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4870 boolean doit, boolean evenPersistent, String reason) { 4871 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4872 4873 // Remove all processes this package may have touched: all with the 4874 // same UID (except for the system or root user), and all whose name 4875 // matches the package name. 4876 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4877 final int NP = mProcessNames.getMap().size(); 4878 for (int ip=0; ip<NP; ip++) { 4879 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4880 final int NA = apps.size(); 4881 for (int ia=0; ia<NA; ia++) { 4882 ProcessRecord app = apps.valueAt(ia); 4883 if (app.persistent && !evenPersistent) { 4884 // we don't kill persistent processes 4885 continue; 4886 } 4887 if (app.removed) { 4888 if (doit) { 4889 procs.add(app); 4890 } 4891 continue; 4892 } 4893 4894 // Skip process if it doesn't meet our oom adj requirement. 4895 if (app.setAdj < minOomAdj) { 4896 continue; 4897 } 4898 4899 // If no package is specified, we call all processes under the 4900 // give user id. 4901 if (packageName == null) { 4902 if (app.userId != userId) { 4903 continue; 4904 } 4905 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4906 continue; 4907 } 4908 // Package has been specified, we want to hit all processes 4909 // that match it. We need to qualify this by the processes 4910 // that are running under the specified app and user ID. 4911 } else { 4912 if (UserHandle.getAppId(app.uid) != appId) { 4913 continue; 4914 } 4915 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4916 continue; 4917 } 4918 if (!app.pkgList.containsKey(packageName)) { 4919 continue; 4920 } 4921 } 4922 4923 // Process has passed all conditions, kill it! 4924 if (!doit) { 4925 return true; 4926 } 4927 app.removed = true; 4928 procs.add(app); 4929 } 4930 } 4931 4932 int N = procs.size(); 4933 for (int i=0; i<N; i++) { 4934 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4935 } 4936 updateOomAdjLocked(); 4937 return N > 0; 4938 } 4939 4940 private final boolean forceStopPackageLocked(String name, int appId, 4941 boolean callerWillRestart, boolean purgeCache, boolean doit, 4942 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4943 int i; 4944 int N; 4945 4946 if (userId == UserHandle.USER_ALL && name == null) { 4947 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4948 } 4949 4950 if (appId < 0 && name != null) { 4951 try { 4952 appId = UserHandle.getAppId( 4953 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4954 } catch (RemoteException e) { 4955 } 4956 } 4957 4958 if (doit) { 4959 if (name != null) { 4960 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4961 + " user=" + userId + ": " + reason); 4962 } else { 4963 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4964 } 4965 4966 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4967 for (int ip=pmap.size()-1; ip>=0; ip--) { 4968 SparseArray<Long> ba = pmap.valueAt(ip); 4969 for (i=ba.size()-1; i>=0; i--) { 4970 boolean remove = false; 4971 final int entUid = ba.keyAt(i); 4972 if (name != null) { 4973 if (userId == UserHandle.USER_ALL) { 4974 if (UserHandle.getAppId(entUid) == appId) { 4975 remove = true; 4976 } 4977 } else { 4978 if (entUid == UserHandle.getUid(userId, appId)) { 4979 remove = true; 4980 } 4981 } 4982 } else if (UserHandle.getUserId(entUid) == userId) { 4983 remove = true; 4984 } 4985 if (remove) { 4986 ba.removeAt(i); 4987 } 4988 } 4989 if (ba.size() == 0) { 4990 pmap.removeAt(ip); 4991 } 4992 } 4993 } 4994 4995 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4996 -100, callerWillRestart, true, doit, evenPersistent, 4997 name == null ? ("stop user " + userId) : ("stop " + name)); 4998 4999 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5000 if (!doit) { 5001 return true; 5002 } 5003 didSomething = true; 5004 } 5005 5006 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5007 if (!doit) { 5008 return true; 5009 } 5010 didSomething = true; 5011 } 5012 5013 if (name == null) { 5014 // Remove all sticky broadcasts from this user. 5015 mStickyBroadcasts.remove(userId); 5016 } 5017 5018 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5019 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5020 userId, providers)) { 5021 if (!doit) { 5022 return true; 5023 } 5024 didSomething = true; 5025 } 5026 N = providers.size(); 5027 for (i=0; i<N; i++) { 5028 removeDyingProviderLocked(null, providers.get(i), true); 5029 } 5030 5031 // Remove transient permissions granted from/to this package/user 5032 removeUriPermissionsForPackageLocked(name, userId, false); 5033 5034 if (name == null || uninstalling) { 5035 // Remove pending intents. For now we only do this when force 5036 // stopping users, because we have some problems when doing this 5037 // for packages -- app widgets are not currently cleaned up for 5038 // such packages, so they can be left with bad pending intents. 5039 if (mIntentSenderRecords.size() > 0) { 5040 Iterator<WeakReference<PendingIntentRecord>> it 5041 = mIntentSenderRecords.values().iterator(); 5042 while (it.hasNext()) { 5043 WeakReference<PendingIntentRecord> wpir = it.next(); 5044 if (wpir == null) { 5045 it.remove(); 5046 continue; 5047 } 5048 PendingIntentRecord pir = wpir.get(); 5049 if (pir == null) { 5050 it.remove(); 5051 continue; 5052 } 5053 if (name == null) { 5054 // Stopping user, remove all objects for the user. 5055 if (pir.key.userId != userId) { 5056 // Not the same user, skip it. 5057 continue; 5058 } 5059 } else { 5060 if (UserHandle.getAppId(pir.uid) != appId) { 5061 // Different app id, skip it. 5062 continue; 5063 } 5064 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5065 // Different user, skip it. 5066 continue; 5067 } 5068 if (!pir.key.packageName.equals(name)) { 5069 // Different package, skip it. 5070 continue; 5071 } 5072 } 5073 if (!doit) { 5074 return true; 5075 } 5076 didSomething = true; 5077 it.remove(); 5078 pir.canceled = true; 5079 if (pir.key.activity != null) { 5080 pir.key.activity.pendingResults.remove(pir.ref); 5081 } 5082 } 5083 } 5084 } 5085 5086 if (doit) { 5087 if (purgeCache && name != null) { 5088 AttributeCache ac = AttributeCache.instance(); 5089 if (ac != null) { 5090 ac.removePackage(name); 5091 } 5092 } 5093 if (mBooted) { 5094 mStackSupervisor.resumeTopActivitiesLocked(); 5095 mStackSupervisor.scheduleIdleLocked(); 5096 } 5097 } 5098 5099 return didSomething; 5100 } 5101 5102 private final boolean removeProcessLocked(ProcessRecord app, 5103 boolean callerWillRestart, boolean allowRestart, String reason) { 5104 final String name = app.processName; 5105 final int uid = app.uid; 5106 if (DEBUG_PROCESSES) Slog.d( 5107 TAG, "Force removing proc " + app.toShortString() + " (" + name 5108 + "/" + uid + ")"); 5109 5110 mProcessNames.remove(name, uid); 5111 mIsolatedProcesses.remove(app.uid); 5112 if (mHeavyWeightProcess == app) { 5113 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5114 mHeavyWeightProcess.userId, 0)); 5115 mHeavyWeightProcess = null; 5116 } 5117 boolean needRestart = false; 5118 if (app.pid > 0 && app.pid != MY_PID) { 5119 int pid = app.pid; 5120 synchronized (mPidsSelfLocked) { 5121 mPidsSelfLocked.remove(pid); 5122 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5123 } 5124 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5125 app.processName, app.info.uid); 5126 if (app.isolated) { 5127 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5128 } 5129 killUnneededProcessLocked(app, reason); 5130 handleAppDiedLocked(app, true, allowRestart); 5131 removeLruProcessLocked(app); 5132 5133 if (app.persistent && !app.isolated) { 5134 if (!callerWillRestart) { 5135 addAppLocked(app.info, false, null /* ABI override */); 5136 } else { 5137 needRestart = true; 5138 } 5139 } 5140 } else { 5141 mRemovedProcesses.add(app); 5142 } 5143 5144 return needRestart; 5145 } 5146 5147 private final void processStartTimedOutLocked(ProcessRecord app) { 5148 final int pid = app.pid; 5149 boolean gone = false; 5150 synchronized (mPidsSelfLocked) { 5151 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5152 if (knownApp != null && knownApp.thread == null) { 5153 mPidsSelfLocked.remove(pid); 5154 gone = true; 5155 } 5156 } 5157 5158 if (gone) { 5159 Slog.w(TAG, "Process " + app + " failed to attach"); 5160 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5161 pid, app.uid, app.processName); 5162 mProcessNames.remove(app.processName, app.uid); 5163 mIsolatedProcesses.remove(app.uid); 5164 if (mHeavyWeightProcess == app) { 5165 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5166 mHeavyWeightProcess.userId, 0)); 5167 mHeavyWeightProcess = null; 5168 } 5169 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5170 app.processName, app.info.uid); 5171 if (app.isolated) { 5172 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5173 } 5174 // Take care of any launching providers waiting for this process. 5175 checkAppInLaunchingProvidersLocked(app, true); 5176 // Take care of any services that are waiting for the process. 5177 mServices.processStartTimedOutLocked(app); 5178 killUnneededProcessLocked(app, "start timeout"); 5179 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5180 Slog.w(TAG, "Unattached app died before backup, skipping"); 5181 try { 5182 IBackupManager bm = IBackupManager.Stub.asInterface( 5183 ServiceManager.getService(Context.BACKUP_SERVICE)); 5184 bm.agentDisconnected(app.info.packageName); 5185 } catch (RemoteException e) { 5186 // Can't happen; the backup manager is local 5187 } 5188 } 5189 if (isPendingBroadcastProcessLocked(pid)) { 5190 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5191 skipPendingBroadcastLocked(pid); 5192 } 5193 } else { 5194 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5195 } 5196 } 5197 5198 private final boolean attachApplicationLocked(IApplicationThread thread, 5199 int pid) { 5200 5201 // Find the application record that is being attached... either via 5202 // the pid if we are running in multiple processes, or just pull the 5203 // next app record if we are emulating process with anonymous threads. 5204 ProcessRecord app; 5205 if (pid != MY_PID && pid >= 0) { 5206 synchronized (mPidsSelfLocked) { 5207 app = mPidsSelfLocked.get(pid); 5208 } 5209 } else { 5210 app = null; 5211 } 5212 5213 if (app == null) { 5214 Slog.w(TAG, "No pending application record for pid " + pid 5215 + " (IApplicationThread " + thread + "); dropping process"); 5216 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5217 if (pid > 0 && pid != MY_PID) { 5218 Process.killProcessQuiet(pid); 5219 } else { 5220 try { 5221 thread.scheduleExit(); 5222 } catch (Exception e) { 5223 // Ignore exceptions. 5224 } 5225 } 5226 return false; 5227 } 5228 5229 // If this application record is still attached to a previous 5230 // process, clean it up now. 5231 if (app.thread != null) { 5232 handleAppDiedLocked(app, true, true); 5233 } 5234 5235 // Tell the process all about itself. 5236 5237 if (localLOGV) Slog.v( 5238 TAG, "Binding process pid " + pid + " to record " + app); 5239 5240 final String processName = app.processName; 5241 try { 5242 AppDeathRecipient adr = new AppDeathRecipient( 5243 app, pid, thread); 5244 thread.asBinder().linkToDeath(adr, 0); 5245 app.deathRecipient = adr; 5246 } catch (RemoteException e) { 5247 app.resetPackageList(mProcessStats); 5248 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5249 return false; 5250 } 5251 5252 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5253 5254 app.makeActive(thread, mProcessStats); 5255 app.curAdj = app.setAdj = -100; 5256 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5257 app.forcingToForeground = null; 5258 updateProcessForegroundLocked(app, false, false); 5259 app.hasShownUi = false; 5260 app.debugging = false; 5261 app.cached = false; 5262 5263 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5264 5265 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5266 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5267 5268 if (!normalMode) { 5269 Slog.i(TAG, "Launching preboot mode app: " + app); 5270 } 5271 5272 if (localLOGV) Slog.v( 5273 TAG, "New app record " + app 5274 + " thread=" + thread.asBinder() + " pid=" + pid); 5275 try { 5276 int testMode = IApplicationThread.DEBUG_OFF; 5277 if (mDebugApp != null && mDebugApp.equals(processName)) { 5278 testMode = mWaitForDebugger 5279 ? IApplicationThread.DEBUG_WAIT 5280 : IApplicationThread.DEBUG_ON; 5281 app.debugging = true; 5282 if (mDebugTransient) { 5283 mDebugApp = mOrigDebugApp; 5284 mWaitForDebugger = mOrigWaitForDebugger; 5285 } 5286 } 5287 String profileFile = app.instrumentationProfileFile; 5288 ParcelFileDescriptor profileFd = null; 5289 boolean profileAutoStop = false; 5290 if (mProfileApp != null && mProfileApp.equals(processName)) { 5291 mProfileProc = app; 5292 profileFile = mProfileFile; 5293 profileFd = mProfileFd; 5294 profileAutoStop = mAutoStopProfiler; 5295 } 5296 boolean enableOpenGlTrace = false; 5297 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5298 enableOpenGlTrace = true; 5299 mOpenGlTraceApp = null; 5300 } 5301 5302 // If the app is being launched for restore or full backup, set it up specially 5303 boolean isRestrictedBackupMode = false; 5304 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5305 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5306 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5307 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5308 } 5309 5310 ensurePackageDexOpt(app.instrumentationInfo != null 5311 ? app.instrumentationInfo.packageName 5312 : app.info.packageName); 5313 if (app.instrumentationClass != null) { 5314 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5315 } 5316 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5317 + processName + " with config " + mConfiguration); 5318 ApplicationInfo appInfo = app.instrumentationInfo != null 5319 ? app.instrumentationInfo : app.info; 5320 app.compat = compatibilityInfoForPackageLocked(appInfo); 5321 if (profileFd != null) { 5322 profileFd = profileFd.dup(); 5323 } 5324 thread.bindApplication(processName, appInfo, providers, 5325 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5326 app.instrumentationArguments, app.instrumentationWatcher, 5327 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5328 isRestrictedBackupMode || !normalMode, app.persistent, 5329 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5330 mCoreSettingsObserver.getCoreSettingsLocked()); 5331 updateLruProcessLocked(app, false, null); 5332 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5333 } catch (Exception e) { 5334 // todo: Yikes! What should we do? For now we will try to 5335 // start another process, but that could easily get us in 5336 // an infinite loop of restarting processes... 5337 Slog.w(TAG, "Exception thrown during bind!", e); 5338 5339 app.resetPackageList(mProcessStats); 5340 app.unlinkDeathRecipient(); 5341 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5342 return false; 5343 } 5344 5345 // Remove this record from the list of starting applications. 5346 mPersistentStartingProcesses.remove(app); 5347 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5348 "Attach application locked removing on hold: " + app); 5349 mProcessesOnHold.remove(app); 5350 5351 boolean badApp = false; 5352 boolean didSomething = false; 5353 5354 // See if the top visible activity is waiting to run in this process... 5355 if (normalMode) { 5356 try { 5357 if (mStackSupervisor.attachApplicationLocked(app)) { 5358 didSomething = true; 5359 } 5360 } catch (Exception e) { 5361 badApp = true; 5362 } 5363 } 5364 5365 // Find any services that should be running in this process... 5366 if (!badApp) { 5367 try { 5368 didSomething |= mServices.attachApplicationLocked(app, processName); 5369 } catch (Exception e) { 5370 badApp = true; 5371 } 5372 } 5373 5374 // Check if a next-broadcast receiver is in this process... 5375 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5376 try { 5377 didSomething |= sendPendingBroadcastsLocked(app); 5378 } catch (Exception e) { 5379 // If the app died trying to launch the receiver we declare it 'bad' 5380 badApp = true; 5381 } 5382 } 5383 5384 // Check whether the next backup agent is in this process... 5385 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5386 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5387 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5388 try { 5389 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5390 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5391 mBackupTarget.backupMode); 5392 } catch (Exception e) { 5393 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5394 e.printStackTrace(); 5395 } 5396 } 5397 5398 if (badApp) { 5399 // todo: Also need to kill application to deal with all 5400 // kinds of exceptions. 5401 handleAppDiedLocked(app, false, true); 5402 return false; 5403 } 5404 5405 if (!didSomething) { 5406 updateOomAdjLocked(); 5407 } 5408 5409 return true; 5410 } 5411 5412 @Override 5413 public final void attachApplication(IApplicationThread thread) { 5414 synchronized (this) { 5415 int callingPid = Binder.getCallingPid(); 5416 final long origId = Binder.clearCallingIdentity(); 5417 attachApplicationLocked(thread, callingPid); 5418 Binder.restoreCallingIdentity(origId); 5419 } 5420 } 5421 5422 @Override 5423 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5424 final long origId = Binder.clearCallingIdentity(); 5425 synchronized (this) { 5426 ActivityStack stack = ActivityRecord.getStackLocked(token); 5427 if (stack != null) { 5428 ActivityRecord r = 5429 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5430 if (stopProfiling) { 5431 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5432 try { 5433 mProfileFd.close(); 5434 } catch (IOException e) { 5435 } 5436 clearProfilerLocked(); 5437 } 5438 } 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 void enableScreenAfterBoot() { 5445 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5446 SystemClock.uptimeMillis()); 5447 mWindowManager.enableScreenAfterBoot(); 5448 5449 synchronized (this) { 5450 updateEventDispatchingLocked(); 5451 } 5452 } 5453 5454 @Override 5455 public void showBootMessage(final CharSequence msg, final boolean always) { 5456 enforceNotIsolatedCaller("showBootMessage"); 5457 mWindowManager.showBootMessage(msg, always); 5458 } 5459 5460 @Override 5461 public void dismissKeyguardOnNextActivity() { 5462 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5463 final long token = Binder.clearCallingIdentity(); 5464 try { 5465 synchronized (this) { 5466 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5467 if (mLockScreenShown) { 5468 mLockScreenShown = false; 5469 comeOutOfSleepIfNeededLocked(); 5470 } 5471 mStackSupervisor.setDismissKeyguard(true); 5472 } 5473 } finally { 5474 Binder.restoreCallingIdentity(token); 5475 } 5476 } 5477 5478 final void finishBooting() { 5479 // Register receivers to handle package update events 5480 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5481 5482 synchronized (this) { 5483 // Ensure that any processes we had put on hold are now started 5484 // up. 5485 final int NP = mProcessesOnHold.size(); 5486 if (NP > 0) { 5487 ArrayList<ProcessRecord> procs = 5488 new ArrayList<ProcessRecord>(mProcessesOnHold); 5489 for (int ip=0; ip<NP; ip++) { 5490 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5491 + procs.get(ip)); 5492 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5493 } 5494 } 5495 5496 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5497 // Start looking for apps that are abusing wake locks. 5498 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5499 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5500 // Tell anyone interested that we are done booting! 5501 SystemProperties.set("sys.boot_completed", "1"); 5502 SystemProperties.set("dev.bootcomplete", "1"); 5503 for (int i=0; i<mStartedUsers.size(); i++) { 5504 UserStartedState uss = mStartedUsers.valueAt(i); 5505 if (uss.mState == UserStartedState.STATE_BOOTING) { 5506 uss.mState = UserStartedState.STATE_RUNNING; 5507 final int userId = mStartedUsers.keyAt(i); 5508 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5509 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5510 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5511 broadcastIntentLocked(null, null, intent, null, 5512 new IIntentReceiver.Stub() { 5513 @Override 5514 public void performReceive(Intent intent, int resultCode, 5515 String data, Bundle extras, boolean ordered, 5516 boolean sticky, int sendingUser) { 5517 synchronized (ActivityManagerService.this) { 5518 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5519 true, false); 5520 } 5521 } 5522 }, 5523 0, null, null, 5524 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5525 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5526 userId); 5527 } 5528 } 5529 scheduleStartProfilesLocked(); 5530 } 5531 } 5532 } 5533 5534 final void ensureBootCompleted() { 5535 boolean booting; 5536 boolean enableScreen; 5537 synchronized (this) { 5538 booting = mBooting; 5539 mBooting = false; 5540 enableScreen = !mBooted; 5541 mBooted = true; 5542 } 5543 5544 if (booting) { 5545 finishBooting(); 5546 } 5547 5548 if (enableScreen) { 5549 enableScreenAfterBoot(); 5550 } 5551 } 5552 5553 @Override 5554 public final void activityResumed(IBinder token) { 5555 final long origId = Binder.clearCallingIdentity(); 5556 synchronized(this) { 5557 ActivityStack stack = ActivityRecord.getStackLocked(token); 5558 if (stack != null) { 5559 ActivityRecord.activityResumedLocked(token); 5560 } 5561 } 5562 Binder.restoreCallingIdentity(origId); 5563 } 5564 5565 @Override 5566 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5567 final long origId = Binder.clearCallingIdentity(); 5568 synchronized(this) { 5569 ActivityStack stack = ActivityRecord.getStackLocked(token); 5570 if (stack != null) { 5571 stack.activityPausedLocked(token, false, persistentState); 5572 } 5573 } 5574 Binder.restoreCallingIdentity(origId); 5575 } 5576 5577 @Override 5578 public final void activityStopped(IBinder token, Bundle icicle, 5579 PersistableBundle persistentState, CharSequence description) { 5580 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5581 5582 // Refuse possible leaked file descriptors 5583 if (icicle != null && icicle.hasFileDescriptors()) { 5584 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5585 } 5586 5587 final long origId = Binder.clearCallingIdentity(); 5588 5589 synchronized (this) { 5590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5591 if (r != null) { 5592 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5593 } 5594 } 5595 5596 trimApplications(); 5597 5598 Binder.restoreCallingIdentity(origId); 5599 } 5600 5601 @Override 5602 public final void activityDestroyed(IBinder token) { 5603 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5604 synchronized (this) { 5605 ActivityStack stack = ActivityRecord.getStackLocked(token); 5606 if (stack != null) { 5607 stack.activityDestroyedLocked(token); 5608 } 5609 } 5610 } 5611 5612 @Override 5613 public String getCallingPackage(IBinder token) { 5614 synchronized (this) { 5615 ActivityRecord r = getCallingRecordLocked(token); 5616 return r != null ? r.info.packageName : null; 5617 } 5618 } 5619 5620 @Override 5621 public ComponentName getCallingActivity(IBinder token) { 5622 synchronized (this) { 5623 ActivityRecord r = getCallingRecordLocked(token); 5624 return r != null ? r.intent.getComponent() : null; 5625 } 5626 } 5627 5628 private ActivityRecord getCallingRecordLocked(IBinder token) { 5629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5630 if (r == null) { 5631 return null; 5632 } 5633 return r.resultTo; 5634 } 5635 5636 @Override 5637 public ComponentName getActivityClassForToken(IBinder token) { 5638 synchronized(this) { 5639 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5640 if (r == null) { 5641 return null; 5642 } 5643 return r.intent.getComponent(); 5644 } 5645 } 5646 5647 @Override 5648 public String getPackageForToken(IBinder token) { 5649 synchronized(this) { 5650 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5651 if (r == null) { 5652 return null; 5653 } 5654 return r.packageName; 5655 } 5656 } 5657 5658 @Override 5659 public IIntentSender getIntentSender(int type, 5660 String packageName, IBinder token, String resultWho, 5661 int requestCode, Intent[] intents, String[] resolvedTypes, 5662 int flags, Bundle options, int userId) { 5663 enforceNotIsolatedCaller("getIntentSender"); 5664 // Refuse possible leaked file descriptors 5665 if (intents != null) { 5666 if (intents.length < 1) { 5667 throw new IllegalArgumentException("Intents array length must be >= 1"); 5668 } 5669 for (int i=0; i<intents.length; i++) { 5670 Intent intent = intents[i]; 5671 if (intent != null) { 5672 if (intent.hasFileDescriptors()) { 5673 throw new IllegalArgumentException("File descriptors passed in Intent"); 5674 } 5675 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5676 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5677 throw new IllegalArgumentException( 5678 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5679 } 5680 intents[i] = new Intent(intent); 5681 } 5682 } 5683 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5684 throw new IllegalArgumentException( 5685 "Intent array length does not match resolvedTypes length"); 5686 } 5687 } 5688 if (options != null) { 5689 if (options.hasFileDescriptors()) { 5690 throw new IllegalArgumentException("File descriptors passed in options"); 5691 } 5692 } 5693 5694 synchronized(this) { 5695 int callingUid = Binder.getCallingUid(); 5696 int origUserId = userId; 5697 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5698 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5699 "getIntentSender", null); 5700 if (origUserId == UserHandle.USER_CURRENT) { 5701 // We don't want to evaluate this until the pending intent is 5702 // actually executed. However, we do want to always do the 5703 // security checking for it above. 5704 userId = UserHandle.USER_CURRENT; 5705 } 5706 try { 5707 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5708 int uid = AppGlobals.getPackageManager() 5709 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5710 if (!UserHandle.isSameApp(callingUid, uid)) { 5711 String msg = "Permission Denial: getIntentSender() from pid=" 5712 + Binder.getCallingPid() 5713 + ", uid=" + Binder.getCallingUid() 5714 + ", (need uid=" + uid + ")" 5715 + " is not allowed to send as package " + packageName; 5716 Slog.w(TAG, msg); 5717 throw new SecurityException(msg); 5718 } 5719 } 5720 5721 return getIntentSenderLocked(type, packageName, callingUid, userId, 5722 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5723 5724 } catch (RemoteException e) { 5725 throw new SecurityException(e); 5726 } 5727 } 5728 } 5729 5730 IIntentSender getIntentSenderLocked(int type, String packageName, 5731 int callingUid, int userId, IBinder token, String resultWho, 5732 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5733 Bundle options) { 5734 if (DEBUG_MU) 5735 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5736 ActivityRecord activity = null; 5737 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5738 activity = ActivityRecord.isInStackLocked(token); 5739 if (activity == null) { 5740 return null; 5741 } 5742 if (activity.finishing) { 5743 return null; 5744 } 5745 } 5746 5747 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5748 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5749 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5750 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5751 |PendingIntent.FLAG_UPDATE_CURRENT); 5752 5753 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5754 type, packageName, activity, resultWho, 5755 requestCode, intents, resolvedTypes, flags, options, userId); 5756 WeakReference<PendingIntentRecord> ref; 5757 ref = mIntentSenderRecords.get(key); 5758 PendingIntentRecord rec = ref != null ? ref.get() : null; 5759 if (rec != null) { 5760 if (!cancelCurrent) { 5761 if (updateCurrent) { 5762 if (rec.key.requestIntent != null) { 5763 rec.key.requestIntent.replaceExtras(intents != null ? 5764 intents[intents.length - 1] : null); 5765 } 5766 if (intents != null) { 5767 intents[intents.length-1] = rec.key.requestIntent; 5768 rec.key.allIntents = intents; 5769 rec.key.allResolvedTypes = resolvedTypes; 5770 } else { 5771 rec.key.allIntents = null; 5772 rec.key.allResolvedTypes = null; 5773 } 5774 } 5775 return rec; 5776 } 5777 rec.canceled = true; 5778 mIntentSenderRecords.remove(key); 5779 } 5780 if (noCreate) { 5781 return rec; 5782 } 5783 rec = new PendingIntentRecord(this, key, callingUid); 5784 mIntentSenderRecords.put(key, rec.ref); 5785 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5786 if (activity.pendingResults == null) { 5787 activity.pendingResults 5788 = new HashSet<WeakReference<PendingIntentRecord>>(); 5789 } 5790 activity.pendingResults.add(rec.ref); 5791 } 5792 return rec; 5793 } 5794 5795 @Override 5796 public void cancelIntentSender(IIntentSender sender) { 5797 if (!(sender instanceof PendingIntentRecord)) { 5798 return; 5799 } 5800 synchronized(this) { 5801 PendingIntentRecord rec = (PendingIntentRecord)sender; 5802 try { 5803 int uid = AppGlobals.getPackageManager() 5804 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5805 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5806 String msg = "Permission Denial: cancelIntentSender() from pid=" 5807 + Binder.getCallingPid() 5808 + ", uid=" + Binder.getCallingUid() 5809 + " is not allowed to cancel packges " 5810 + rec.key.packageName; 5811 Slog.w(TAG, msg); 5812 throw new SecurityException(msg); 5813 } 5814 } catch (RemoteException e) { 5815 throw new SecurityException(e); 5816 } 5817 cancelIntentSenderLocked(rec, true); 5818 } 5819 } 5820 5821 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5822 rec.canceled = true; 5823 mIntentSenderRecords.remove(rec.key); 5824 if (cleanActivity && rec.key.activity != null) { 5825 rec.key.activity.pendingResults.remove(rec.ref); 5826 } 5827 } 5828 5829 @Override 5830 public String getPackageForIntentSender(IIntentSender pendingResult) { 5831 if (!(pendingResult instanceof PendingIntentRecord)) { 5832 return null; 5833 } 5834 try { 5835 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5836 return res.key.packageName; 5837 } catch (ClassCastException e) { 5838 } 5839 return null; 5840 } 5841 5842 @Override 5843 public int getUidForIntentSender(IIntentSender sender) { 5844 if (sender instanceof PendingIntentRecord) { 5845 try { 5846 PendingIntentRecord res = (PendingIntentRecord)sender; 5847 return res.uid; 5848 } catch (ClassCastException e) { 5849 } 5850 } 5851 return -1; 5852 } 5853 5854 @Override 5855 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5856 if (!(pendingResult instanceof PendingIntentRecord)) { 5857 return false; 5858 } 5859 try { 5860 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5861 if (res.key.allIntents == null) { 5862 return false; 5863 } 5864 for (int i=0; i<res.key.allIntents.length; i++) { 5865 Intent intent = res.key.allIntents[i]; 5866 if (intent.getPackage() != null && intent.getComponent() != null) { 5867 return false; 5868 } 5869 } 5870 return true; 5871 } catch (ClassCastException e) { 5872 } 5873 return false; 5874 } 5875 5876 @Override 5877 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5878 if (!(pendingResult instanceof PendingIntentRecord)) { 5879 return false; 5880 } 5881 try { 5882 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5883 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5884 return true; 5885 } 5886 return false; 5887 } catch (ClassCastException e) { 5888 } 5889 return false; 5890 } 5891 5892 @Override 5893 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5894 if (!(pendingResult instanceof PendingIntentRecord)) { 5895 return null; 5896 } 5897 try { 5898 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5899 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5900 } catch (ClassCastException e) { 5901 } 5902 return null; 5903 } 5904 5905 @Override 5906 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5907 if (!(pendingResult instanceof PendingIntentRecord)) { 5908 return null; 5909 } 5910 try { 5911 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5912 Intent intent = res.key.requestIntent; 5913 if (intent != null) { 5914 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5915 || res.lastTagPrefix.equals(prefix))) { 5916 return res.lastTag; 5917 } 5918 res.lastTagPrefix = prefix; 5919 StringBuilder sb = new StringBuilder(128); 5920 if (prefix != null) { 5921 sb.append(prefix); 5922 } 5923 if (intent.getAction() != null) { 5924 sb.append(intent.getAction()); 5925 } else if (intent.getComponent() != null) { 5926 intent.getComponent().appendShortString(sb); 5927 } else { 5928 sb.append("?"); 5929 } 5930 return res.lastTag = sb.toString(); 5931 } 5932 } catch (ClassCastException e) { 5933 } 5934 return null; 5935 } 5936 5937 @Override 5938 public void setProcessLimit(int max) { 5939 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5940 "setProcessLimit()"); 5941 synchronized (this) { 5942 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5943 mProcessLimitOverride = max; 5944 } 5945 trimApplications(); 5946 } 5947 5948 @Override 5949 public int getProcessLimit() { 5950 synchronized (this) { 5951 return mProcessLimitOverride; 5952 } 5953 } 5954 5955 void foregroundTokenDied(ForegroundToken token) { 5956 synchronized (ActivityManagerService.this) { 5957 synchronized (mPidsSelfLocked) { 5958 ForegroundToken cur 5959 = mForegroundProcesses.get(token.pid); 5960 if (cur != token) { 5961 return; 5962 } 5963 mForegroundProcesses.remove(token.pid); 5964 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5965 if (pr == null) { 5966 return; 5967 } 5968 pr.forcingToForeground = null; 5969 updateProcessForegroundLocked(pr, false, false); 5970 } 5971 updateOomAdjLocked(); 5972 } 5973 } 5974 5975 @Override 5976 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5977 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5978 "setProcessForeground()"); 5979 synchronized(this) { 5980 boolean changed = false; 5981 5982 synchronized (mPidsSelfLocked) { 5983 ProcessRecord pr = mPidsSelfLocked.get(pid); 5984 if (pr == null && isForeground) { 5985 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5986 return; 5987 } 5988 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5989 if (oldToken != null) { 5990 oldToken.token.unlinkToDeath(oldToken, 0); 5991 mForegroundProcesses.remove(pid); 5992 if (pr != null) { 5993 pr.forcingToForeground = null; 5994 } 5995 changed = true; 5996 } 5997 if (isForeground && token != null) { 5998 ForegroundToken newToken = new ForegroundToken() { 5999 @Override 6000 public void binderDied() { 6001 foregroundTokenDied(this); 6002 } 6003 }; 6004 newToken.pid = pid; 6005 newToken.token = token; 6006 try { 6007 token.linkToDeath(newToken, 0); 6008 mForegroundProcesses.put(pid, newToken); 6009 pr.forcingToForeground = token; 6010 changed = true; 6011 } catch (RemoteException e) { 6012 // If the process died while doing this, we will later 6013 // do the cleanup with the process death link. 6014 } 6015 } 6016 } 6017 6018 if (changed) { 6019 updateOomAdjLocked(); 6020 } 6021 } 6022 } 6023 6024 // ========================================================= 6025 // PERMISSIONS 6026 // ========================================================= 6027 6028 static class PermissionController extends IPermissionController.Stub { 6029 ActivityManagerService mActivityManagerService; 6030 PermissionController(ActivityManagerService activityManagerService) { 6031 mActivityManagerService = activityManagerService; 6032 } 6033 6034 @Override 6035 public boolean checkPermission(String permission, int pid, int uid) { 6036 return mActivityManagerService.checkPermission(permission, pid, 6037 uid) == PackageManager.PERMISSION_GRANTED; 6038 } 6039 } 6040 6041 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6042 @Override 6043 public int checkComponentPermission(String permission, int pid, int uid, 6044 int owningUid, boolean exported) { 6045 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6046 owningUid, exported); 6047 } 6048 6049 @Override 6050 public Object getAMSLock() { 6051 return ActivityManagerService.this; 6052 } 6053 } 6054 6055 /** 6056 * This can be called with or without the global lock held. 6057 */ 6058 int checkComponentPermission(String permission, int pid, int uid, 6059 int owningUid, boolean exported) { 6060 // We might be performing an operation on behalf of an indirect binder 6061 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6062 // client identity accordingly before proceeding. 6063 Identity tlsIdentity = sCallerIdentity.get(); 6064 if (tlsIdentity != null) { 6065 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6066 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6067 uid = tlsIdentity.uid; 6068 pid = tlsIdentity.pid; 6069 } 6070 6071 if (pid == MY_PID) { 6072 return PackageManager.PERMISSION_GRANTED; 6073 } 6074 6075 return ActivityManager.checkComponentPermission(permission, uid, 6076 owningUid, exported); 6077 } 6078 6079 /** 6080 * As the only public entry point for permissions checking, this method 6081 * can enforce the semantic that requesting a check on a null global 6082 * permission is automatically denied. (Internally a null permission 6083 * string is used when calling {@link #checkComponentPermission} in cases 6084 * when only uid-based security is needed.) 6085 * 6086 * This can be called with or without the global lock held. 6087 */ 6088 @Override 6089 public int checkPermission(String permission, int pid, int uid) { 6090 if (permission == null) { 6091 return PackageManager.PERMISSION_DENIED; 6092 } 6093 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6094 } 6095 6096 /** 6097 * Binder IPC calls go through the public entry point. 6098 * This can be called with or without the global lock held. 6099 */ 6100 int checkCallingPermission(String permission) { 6101 return checkPermission(permission, 6102 Binder.getCallingPid(), 6103 UserHandle.getAppId(Binder.getCallingUid())); 6104 } 6105 6106 /** 6107 * This can be called with or without the global lock held. 6108 */ 6109 void enforceCallingPermission(String permission, String func) { 6110 if (checkCallingPermission(permission) 6111 == PackageManager.PERMISSION_GRANTED) { 6112 return; 6113 } 6114 6115 String msg = "Permission Denial: " + func + " from pid=" 6116 + Binder.getCallingPid() 6117 + ", uid=" + Binder.getCallingUid() 6118 + " requires " + permission; 6119 Slog.w(TAG, msg); 6120 throw new SecurityException(msg); 6121 } 6122 6123 /** 6124 * Determine if UID is holding permissions required to access {@link Uri} in 6125 * the given {@link ProviderInfo}. Final permission checking is always done 6126 * in {@link ContentProvider}. 6127 */ 6128 private final boolean checkHoldingPermissionsLocked( 6129 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6130 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6131 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6132 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6133 return false; 6134 } 6135 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6136 } 6137 6138 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6139 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6140 if (pi.applicationInfo.uid == uid) { 6141 return true; 6142 } else if (!pi.exported) { 6143 return false; 6144 } 6145 6146 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6147 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6148 try { 6149 // check if target holds top-level <provider> permissions 6150 if (!readMet && pi.readPermission != null && considerUidPermissions 6151 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6152 readMet = true; 6153 } 6154 if (!writeMet && pi.writePermission != null && considerUidPermissions 6155 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6156 writeMet = true; 6157 } 6158 6159 // track if unprotected read/write is allowed; any denied 6160 // <path-permission> below removes this ability 6161 boolean allowDefaultRead = pi.readPermission == null; 6162 boolean allowDefaultWrite = pi.writePermission == null; 6163 6164 // check if target holds any <path-permission> that match uri 6165 final PathPermission[] pps = pi.pathPermissions; 6166 if (pps != null) { 6167 final String path = grantUri.uri.getPath(); 6168 int i = pps.length; 6169 while (i > 0 && (!readMet || !writeMet)) { 6170 i--; 6171 PathPermission pp = pps[i]; 6172 if (pp.match(path)) { 6173 if (!readMet) { 6174 final String pprperm = pp.getReadPermission(); 6175 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6176 + pprperm + " for " + pp.getPath() 6177 + ": match=" + pp.match(path) 6178 + " check=" + pm.checkUidPermission(pprperm, uid)); 6179 if (pprperm != null) { 6180 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6181 == PERMISSION_GRANTED) { 6182 readMet = true; 6183 } else { 6184 allowDefaultRead = false; 6185 } 6186 } 6187 } 6188 if (!writeMet) { 6189 final String ppwperm = pp.getWritePermission(); 6190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6191 + ppwperm + " for " + pp.getPath() 6192 + ": match=" + pp.match(path) 6193 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6194 if (ppwperm != null) { 6195 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6196 == PERMISSION_GRANTED) { 6197 writeMet = true; 6198 } else { 6199 allowDefaultWrite = false; 6200 } 6201 } 6202 } 6203 } 6204 } 6205 } 6206 6207 // grant unprotected <provider> read/write, if not blocked by 6208 // <path-permission> above 6209 if (allowDefaultRead) readMet = true; 6210 if (allowDefaultWrite) writeMet = true; 6211 6212 } catch (RemoteException e) { 6213 return false; 6214 } 6215 6216 return readMet && writeMet; 6217 } 6218 6219 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6220 ProviderInfo pi = null; 6221 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6222 if (cpr != null) { 6223 pi = cpr.info; 6224 } else { 6225 try { 6226 pi = AppGlobals.getPackageManager().resolveContentProvider( 6227 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6228 } catch (RemoteException ex) { 6229 } 6230 } 6231 return pi; 6232 } 6233 6234 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6235 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6236 if (targetUris != null) { 6237 return targetUris.get(grantUri); 6238 } 6239 return null; 6240 } 6241 6242 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6243 String targetPkg, int targetUid, GrantUri grantUri) { 6244 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6245 if (targetUris == null) { 6246 targetUris = Maps.newArrayMap(); 6247 mGrantedUriPermissions.put(targetUid, targetUris); 6248 } 6249 6250 UriPermission perm = targetUris.get(grantUri); 6251 if (perm == null) { 6252 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6253 targetUris.put(grantUri, perm); 6254 } 6255 6256 return perm; 6257 } 6258 6259 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6260 final int modeFlags) { 6261 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6262 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6263 : UriPermission.STRENGTH_OWNED; 6264 6265 // Root gets to do everything. 6266 if (uid == 0) { 6267 return true; 6268 } 6269 6270 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6271 if (perms == null) return false; 6272 6273 // First look for exact match 6274 final UriPermission exactPerm = perms.get(grantUri); 6275 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6276 return true; 6277 } 6278 6279 // No exact match, look for prefixes 6280 final int N = perms.size(); 6281 for (int i = 0; i < N; i++) { 6282 final UriPermission perm = perms.valueAt(i); 6283 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6284 && perm.getStrength(modeFlags) >= minStrength) { 6285 return true; 6286 } 6287 } 6288 6289 return false; 6290 } 6291 6292 @Override 6293 public int checkUriPermission(Uri uri, int pid, int uid, 6294 final int modeFlags, int userId) { 6295 enforceNotIsolatedCaller("checkUriPermission"); 6296 6297 // Another redirected-binder-call permissions check as in 6298 // {@link checkComponentPermission}. 6299 Identity tlsIdentity = sCallerIdentity.get(); 6300 if (tlsIdentity != null) { 6301 uid = tlsIdentity.uid; 6302 pid = tlsIdentity.pid; 6303 } 6304 6305 // Our own process gets to do everything. 6306 if (pid == MY_PID) { 6307 return PackageManager.PERMISSION_GRANTED; 6308 } 6309 synchronized (this) { 6310 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6311 ? PackageManager.PERMISSION_GRANTED 6312 : PackageManager.PERMISSION_DENIED; 6313 } 6314 } 6315 6316 /** 6317 * Check if the targetPkg can be granted permission to access uri by 6318 * the callingUid using the given modeFlags. Throws a security exception 6319 * if callingUid is not allowed to do this. Returns the uid of the target 6320 * if the URI permission grant should be performed; returns -1 if it is not 6321 * needed (for example targetPkg already has permission to access the URI). 6322 * If you already know the uid of the target, you can supply it in 6323 * lastTargetUid else set that to -1. 6324 */ 6325 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6326 final int modeFlags, int lastTargetUid) { 6327 if (!Intent.isAccessUriMode(modeFlags)) { 6328 return -1; 6329 } 6330 6331 if (targetPkg != null) { 6332 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6333 "Checking grant " + targetPkg + " permission to " + grantUri); 6334 } 6335 6336 final IPackageManager pm = AppGlobals.getPackageManager(); 6337 6338 // If this is not a content: uri, we can't do anything with it. 6339 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6340 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6341 "Can't grant URI permission for non-content URI: " + grantUri); 6342 return -1; 6343 } 6344 6345 final String authority = grantUri.uri.getAuthority(); 6346 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6347 if (pi == null) { 6348 Slog.w(TAG, "No content provider found for permission check: " + 6349 grantUri.uri.toSafeString()); 6350 return -1; 6351 } 6352 6353 int targetUid = lastTargetUid; 6354 if (targetUid < 0 && targetPkg != null) { 6355 try { 6356 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6357 if (targetUid < 0) { 6358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6359 "Can't grant URI permission no uid for: " + targetPkg); 6360 return -1; 6361 } 6362 } catch (RemoteException ex) { 6363 return -1; 6364 } 6365 } 6366 6367 if (targetUid >= 0) { 6368 // First... does the target actually need this permission? 6369 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6370 // No need to grant the target this permission. 6371 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6372 "Target " + targetPkg + " already has full permission to " + grantUri); 6373 return -1; 6374 } 6375 } else { 6376 // First... there is no target package, so can anyone access it? 6377 boolean allowed = pi.exported; 6378 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6379 if (pi.readPermission != null) { 6380 allowed = false; 6381 } 6382 } 6383 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6384 if (pi.writePermission != null) { 6385 allowed = false; 6386 } 6387 } 6388 if (allowed) { 6389 return -1; 6390 } 6391 } 6392 6393 /* There is a special cross user grant if: 6394 * - The target is on another user. 6395 * - Apps on the current user can access the uri without any uid permissions. 6396 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6397 * grant uri permissions. 6398 */ 6399 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6400 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6401 modeFlags, false /*without considering the uid permissions*/); 6402 6403 // Second... is the provider allowing granting of URI permissions? 6404 if (!specialCrossUserGrant) { 6405 if (!pi.grantUriPermissions) { 6406 throw new SecurityException("Provider " + pi.packageName 6407 + "/" + pi.name 6408 + " does not allow granting of Uri permissions (uri " 6409 + grantUri + ")"); 6410 } 6411 if (pi.uriPermissionPatterns != null) { 6412 final int N = pi.uriPermissionPatterns.length; 6413 boolean allowed = false; 6414 for (int i=0; i<N; i++) { 6415 if (pi.uriPermissionPatterns[i] != null 6416 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6417 allowed = true; 6418 break; 6419 } 6420 } 6421 if (!allowed) { 6422 throw new SecurityException("Provider " + pi.packageName 6423 + "/" + pi.name 6424 + " does not allow granting of permission to path of Uri " 6425 + grantUri); 6426 } 6427 } 6428 } 6429 6430 // Third... does the caller itself have permission to access 6431 // this uri? 6432 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6433 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6434 // Require they hold a strong enough Uri permission 6435 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6436 throw new SecurityException("Uid " + callingUid 6437 + " does not have permission to uri " + grantUri); 6438 } 6439 } 6440 } 6441 return targetUid; 6442 } 6443 6444 @Override 6445 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6446 final int modeFlags, int userId) { 6447 enforceNotIsolatedCaller("checkGrantUriPermission"); 6448 synchronized(this) { 6449 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6450 new GrantUri(userId, uri, false), modeFlags, -1); 6451 } 6452 } 6453 6454 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6455 final int modeFlags, UriPermissionOwner owner) { 6456 if (!Intent.isAccessUriMode(modeFlags)) { 6457 return; 6458 } 6459 6460 // So here we are: the caller has the assumed permission 6461 // to the uri, and the target doesn't. Let's now give this to 6462 // the target. 6463 6464 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6465 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6466 6467 final String authority = grantUri.uri.getAuthority(); 6468 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6469 if (pi == null) { 6470 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6471 return; 6472 } 6473 6474 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6475 grantUri.prefix = true; 6476 } 6477 final UriPermission perm = findOrCreateUriPermissionLocked( 6478 pi.packageName, targetPkg, targetUid, grantUri); 6479 perm.grantModes(modeFlags, owner); 6480 } 6481 6482 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6483 final int modeFlags, UriPermissionOwner owner) { 6484 if (targetPkg == null) { 6485 throw new NullPointerException("targetPkg"); 6486 } 6487 6488 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6489 -1); 6490 if (targetUid < 0) { 6491 return; 6492 } 6493 6494 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6495 owner); 6496 } 6497 6498 static class NeededUriGrants extends ArrayList<GrantUri> { 6499 final String targetPkg; 6500 final int targetUid; 6501 final int flags; 6502 6503 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6504 this.targetPkg = targetPkg; 6505 this.targetUid = targetUid; 6506 this.flags = flags; 6507 } 6508 } 6509 6510 /** 6511 * Like checkGrantUriPermissionLocked, but takes an Intent. 6512 */ 6513 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6514 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6515 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6516 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6517 + " clip=" + (intent != null ? intent.getClipData() : null) 6518 + " from " + intent + "; flags=0x" 6519 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6520 6521 if (targetPkg == null) { 6522 throw new NullPointerException("targetPkg"); 6523 } 6524 6525 if (intent == null) { 6526 return null; 6527 } 6528 Uri data = intent.getData(); 6529 ClipData clip = intent.getClipData(); 6530 if (data == null && clip == null) { 6531 return null; 6532 } 6533 final IPackageManager pm = AppGlobals.getPackageManager(); 6534 int targetUid; 6535 if (needed != null) { 6536 targetUid = needed.targetUid; 6537 } else { 6538 try { 6539 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6540 } catch (RemoteException ex) { 6541 return null; 6542 } 6543 if (targetUid < 0) { 6544 if (DEBUG_URI_PERMISSION) { 6545 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6546 + " on user " + targetUserId); 6547 } 6548 return null; 6549 } 6550 } 6551 if (data != null) { 6552 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6553 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6554 targetUid); 6555 if (targetUid > 0) { 6556 if (needed == null) { 6557 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6558 } 6559 needed.add(grantUri); 6560 } 6561 } 6562 if (clip != null) { 6563 for (int i=0; i<clip.getItemCount(); i++) { 6564 Uri uri = clip.getItemAt(i).getUri(); 6565 if (uri != null) { 6566 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6567 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6568 targetUid); 6569 if (targetUid > 0) { 6570 if (needed == null) { 6571 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6572 } 6573 needed.add(grantUri); 6574 } 6575 } else { 6576 Intent clipIntent = clip.getItemAt(i).getIntent(); 6577 if (clipIntent != null) { 6578 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6579 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6580 if (newNeeded != null) { 6581 needed = newNeeded; 6582 } 6583 } 6584 } 6585 } 6586 } 6587 6588 return needed; 6589 } 6590 6591 /** 6592 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6593 */ 6594 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6595 UriPermissionOwner owner) { 6596 if (needed != null) { 6597 for (int i=0; i<needed.size(); i++) { 6598 GrantUri grantUri = needed.get(i); 6599 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6600 grantUri, needed.flags, owner); 6601 } 6602 } 6603 } 6604 6605 void grantUriPermissionFromIntentLocked(int callingUid, 6606 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6607 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6608 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6609 if (needed == null) { 6610 return; 6611 } 6612 6613 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6614 } 6615 6616 @Override 6617 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6618 final int modeFlags, int userId) { 6619 enforceNotIsolatedCaller("grantUriPermission"); 6620 GrantUri grantUri = new GrantUri(userId, uri, false); 6621 synchronized(this) { 6622 final ProcessRecord r = getRecordForAppLocked(caller); 6623 if (r == null) { 6624 throw new SecurityException("Unable to find app for caller " 6625 + caller 6626 + " when granting permission to uri " + grantUri); 6627 } 6628 if (targetPkg == null) { 6629 throw new IllegalArgumentException("null target"); 6630 } 6631 if (grantUri == null) { 6632 throw new IllegalArgumentException("null uri"); 6633 } 6634 6635 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6636 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6637 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6638 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6639 6640 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6641 } 6642 } 6643 6644 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6645 if (perm.modeFlags == 0) { 6646 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6647 perm.targetUid); 6648 if (perms != null) { 6649 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6650 "Removing " + perm.targetUid + " permission to " + perm.uri); 6651 6652 perms.remove(perm.uri); 6653 if (perms.isEmpty()) { 6654 mGrantedUriPermissions.remove(perm.targetUid); 6655 } 6656 } 6657 } 6658 } 6659 6660 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6661 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6662 6663 final IPackageManager pm = AppGlobals.getPackageManager(); 6664 final String authority = grantUri.uri.getAuthority(); 6665 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6666 if (pi == null) { 6667 Slog.w(TAG, "No content provider found for permission revoke: " 6668 + grantUri.toSafeString()); 6669 return; 6670 } 6671 6672 // Does the caller have this permission on the URI? 6673 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6674 // Right now, if you are not the original owner of the permission, 6675 // you are not allowed to revoke it. 6676 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6677 throw new SecurityException("Uid " + callingUid 6678 + " does not have permission to uri " + grantUri); 6679 //} 6680 } 6681 6682 boolean persistChanged = false; 6683 6684 // Go through all of the permissions and remove any that match. 6685 int N = mGrantedUriPermissions.size(); 6686 for (int i = 0; i < N; i++) { 6687 final int targetUid = mGrantedUriPermissions.keyAt(i); 6688 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6689 6690 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6691 final UriPermission perm = it.next(); 6692 if (perm.uri.sourceUserId == grantUri.sourceUserId 6693 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6694 if (DEBUG_URI_PERMISSION) 6695 Slog.v(TAG, 6696 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6697 persistChanged |= perm.revokeModes( 6698 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6699 if (perm.modeFlags == 0) { 6700 it.remove(); 6701 } 6702 } 6703 } 6704 6705 if (perms.isEmpty()) { 6706 mGrantedUriPermissions.remove(targetUid); 6707 N--; 6708 i--; 6709 } 6710 } 6711 6712 if (persistChanged) { 6713 schedulePersistUriGrants(); 6714 } 6715 } 6716 6717 @Override 6718 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6719 int userId) { 6720 enforceNotIsolatedCaller("revokeUriPermission"); 6721 synchronized(this) { 6722 final ProcessRecord r = getRecordForAppLocked(caller); 6723 if (r == null) { 6724 throw new SecurityException("Unable to find app for caller " 6725 + caller 6726 + " when revoking permission to uri " + uri); 6727 } 6728 if (uri == null) { 6729 Slog.w(TAG, "revokeUriPermission: null uri"); 6730 return; 6731 } 6732 6733 if (!Intent.isAccessUriMode(modeFlags)) { 6734 return; 6735 } 6736 6737 final IPackageManager pm = AppGlobals.getPackageManager(); 6738 final String authority = uri.getAuthority(); 6739 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6740 if (pi == null) { 6741 Slog.w(TAG, "No content provider found for permission revoke: " 6742 + uri.toSafeString()); 6743 return; 6744 } 6745 6746 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6747 } 6748 } 6749 6750 /** 6751 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6752 * given package. 6753 * 6754 * @param packageName Package name to match, or {@code null} to apply to all 6755 * packages. 6756 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6757 * to all users. 6758 * @param persistable If persistable grants should be removed. 6759 */ 6760 private void removeUriPermissionsForPackageLocked( 6761 String packageName, int userHandle, boolean persistable) { 6762 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6763 throw new IllegalArgumentException("Must narrow by either package or user"); 6764 } 6765 6766 boolean persistChanged = false; 6767 6768 int N = mGrantedUriPermissions.size(); 6769 for (int i = 0; i < N; i++) { 6770 final int targetUid = mGrantedUriPermissions.keyAt(i); 6771 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6772 6773 // Only inspect grants matching user 6774 if (userHandle == UserHandle.USER_ALL 6775 || userHandle == UserHandle.getUserId(targetUid)) { 6776 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6777 final UriPermission perm = it.next(); 6778 6779 // Only inspect grants matching package 6780 if (packageName == null || perm.sourcePkg.equals(packageName) 6781 || perm.targetPkg.equals(packageName)) { 6782 persistChanged |= perm.revokeModes( 6783 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6784 6785 // Only remove when no modes remain; any persisted grants 6786 // will keep this alive. 6787 if (perm.modeFlags == 0) { 6788 it.remove(); 6789 } 6790 } 6791 } 6792 6793 if (perms.isEmpty()) { 6794 mGrantedUriPermissions.remove(targetUid); 6795 N--; 6796 i--; 6797 } 6798 } 6799 } 6800 6801 if (persistChanged) { 6802 schedulePersistUriGrants(); 6803 } 6804 } 6805 6806 @Override 6807 public IBinder newUriPermissionOwner(String name) { 6808 enforceNotIsolatedCaller("newUriPermissionOwner"); 6809 synchronized(this) { 6810 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6811 return owner.getExternalTokenLocked(); 6812 } 6813 } 6814 6815 @Override 6816 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6817 final int modeFlags, int userId) { 6818 synchronized(this) { 6819 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6820 if (owner == null) { 6821 throw new IllegalArgumentException("Unknown owner: " + token); 6822 } 6823 if (fromUid != Binder.getCallingUid()) { 6824 if (Binder.getCallingUid() != Process.myUid()) { 6825 // Only system code can grant URI permissions on behalf 6826 // of other users. 6827 throw new SecurityException("nice try"); 6828 } 6829 } 6830 if (targetPkg == null) { 6831 throw new IllegalArgumentException("null target"); 6832 } 6833 if (uri == null) { 6834 throw new IllegalArgumentException("null uri"); 6835 } 6836 6837 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6838 modeFlags, owner); 6839 } 6840 } 6841 6842 @Override 6843 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6844 synchronized(this) { 6845 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6846 if (owner == null) { 6847 throw new IllegalArgumentException("Unknown owner: " + token); 6848 } 6849 6850 if (uri == null) { 6851 owner.removeUriPermissionsLocked(mode); 6852 } else { 6853 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6854 } 6855 } 6856 } 6857 6858 private void schedulePersistUriGrants() { 6859 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6860 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6861 10 * DateUtils.SECOND_IN_MILLIS); 6862 } 6863 } 6864 6865 private void writeGrantedUriPermissions() { 6866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6867 6868 // Snapshot permissions so we can persist without lock 6869 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6870 synchronized (this) { 6871 final int size = mGrantedUriPermissions.size(); 6872 for (int i = 0; i < size; i++) { 6873 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6874 for (UriPermission perm : perms.values()) { 6875 if (perm.persistedModeFlags != 0) { 6876 persist.add(perm.snapshot()); 6877 } 6878 } 6879 } 6880 } 6881 6882 FileOutputStream fos = null; 6883 try { 6884 fos = mGrantFile.startWrite(); 6885 6886 XmlSerializer out = new FastXmlSerializer(); 6887 out.setOutput(fos, "utf-8"); 6888 out.startDocument(null, true); 6889 out.startTag(null, TAG_URI_GRANTS); 6890 for (UriPermission.Snapshot perm : persist) { 6891 out.startTag(null, TAG_URI_GRANT); 6892 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6893 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6894 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6895 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6896 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6897 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6898 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6899 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6900 out.endTag(null, TAG_URI_GRANT); 6901 } 6902 out.endTag(null, TAG_URI_GRANTS); 6903 out.endDocument(); 6904 6905 mGrantFile.finishWrite(fos); 6906 } catch (IOException e) { 6907 if (fos != null) { 6908 mGrantFile.failWrite(fos); 6909 } 6910 } 6911 } 6912 6913 private void readGrantedUriPermissionsLocked() { 6914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6915 6916 final long now = System.currentTimeMillis(); 6917 6918 FileInputStream fis = null; 6919 try { 6920 fis = mGrantFile.openRead(); 6921 final XmlPullParser in = Xml.newPullParser(); 6922 in.setInput(fis, null); 6923 6924 int type; 6925 while ((type = in.next()) != END_DOCUMENT) { 6926 final String tag = in.getName(); 6927 if (type == START_TAG) { 6928 if (TAG_URI_GRANT.equals(tag)) { 6929 final int sourceUserId; 6930 final int targetUserId; 6931 final int userHandle = readIntAttribute(in, 6932 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6933 if (userHandle != UserHandle.USER_NULL) { 6934 // For backwards compatibility. 6935 sourceUserId = userHandle; 6936 targetUserId = userHandle; 6937 } else { 6938 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6939 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6940 } 6941 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6942 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6943 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6944 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6945 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6946 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6947 6948 // Sanity check that provider still belongs to source package 6949 final ProviderInfo pi = getProviderInfoLocked( 6950 uri.getAuthority(), sourceUserId); 6951 if (pi != null && sourcePkg.equals(pi.packageName)) { 6952 int targetUid = -1; 6953 try { 6954 targetUid = AppGlobals.getPackageManager() 6955 .getPackageUid(targetPkg, targetUserId); 6956 } catch (RemoteException e) { 6957 } 6958 if (targetUid != -1) { 6959 final UriPermission perm = findOrCreateUriPermissionLocked( 6960 sourcePkg, targetPkg, targetUid, 6961 new GrantUri(sourceUserId, uri, prefix)); 6962 perm.initPersistedModes(modeFlags, createdTime); 6963 } 6964 } else { 6965 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6966 + " but instead found " + pi); 6967 } 6968 } 6969 } 6970 } 6971 } catch (FileNotFoundException e) { 6972 // Missing grants is okay 6973 } catch (IOException e) { 6974 Log.wtf(TAG, "Failed reading Uri grants", e); 6975 } catch (XmlPullParserException e) { 6976 Log.wtf(TAG, "Failed reading Uri grants", e); 6977 } finally { 6978 IoUtils.closeQuietly(fis); 6979 } 6980 } 6981 6982 @Override 6983 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6984 enforceNotIsolatedCaller("takePersistableUriPermission"); 6985 6986 Preconditions.checkFlagsArgument(modeFlags, 6987 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6988 6989 synchronized (this) { 6990 final int callingUid = Binder.getCallingUid(); 6991 boolean persistChanged = false; 6992 GrantUri grantUri = new GrantUri(userId, uri, false); 6993 6994 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6995 new GrantUri(userId, uri, false)); 6996 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6997 new GrantUri(userId, uri, true)); 6998 6999 final boolean exactValid = (exactPerm != null) 7000 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7001 final boolean prefixValid = (prefixPerm != null) 7002 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7003 7004 if (!(exactValid || prefixValid)) { 7005 throw new SecurityException("No persistable permission grants found for UID " 7006 + callingUid + " and Uri " + grantUri.toSafeString()); 7007 } 7008 7009 if (exactValid) { 7010 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7011 } 7012 if (prefixValid) { 7013 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7014 } 7015 7016 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7017 7018 if (persistChanged) { 7019 schedulePersistUriGrants(); 7020 } 7021 } 7022 } 7023 7024 @Override 7025 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7026 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7027 7028 Preconditions.checkFlagsArgument(modeFlags, 7029 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7030 7031 synchronized (this) { 7032 final int callingUid = Binder.getCallingUid(); 7033 boolean persistChanged = false; 7034 7035 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7036 new GrantUri(userId, uri, false)); 7037 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7038 new GrantUri(userId, uri, true)); 7039 if (exactPerm == null && prefixPerm == null) { 7040 throw new SecurityException("No permission grants found for UID " + callingUid 7041 + " and Uri " + uri.toSafeString()); 7042 } 7043 7044 if (exactPerm != null) { 7045 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7046 removeUriPermissionIfNeededLocked(exactPerm); 7047 } 7048 if (prefixPerm != null) { 7049 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7050 removeUriPermissionIfNeededLocked(prefixPerm); 7051 } 7052 7053 if (persistChanged) { 7054 schedulePersistUriGrants(); 7055 } 7056 } 7057 } 7058 7059 /** 7060 * Prune any older {@link UriPermission} for the given UID until outstanding 7061 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7062 * 7063 * @return if any mutations occured that require persisting. 7064 */ 7065 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7066 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7067 if (perms == null) return false; 7068 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7069 7070 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7071 for (UriPermission perm : perms.values()) { 7072 if (perm.persistedModeFlags != 0) { 7073 persisted.add(perm); 7074 } 7075 } 7076 7077 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7078 if (trimCount <= 0) return false; 7079 7080 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7081 for (int i = 0; i < trimCount; i++) { 7082 final UriPermission perm = persisted.get(i); 7083 7084 if (DEBUG_URI_PERMISSION) { 7085 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7086 } 7087 7088 perm.releasePersistableModes(~0); 7089 removeUriPermissionIfNeededLocked(perm); 7090 } 7091 7092 return true; 7093 } 7094 7095 @Override 7096 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7097 String packageName, boolean incoming) { 7098 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7099 Preconditions.checkNotNull(packageName, "packageName"); 7100 7101 final int callingUid = Binder.getCallingUid(); 7102 final IPackageManager pm = AppGlobals.getPackageManager(); 7103 try { 7104 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7105 if (packageUid != callingUid) { 7106 throw new SecurityException( 7107 "Package " + packageName + " does not belong to calling UID " + callingUid); 7108 } 7109 } catch (RemoteException e) { 7110 throw new SecurityException("Failed to verify package name ownership"); 7111 } 7112 7113 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7114 synchronized (this) { 7115 if (incoming) { 7116 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7117 callingUid); 7118 if (perms == null) { 7119 Slog.w(TAG, "No permission grants found for " + packageName); 7120 } else { 7121 for (UriPermission perm : perms.values()) { 7122 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7123 result.add(perm.buildPersistedPublicApiObject()); 7124 } 7125 } 7126 } 7127 } else { 7128 final int size = mGrantedUriPermissions.size(); 7129 for (int i = 0; i < size; i++) { 7130 final ArrayMap<GrantUri, UriPermission> perms = 7131 mGrantedUriPermissions.valueAt(i); 7132 for (UriPermission perm : perms.values()) { 7133 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7134 result.add(perm.buildPersistedPublicApiObject()); 7135 } 7136 } 7137 } 7138 } 7139 } 7140 return new ParceledListSlice<android.content.UriPermission>(result); 7141 } 7142 7143 @Override 7144 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7145 synchronized (this) { 7146 ProcessRecord app = 7147 who != null ? getRecordForAppLocked(who) : null; 7148 if (app == null) return; 7149 7150 Message msg = Message.obtain(); 7151 msg.what = WAIT_FOR_DEBUGGER_MSG; 7152 msg.obj = app; 7153 msg.arg1 = waiting ? 1 : 0; 7154 mHandler.sendMessage(msg); 7155 } 7156 } 7157 7158 @Override 7159 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7160 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7161 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7162 outInfo.availMem = Process.getFreeMemory(); 7163 outInfo.totalMem = Process.getTotalMemory(); 7164 outInfo.threshold = homeAppMem; 7165 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7166 outInfo.hiddenAppThreshold = cachedAppMem; 7167 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7168 ProcessList.SERVICE_ADJ); 7169 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7170 ProcessList.VISIBLE_APP_ADJ); 7171 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7172 ProcessList.FOREGROUND_APP_ADJ); 7173 } 7174 7175 // ========================================================= 7176 // TASK MANAGEMENT 7177 // ========================================================= 7178 7179 @Override 7180 public List<IAppTask> getAppTasks() { 7181 final PackageManager pm = mContext.getPackageManager(); 7182 int callingUid = Binder.getCallingUid(); 7183 long ident = Binder.clearCallingIdentity(); 7184 7185 // Compose the list of packages for this id to test against 7186 HashSet<String> packages = new HashSet<String>(); 7187 String[] uidPackages = pm.getPackagesForUid(callingUid); 7188 for (int i = 0; i < uidPackages.length; i++) { 7189 packages.add(uidPackages[i]); 7190 } 7191 7192 synchronized(this) { 7193 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7194 try { 7195 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7196 7197 final int N = mRecentTasks.size(); 7198 for (int i = 0; i < N; i++) { 7199 TaskRecord tr = mRecentTasks.get(i); 7200 // Skip tasks that are not created by the caller 7201 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7202 ActivityManager.RecentTaskInfo taskInfo = 7203 createRecentTaskInfoFromTaskRecord(tr); 7204 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7205 list.add(taskImpl); 7206 } 7207 } 7208 } finally { 7209 Binder.restoreCallingIdentity(ident); 7210 } 7211 return list; 7212 } 7213 } 7214 7215 @Override 7216 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7217 final int callingUid = Binder.getCallingUid(); 7218 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7219 7220 synchronized(this) { 7221 if (localLOGV) Slog.v( 7222 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7223 7224 final boolean allowed = checkCallingPermission( 7225 android.Manifest.permission.GET_TASKS) 7226 == PackageManager.PERMISSION_GRANTED; 7227 if (!allowed) { 7228 Slog.w(TAG, "getTasks: caller " + callingUid 7229 + " does not hold GET_TASKS; limiting output"); 7230 } 7231 7232 // TODO: Improve with MRU list from all ActivityStacks. 7233 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7234 } 7235 7236 return list; 7237 } 7238 7239 TaskRecord getMostRecentTask() { 7240 return mRecentTasks.get(0); 7241 } 7242 7243 /** 7244 * Creates a new RecentTaskInfo from a TaskRecord. 7245 */ 7246 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7247 // Update the task description to reflect any changes in the task stack 7248 tr.updateTaskDescription(); 7249 7250 // Compose the recent task info 7251 ActivityManager.RecentTaskInfo rti 7252 = new ActivityManager.RecentTaskInfo(); 7253 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7254 rti.persistentId = tr.taskId; 7255 rti.baseIntent = new Intent(tr.getBaseIntent()); 7256 rti.origActivity = tr.origActivity; 7257 rti.description = tr.lastDescription; 7258 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7259 rti.userId = tr.userId; 7260 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7261 rti.firstActiveTime = tr.firstActiveTime; 7262 rti.lastActiveTime = tr.lastActiveTime; 7263 return rti; 7264 } 7265 7266 @Override 7267 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7268 int flags, int userId) { 7269 final int callingUid = Binder.getCallingUid(); 7270 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7271 false, true, "getRecentTasks", null); 7272 7273 synchronized (this) { 7274 final boolean allowed = checkCallingPermission( 7275 android.Manifest.permission.GET_TASKS) 7276 == PackageManager.PERMISSION_GRANTED; 7277 if (!allowed) { 7278 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7279 + " does not hold GET_TASKS; limiting output"); 7280 } 7281 final boolean detailed = checkCallingPermission( 7282 android.Manifest.permission.GET_DETAILED_TASKS) 7283 == PackageManager.PERMISSION_GRANTED; 7284 7285 IPackageManager pm = AppGlobals.getPackageManager(); 7286 7287 final int N = mRecentTasks.size(); 7288 ArrayList<ActivityManager.RecentTaskInfo> res 7289 = new ArrayList<ActivityManager.RecentTaskInfo>( 7290 maxNum < N ? maxNum : N); 7291 7292 final Set<Integer> includedUsers; 7293 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7294 includedUsers = getProfileIdsLocked(userId); 7295 } else { 7296 includedUsers = new HashSet<Integer>(); 7297 } 7298 includedUsers.add(Integer.valueOf(userId)); 7299 for (int i=0; i<N && maxNum > 0; i++) { 7300 TaskRecord tr = mRecentTasks.get(i); 7301 // Only add calling user or related users recent tasks 7302 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7303 7304 // Return the entry if desired by the caller. We always return 7305 // the first entry, because callers always expect this to be the 7306 // foreground app. We may filter others if the caller has 7307 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7308 // we should exclude the entry. 7309 7310 if (i == 0 7311 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7312 || (tr.intent == null) 7313 || ((tr.intent.getFlags() 7314 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7315 if (!allowed) { 7316 // If the caller doesn't have the GET_TASKS permission, then only 7317 // allow them to see a small subset of tasks -- their own and home. 7318 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7319 continue; 7320 } 7321 } 7322 if (tr.intent != null && 7323 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7324 != 0 && tr.getTopActivity() == null) { 7325 // Don't include auto remove tasks that are finished or finishing. 7326 continue; 7327 } 7328 7329 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7330 if (!detailed) { 7331 rti.baseIntent.replaceExtras((Bundle)null); 7332 } 7333 7334 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7335 // Check whether this activity is currently available. 7336 try { 7337 if (rti.origActivity != null) { 7338 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7339 == null) { 7340 continue; 7341 } 7342 } else if (rti.baseIntent != null) { 7343 if (pm.queryIntentActivities(rti.baseIntent, 7344 null, 0, userId) == null) { 7345 continue; 7346 } 7347 } 7348 } catch (RemoteException e) { 7349 // Will never happen. 7350 } 7351 } 7352 7353 res.add(rti); 7354 maxNum--; 7355 } 7356 } 7357 return res; 7358 } 7359 } 7360 7361 private TaskRecord recentTaskForIdLocked(int id) { 7362 final int N = mRecentTasks.size(); 7363 for (int i=0; i<N; i++) { 7364 TaskRecord tr = mRecentTasks.get(i); 7365 if (tr.taskId == id) { 7366 return tr; 7367 } 7368 } 7369 return null; 7370 } 7371 7372 @Override 7373 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7374 synchronized (this) { 7375 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7376 "getTaskThumbnail()"); 7377 TaskRecord tr = recentTaskForIdLocked(id); 7378 if (tr != null) { 7379 return tr.getTaskThumbnailLocked(); 7380 } 7381 } 7382 return null; 7383 } 7384 7385 @Override 7386 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7387 synchronized (this) { 7388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7389 if (r != null) { 7390 r.taskDescription = td; 7391 r.task.updateTaskDescription(); 7392 } 7393 } 7394 } 7395 7396 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7397 if (!pr.killedByAm) { 7398 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7399 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7400 pr.processName, pr.setAdj, reason); 7401 pr.killedByAm = true; 7402 Process.killProcessQuiet(pr.pid); 7403 } 7404 } 7405 7406 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7407 tr.disposeThumbnail(); 7408 mRecentTasks.remove(tr); 7409 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7410 Intent baseIntent = new Intent( 7411 tr.intent != null ? tr.intent : tr.affinityIntent); 7412 ComponentName component = baseIntent.getComponent(); 7413 if (component == null) { 7414 Slog.w(TAG, "Now component for base intent of task: " + tr); 7415 return; 7416 } 7417 7418 // Find any running services associated with this app. 7419 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7420 7421 if (killProcesses) { 7422 // Find any running processes associated with this app. 7423 final String pkg = component.getPackageName(); 7424 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7425 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7426 for (int i=0; i<pmap.size(); i++) { 7427 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7428 for (int j=0; j<uids.size(); j++) { 7429 ProcessRecord proc = uids.valueAt(j); 7430 if (proc.userId != tr.userId) { 7431 continue; 7432 } 7433 if (!proc.pkgList.containsKey(pkg)) { 7434 continue; 7435 } 7436 procs.add(proc); 7437 } 7438 } 7439 7440 // Kill the running processes. 7441 for (int i=0; i<procs.size(); i++) { 7442 ProcessRecord pr = procs.get(i); 7443 if (pr == mHomeProcess) { 7444 // Don't kill the home process along with tasks from the same package. 7445 continue; 7446 } 7447 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7448 killUnneededProcessLocked(pr, "remove task"); 7449 } else { 7450 pr.waitingToKill = "remove task"; 7451 } 7452 } 7453 } 7454 } 7455 7456 /** 7457 * Removes the task with the specified task id. 7458 * 7459 * @param taskId Identifier of the task to be removed. 7460 * @param flags Additional operational flags. May be 0 or 7461 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7462 * @return Returns true if the given task was found and removed. 7463 */ 7464 private boolean removeTaskByIdLocked(int taskId, int flags) { 7465 TaskRecord tr = recentTaskForIdLocked(taskId); 7466 if (tr != null) { 7467 tr.removeTaskActivitiesLocked(); 7468 cleanUpRemovedTaskLocked(tr, flags); 7469 if (tr.isPersistable) { 7470 notifyTaskPersisterLocked(tr, true); 7471 } 7472 return true; 7473 } 7474 return false; 7475 } 7476 7477 @Override 7478 public boolean removeTask(int taskId, int flags) { 7479 synchronized (this) { 7480 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7481 "removeTask()"); 7482 long ident = Binder.clearCallingIdentity(); 7483 try { 7484 return removeTaskByIdLocked(taskId, flags); 7485 } finally { 7486 Binder.restoreCallingIdentity(ident); 7487 } 7488 } 7489 } 7490 7491 /** 7492 * TODO: Add mController hook 7493 */ 7494 @Override 7495 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7496 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7497 "moveTaskToFront()"); 7498 7499 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7500 synchronized(this) { 7501 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7502 Binder.getCallingUid(), "Task to front")) { 7503 ActivityOptions.abort(options); 7504 return; 7505 } 7506 final long origId = Binder.clearCallingIdentity(); 7507 try { 7508 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7509 if (task == null) { 7510 return; 7511 } 7512 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7513 mStackSupervisor.showLockTaskToast(); 7514 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7515 return; 7516 } 7517 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7518 if (prev != null && prev.isRecentsActivity()) { 7519 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7520 } 7521 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7522 } finally { 7523 Binder.restoreCallingIdentity(origId); 7524 } 7525 ActivityOptions.abort(options); 7526 } 7527 } 7528 7529 @Override 7530 public void moveTaskToBack(int taskId) { 7531 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7532 "moveTaskToBack()"); 7533 7534 synchronized(this) { 7535 TaskRecord tr = recentTaskForIdLocked(taskId); 7536 if (tr != null) { 7537 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7538 ActivityStack stack = tr.stack; 7539 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7540 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7541 Binder.getCallingUid(), "Task to back")) { 7542 return; 7543 } 7544 } 7545 final long origId = Binder.clearCallingIdentity(); 7546 try { 7547 stack.moveTaskToBackLocked(taskId, null); 7548 } finally { 7549 Binder.restoreCallingIdentity(origId); 7550 } 7551 } 7552 } 7553 } 7554 7555 /** 7556 * Moves an activity, and all of the other activities within the same task, to the bottom 7557 * of the history stack. The activity's order within the task is unchanged. 7558 * 7559 * @param token A reference to the activity we wish to move 7560 * @param nonRoot If false then this only works if the activity is the root 7561 * of a task; if true it will work for any activity in a task. 7562 * @return Returns true if the move completed, false if not. 7563 */ 7564 @Override 7565 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7566 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7567 synchronized(this) { 7568 final long origId = Binder.clearCallingIdentity(); 7569 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7570 if (taskId >= 0) { 7571 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7572 } 7573 Binder.restoreCallingIdentity(origId); 7574 } 7575 return false; 7576 } 7577 7578 @Override 7579 public void moveTaskBackwards(int task) { 7580 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7581 "moveTaskBackwards()"); 7582 7583 synchronized(this) { 7584 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7585 Binder.getCallingUid(), "Task backwards")) { 7586 return; 7587 } 7588 final long origId = Binder.clearCallingIdentity(); 7589 moveTaskBackwardsLocked(task); 7590 Binder.restoreCallingIdentity(origId); 7591 } 7592 } 7593 7594 private final void moveTaskBackwardsLocked(int task) { 7595 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7596 } 7597 7598 @Override 7599 public IBinder getHomeActivityToken() throws RemoteException { 7600 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7601 "getHomeActivityToken()"); 7602 synchronized (this) { 7603 return mStackSupervisor.getHomeActivityToken(); 7604 } 7605 } 7606 7607 @Override 7608 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7609 IActivityContainerCallback callback) throws RemoteException { 7610 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7611 "createActivityContainer()"); 7612 synchronized (this) { 7613 if (parentActivityToken == null) { 7614 throw new IllegalArgumentException("parent token must not be null"); 7615 } 7616 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7617 if (r == null) { 7618 return null; 7619 } 7620 if (callback == null) { 7621 throw new IllegalArgumentException("callback must not be null"); 7622 } 7623 return mStackSupervisor.createActivityContainer(r, callback); 7624 } 7625 } 7626 7627 @Override 7628 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7629 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7630 "deleteActivityContainer()"); 7631 synchronized (this) { 7632 mStackSupervisor.deleteActivityContainer(container); 7633 } 7634 } 7635 7636 @Override 7637 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7638 throws RemoteException { 7639 synchronized (this) { 7640 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7641 if (stack != null) { 7642 return stack.mActivityContainer; 7643 } 7644 return null; 7645 } 7646 } 7647 7648 @Override 7649 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7650 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7651 "moveTaskToStack()"); 7652 if (stackId == HOME_STACK_ID) { 7653 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7654 new RuntimeException("here").fillInStackTrace()); 7655 } 7656 synchronized (this) { 7657 long ident = Binder.clearCallingIdentity(); 7658 try { 7659 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7660 + stackId + " toTop=" + toTop); 7661 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7662 } finally { 7663 Binder.restoreCallingIdentity(ident); 7664 } 7665 } 7666 } 7667 7668 @Override 7669 public void resizeStack(int stackBoxId, Rect bounds) { 7670 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7671 "resizeStackBox()"); 7672 long ident = Binder.clearCallingIdentity(); 7673 try { 7674 mWindowManager.resizeStack(stackBoxId, bounds); 7675 } finally { 7676 Binder.restoreCallingIdentity(ident); 7677 } 7678 } 7679 7680 @Override 7681 public List<StackInfo> getAllStackInfos() { 7682 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7683 "getAllStackInfos()"); 7684 long ident = Binder.clearCallingIdentity(); 7685 try { 7686 synchronized (this) { 7687 return mStackSupervisor.getAllStackInfosLocked(); 7688 } 7689 } finally { 7690 Binder.restoreCallingIdentity(ident); 7691 } 7692 } 7693 7694 @Override 7695 public StackInfo getStackInfo(int stackId) { 7696 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7697 "getStackInfo()"); 7698 long ident = Binder.clearCallingIdentity(); 7699 try { 7700 synchronized (this) { 7701 return mStackSupervisor.getStackInfoLocked(stackId); 7702 } 7703 } finally { 7704 Binder.restoreCallingIdentity(ident); 7705 } 7706 } 7707 7708 @Override 7709 public boolean isInHomeStack(int taskId) { 7710 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7711 "getStackInfo()"); 7712 long ident = Binder.clearCallingIdentity(); 7713 try { 7714 synchronized (this) { 7715 TaskRecord tr = recentTaskForIdLocked(taskId); 7716 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7717 } 7718 } finally { 7719 Binder.restoreCallingIdentity(ident); 7720 } 7721 } 7722 7723 @Override 7724 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7725 synchronized(this) { 7726 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7727 } 7728 } 7729 7730 private boolean isLockTaskAuthorized(String pkg) { 7731 final DevicePolicyManager dpm = (DevicePolicyManager) 7732 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7733 try { 7734 int uid = mContext.getPackageManager().getPackageUid(pkg, 7735 Binder.getCallingUserHandle().getIdentifier()); 7736 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7737 } catch (NameNotFoundException e) { 7738 return false; 7739 } 7740 } 7741 7742 void startLockTaskMode(TaskRecord task) { 7743 final String pkg; 7744 synchronized (this) { 7745 pkg = task.intent.getComponent().getPackageName(); 7746 } 7747 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7748 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7749 final TaskRecord taskRecord = task; 7750 mHandler.post(new Runnable() { 7751 @Override 7752 public void run() { 7753 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7754 } 7755 }); 7756 return; 7757 } 7758 long ident = Binder.clearCallingIdentity(); 7759 try { 7760 synchronized (this) { 7761 // Since we lost lock on task, make sure it is still there. 7762 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7763 if (task != null) { 7764 if (!isSystemInitiated 7765 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7766 throw new IllegalArgumentException("Invalid task, not in foreground"); 7767 } 7768 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7769 } 7770 } 7771 } finally { 7772 Binder.restoreCallingIdentity(ident); 7773 } 7774 } 7775 7776 @Override 7777 public void startLockTaskMode(int taskId) { 7778 final TaskRecord task; 7779 long ident = Binder.clearCallingIdentity(); 7780 try { 7781 synchronized (this) { 7782 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7783 } 7784 } finally { 7785 Binder.restoreCallingIdentity(ident); 7786 } 7787 if (task != null) { 7788 startLockTaskMode(task); 7789 } 7790 } 7791 7792 @Override 7793 public void startLockTaskMode(IBinder token) { 7794 final TaskRecord task; 7795 long ident = Binder.clearCallingIdentity(); 7796 try { 7797 synchronized (this) { 7798 final ActivityRecord r = ActivityRecord.forToken(token); 7799 if (r == null) { 7800 return; 7801 } 7802 task = r.task; 7803 } 7804 } finally { 7805 Binder.restoreCallingIdentity(ident); 7806 } 7807 if (task != null) { 7808 startLockTaskMode(task); 7809 } 7810 } 7811 7812 @Override 7813 public void startLockTaskModeOnCurrent() throws RemoteException { 7814 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7815 ActivityRecord r = null; 7816 synchronized (this) { 7817 r = mStackSupervisor.topRunningActivityLocked(); 7818 } 7819 startLockTaskMode(r.task); 7820 } 7821 7822 @Override 7823 public void stopLockTaskMode() { 7824 // Verify that the user matches the package of the intent for the TaskRecord 7825 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7826 // and stopLockTaskMode. 7827 final int callingUid = Binder.getCallingUid(); 7828 if (callingUid != Process.SYSTEM_UID) { 7829 try { 7830 String pkg = 7831 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7832 int uid = mContext.getPackageManager().getPackageUid(pkg, 7833 Binder.getCallingUserHandle().getIdentifier()); 7834 if (uid != callingUid) { 7835 throw new SecurityException("Invalid uid, expected " + uid); 7836 } 7837 } catch (NameNotFoundException e) { 7838 Log.d(TAG, "stopLockTaskMode " + e); 7839 return; 7840 } 7841 } 7842 long ident = Binder.clearCallingIdentity(); 7843 try { 7844 Log.d(TAG, "stopLockTaskMode"); 7845 // Stop lock task 7846 synchronized (this) { 7847 mStackSupervisor.setLockTaskModeLocked(null, false); 7848 } 7849 } finally { 7850 Binder.restoreCallingIdentity(ident); 7851 } 7852 } 7853 7854 @Override 7855 public void stopLockTaskModeOnCurrent() throws RemoteException { 7856 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7857 long ident = Binder.clearCallingIdentity(); 7858 try { 7859 stopLockTaskMode(); 7860 } finally { 7861 Binder.restoreCallingIdentity(ident); 7862 } 7863 } 7864 7865 @Override 7866 public boolean isInLockTaskMode() { 7867 synchronized (this) { 7868 return mStackSupervisor.isInLockTaskMode(); 7869 } 7870 } 7871 7872 // ========================================================= 7873 // CONTENT PROVIDERS 7874 // ========================================================= 7875 7876 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7877 List<ProviderInfo> providers = null; 7878 try { 7879 providers = AppGlobals.getPackageManager(). 7880 queryContentProviders(app.processName, app.uid, 7881 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7882 } catch (RemoteException ex) { 7883 } 7884 if (DEBUG_MU) 7885 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7886 int userId = app.userId; 7887 if (providers != null) { 7888 int N = providers.size(); 7889 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7890 for (int i=0; i<N; i++) { 7891 ProviderInfo cpi = 7892 (ProviderInfo)providers.get(i); 7893 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7894 cpi.name, cpi.flags); 7895 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7896 // This is a singleton provider, but a user besides the 7897 // default user is asking to initialize a process it runs 7898 // in... well, no, it doesn't actually run in this process, 7899 // it runs in the process of the default user. Get rid of it. 7900 providers.remove(i); 7901 N--; 7902 i--; 7903 continue; 7904 } 7905 7906 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7907 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7908 if (cpr == null) { 7909 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7910 mProviderMap.putProviderByClass(comp, cpr); 7911 } 7912 if (DEBUG_MU) 7913 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7914 app.pubProviders.put(cpi.name, cpr); 7915 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7916 // Don't add this if it is a platform component that is marked 7917 // to run in multiple processes, because this is actually 7918 // part of the framework so doesn't make sense to track as a 7919 // separate apk in the process. 7920 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7921 mProcessStats); 7922 } 7923 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7924 } 7925 } 7926 return providers; 7927 } 7928 7929 /** 7930 * Check if {@link ProcessRecord} has a possible chance at accessing the 7931 * given {@link ProviderInfo}. Final permission checking is always done 7932 * in {@link ContentProvider}. 7933 */ 7934 private final String checkContentProviderPermissionLocked( 7935 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7936 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7937 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7938 boolean checkedGrants = false; 7939 if (checkUser) { 7940 // Looking for cross-user grants before enforcing the typical cross-users permissions 7941 if (UserHandle.getUserId(callingUid) != userId) { 7942 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7943 return null; 7944 } 7945 checkedGrants = true; 7946 } 7947 userId = handleIncomingUser(callingPid, callingUid, userId, 7948 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7949 } 7950 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7951 cpi.applicationInfo.uid, cpi.exported) 7952 == PackageManager.PERMISSION_GRANTED) { 7953 return null; 7954 } 7955 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7956 cpi.applicationInfo.uid, cpi.exported) 7957 == PackageManager.PERMISSION_GRANTED) { 7958 return null; 7959 } 7960 7961 PathPermission[] pps = cpi.pathPermissions; 7962 if (pps != null) { 7963 int i = pps.length; 7964 while (i > 0) { 7965 i--; 7966 PathPermission pp = pps[i]; 7967 String pprperm = pp.getReadPermission(); 7968 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7969 cpi.applicationInfo.uid, cpi.exported) 7970 == PackageManager.PERMISSION_GRANTED) { 7971 return null; 7972 } 7973 String ppwperm = pp.getWritePermission(); 7974 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7975 cpi.applicationInfo.uid, cpi.exported) 7976 == PackageManager.PERMISSION_GRANTED) { 7977 return null; 7978 } 7979 } 7980 } 7981 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7982 return null; 7983 } 7984 7985 String msg; 7986 if (!cpi.exported) { 7987 msg = "Permission Denial: opening provider " + cpi.name 7988 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7989 + ", uid=" + callingUid + ") that is not exported from uid " 7990 + cpi.applicationInfo.uid; 7991 } else { 7992 msg = "Permission Denial: opening provider " + cpi.name 7993 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7994 + ", uid=" + callingUid + ") requires " 7995 + cpi.readPermission + " or " + cpi.writePermission; 7996 } 7997 Slog.w(TAG, msg); 7998 return msg; 7999 } 8000 8001 /** 8002 * Returns if the ContentProvider has granted a uri to callingUid 8003 */ 8004 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8005 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8006 if (perms != null) { 8007 for (GrantUri grantUri : perms.keySet()) { 8008 if (grantUri.sourceUserId == userId || !checkUser) { 8009 if (matchesProvider(grantUri.uri, cpi)) { 8010 return true; 8011 } 8012 } 8013 } 8014 } 8015 return false; 8016 } 8017 8018 /** 8019 * Returns true if the uri authority is one of the authorities specified in the provider. 8020 */ 8021 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8022 String uriAuth = uri.getAuthority(); 8023 String cpiAuth = cpi.authority; 8024 if (cpiAuth.indexOf(';') == -1) { 8025 return cpiAuth.equals(uriAuth); 8026 } 8027 String[] cpiAuths = cpiAuth.split(";"); 8028 int length = cpiAuths.length; 8029 for (int i = 0; i < length; i++) { 8030 if (cpiAuths[i].equals(uriAuth)) return true; 8031 } 8032 return false; 8033 } 8034 8035 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8036 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8037 if (r != null) { 8038 for (int i=0; i<r.conProviders.size(); i++) { 8039 ContentProviderConnection conn = r.conProviders.get(i); 8040 if (conn.provider == cpr) { 8041 if (DEBUG_PROVIDER) Slog.v(TAG, 8042 "Adding provider requested by " 8043 + r.processName + " from process " 8044 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8045 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8046 if (stable) { 8047 conn.stableCount++; 8048 conn.numStableIncs++; 8049 } else { 8050 conn.unstableCount++; 8051 conn.numUnstableIncs++; 8052 } 8053 return conn; 8054 } 8055 } 8056 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8057 if (stable) { 8058 conn.stableCount = 1; 8059 conn.numStableIncs = 1; 8060 } else { 8061 conn.unstableCount = 1; 8062 conn.numUnstableIncs = 1; 8063 } 8064 cpr.connections.add(conn); 8065 r.conProviders.add(conn); 8066 return conn; 8067 } 8068 cpr.addExternalProcessHandleLocked(externalProcessToken); 8069 return null; 8070 } 8071 8072 boolean decProviderCountLocked(ContentProviderConnection conn, 8073 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8074 if (conn != null) { 8075 cpr = conn.provider; 8076 if (DEBUG_PROVIDER) Slog.v(TAG, 8077 "Removing provider requested by " 8078 + conn.client.processName + " from process " 8079 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8080 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8081 if (stable) { 8082 conn.stableCount--; 8083 } else { 8084 conn.unstableCount--; 8085 } 8086 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8087 cpr.connections.remove(conn); 8088 conn.client.conProviders.remove(conn); 8089 return true; 8090 } 8091 return false; 8092 } 8093 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8094 return false; 8095 } 8096 8097 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8098 String name, IBinder token, boolean stable, int userId) { 8099 ContentProviderRecord cpr; 8100 ContentProviderConnection conn = null; 8101 ProviderInfo cpi = null; 8102 8103 synchronized(this) { 8104 ProcessRecord r = null; 8105 if (caller != null) { 8106 r = getRecordForAppLocked(caller); 8107 if (r == null) { 8108 throw new SecurityException( 8109 "Unable to find app for caller " + caller 8110 + " (pid=" + Binder.getCallingPid() 8111 + ") when getting content provider " + name); 8112 } 8113 } 8114 8115 boolean checkCrossUser = true; 8116 8117 // First check if this content provider has been published... 8118 cpr = mProviderMap.getProviderByName(name, userId); 8119 // If that didn't work, check if it exists for user 0 and then 8120 // verify that it's a singleton provider before using it. 8121 if (cpr == null && userId != UserHandle.USER_OWNER) { 8122 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8123 if (cpr != null) { 8124 cpi = cpr.info; 8125 if (isSingleton(cpi.processName, cpi.applicationInfo, 8126 cpi.name, cpi.flags) 8127 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8128 userId = UserHandle.USER_OWNER; 8129 checkCrossUser = false; 8130 } else { 8131 cpr = null; 8132 cpi = null; 8133 } 8134 } 8135 } 8136 8137 boolean providerRunning = cpr != null; 8138 if (providerRunning) { 8139 cpi = cpr.info; 8140 String msg; 8141 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8142 != null) { 8143 throw new SecurityException(msg); 8144 } 8145 8146 if (r != null && cpr.canRunHere(r)) { 8147 // This provider has been published or is in the process 8148 // of being published... but it is also allowed to run 8149 // in the caller's process, so don't make a connection 8150 // and just let the caller instantiate its own instance. 8151 ContentProviderHolder holder = cpr.newHolder(null); 8152 // don't give caller the provider object, it needs 8153 // to make its own. 8154 holder.provider = null; 8155 return holder; 8156 } 8157 8158 final long origId = Binder.clearCallingIdentity(); 8159 8160 // In this case the provider instance already exists, so we can 8161 // return it right away. 8162 conn = incProviderCountLocked(r, cpr, token, stable); 8163 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8164 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8165 // If this is a perceptible app accessing the provider, 8166 // make sure to count it as being accessed and thus 8167 // back up on the LRU list. This is good because 8168 // content providers are often expensive to start. 8169 updateLruProcessLocked(cpr.proc, false, null); 8170 } 8171 } 8172 8173 if (cpr.proc != null) { 8174 if (false) { 8175 if (cpr.name.flattenToShortString().equals( 8176 "com.android.providers.calendar/.CalendarProvider2")) { 8177 Slog.v(TAG, "****************** KILLING " 8178 + cpr.name.flattenToShortString()); 8179 Process.killProcess(cpr.proc.pid); 8180 } 8181 } 8182 boolean success = updateOomAdjLocked(cpr.proc); 8183 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8184 // NOTE: there is still a race here where a signal could be 8185 // pending on the process even though we managed to update its 8186 // adj level. Not sure what to do about this, but at least 8187 // the race is now smaller. 8188 if (!success) { 8189 // Uh oh... it looks like the provider's process 8190 // has been killed on us. We need to wait for a new 8191 // process to be started, and make sure its death 8192 // doesn't kill our process. 8193 Slog.i(TAG, 8194 "Existing provider " + cpr.name.flattenToShortString() 8195 + " is crashing; detaching " + r); 8196 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8197 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8198 if (!lastRef) { 8199 // This wasn't the last ref our process had on 8200 // the provider... we have now been killed, bail. 8201 return null; 8202 } 8203 providerRunning = false; 8204 conn = null; 8205 } 8206 } 8207 8208 Binder.restoreCallingIdentity(origId); 8209 } 8210 8211 boolean singleton; 8212 if (!providerRunning) { 8213 try { 8214 cpi = AppGlobals.getPackageManager(). 8215 resolveContentProvider(name, 8216 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8217 } catch (RemoteException ex) { 8218 } 8219 if (cpi == null) { 8220 return null; 8221 } 8222 // If the provider is a singleton AND 8223 // (it's a call within the same user || the provider is a 8224 // privileged app) 8225 // Then allow connecting to the singleton provider 8226 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8227 cpi.name, cpi.flags) 8228 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8229 if (singleton) { 8230 userId = UserHandle.USER_OWNER; 8231 } 8232 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8233 8234 String msg; 8235 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8236 != null) { 8237 throw new SecurityException(msg); 8238 } 8239 8240 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8241 && !cpi.processName.equals("system")) { 8242 // If this content provider does not run in the system 8243 // process, and the system is not yet ready to run other 8244 // processes, then fail fast instead of hanging. 8245 throw new IllegalArgumentException( 8246 "Attempt to launch content provider before system ready"); 8247 } 8248 8249 // Make sure that the user who owns this provider is started. If not, 8250 // we don't want to allow it to run. 8251 if (mStartedUsers.get(userId) == null) { 8252 Slog.w(TAG, "Unable to launch app " 8253 + cpi.applicationInfo.packageName + "/" 8254 + cpi.applicationInfo.uid + " for provider " 8255 + name + ": user " + userId + " is stopped"); 8256 return null; 8257 } 8258 8259 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8260 cpr = mProviderMap.getProviderByClass(comp, userId); 8261 final boolean firstClass = cpr == null; 8262 if (firstClass) { 8263 try { 8264 ApplicationInfo ai = 8265 AppGlobals.getPackageManager(). 8266 getApplicationInfo( 8267 cpi.applicationInfo.packageName, 8268 STOCK_PM_FLAGS, userId); 8269 if (ai == null) { 8270 Slog.w(TAG, "No package info for content provider " 8271 + cpi.name); 8272 return null; 8273 } 8274 ai = getAppInfoForUser(ai, userId); 8275 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8276 } catch (RemoteException ex) { 8277 // pm is in same process, this will never happen. 8278 } 8279 } 8280 8281 if (r != null && cpr.canRunHere(r)) { 8282 // If this is a multiprocess provider, then just return its 8283 // info and allow the caller to instantiate it. Only do 8284 // this if the provider is the same user as the caller's 8285 // process, or can run as root (so can be in any process). 8286 return cpr.newHolder(null); 8287 } 8288 8289 if (DEBUG_PROVIDER) { 8290 RuntimeException e = new RuntimeException("here"); 8291 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8292 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8293 } 8294 8295 // This is single process, and our app is now connecting to it. 8296 // See if we are already in the process of launching this 8297 // provider. 8298 final int N = mLaunchingProviders.size(); 8299 int i; 8300 for (i=0; i<N; i++) { 8301 if (mLaunchingProviders.get(i) == cpr) { 8302 break; 8303 } 8304 } 8305 8306 // If the provider is not already being launched, then get it 8307 // started. 8308 if (i >= N) { 8309 final long origId = Binder.clearCallingIdentity(); 8310 8311 try { 8312 // Content provider is now in use, its package can't be stopped. 8313 try { 8314 AppGlobals.getPackageManager().setPackageStoppedState( 8315 cpr.appInfo.packageName, false, userId); 8316 } catch (RemoteException e) { 8317 } catch (IllegalArgumentException e) { 8318 Slog.w(TAG, "Failed trying to unstop package " 8319 + cpr.appInfo.packageName + ": " + e); 8320 } 8321 8322 // Use existing process if already started 8323 ProcessRecord proc = getProcessRecordLocked( 8324 cpi.processName, cpr.appInfo.uid, false); 8325 if (proc != null && proc.thread != null) { 8326 if (DEBUG_PROVIDER) { 8327 Slog.d(TAG, "Installing in existing process " + proc); 8328 } 8329 proc.pubProviders.put(cpi.name, cpr); 8330 try { 8331 proc.thread.scheduleInstallProvider(cpi); 8332 } catch (RemoteException e) { 8333 } 8334 } else { 8335 proc = startProcessLocked(cpi.processName, 8336 cpr.appInfo, false, 0, "content provider", 8337 new ComponentName(cpi.applicationInfo.packageName, 8338 cpi.name), false, false, false); 8339 if (proc == null) { 8340 Slog.w(TAG, "Unable to launch app " 8341 + cpi.applicationInfo.packageName + "/" 8342 + cpi.applicationInfo.uid + " for provider " 8343 + name + ": process is bad"); 8344 return null; 8345 } 8346 } 8347 cpr.launchingApp = proc; 8348 mLaunchingProviders.add(cpr); 8349 } finally { 8350 Binder.restoreCallingIdentity(origId); 8351 } 8352 } 8353 8354 // Make sure the provider is published (the same provider class 8355 // may be published under multiple names). 8356 if (firstClass) { 8357 mProviderMap.putProviderByClass(comp, cpr); 8358 } 8359 8360 mProviderMap.putProviderByName(name, cpr); 8361 conn = incProviderCountLocked(r, cpr, token, stable); 8362 if (conn != null) { 8363 conn.waiting = true; 8364 } 8365 } 8366 } 8367 8368 // Wait for the provider to be published... 8369 synchronized (cpr) { 8370 while (cpr.provider == null) { 8371 if (cpr.launchingApp == null) { 8372 Slog.w(TAG, "Unable to launch app " 8373 + cpi.applicationInfo.packageName + "/" 8374 + cpi.applicationInfo.uid + " for provider " 8375 + name + ": launching app became null"); 8376 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8377 UserHandle.getUserId(cpi.applicationInfo.uid), 8378 cpi.applicationInfo.packageName, 8379 cpi.applicationInfo.uid, name); 8380 return null; 8381 } 8382 try { 8383 if (DEBUG_MU) { 8384 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8385 + cpr.launchingApp); 8386 } 8387 if (conn != null) { 8388 conn.waiting = true; 8389 } 8390 cpr.wait(); 8391 } catch (InterruptedException ex) { 8392 } finally { 8393 if (conn != null) { 8394 conn.waiting = false; 8395 } 8396 } 8397 } 8398 } 8399 return cpr != null ? cpr.newHolder(conn) : null; 8400 } 8401 8402 @Override 8403 public final ContentProviderHolder getContentProvider( 8404 IApplicationThread caller, String name, int userId, boolean stable) { 8405 enforceNotIsolatedCaller("getContentProvider"); 8406 if (caller == null) { 8407 String msg = "null IApplicationThread when getting content provider " 8408 + name; 8409 Slog.w(TAG, msg); 8410 throw new SecurityException(msg); 8411 } 8412 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8413 // with cross-user grant. 8414 return getContentProviderImpl(caller, name, null, stable, userId); 8415 } 8416 8417 public ContentProviderHolder getContentProviderExternal( 8418 String name, int userId, IBinder token) { 8419 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8420 "Do not have permission in call getContentProviderExternal()"); 8421 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8422 false, true, "getContentProvider", null); 8423 return getContentProviderExternalUnchecked(name, token, userId); 8424 } 8425 8426 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8427 IBinder token, int userId) { 8428 return getContentProviderImpl(null, name, token, true, userId); 8429 } 8430 8431 /** 8432 * Drop a content provider from a ProcessRecord's bookkeeping 8433 */ 8434 public void removeContentProvider(IBinder connection, boolean stable) { 8435 enforceNotIsolatedCaller("removeContentProvider"); 8436 long ident = Binder.clearCallingIdentity(); 8437 try { 8438 synchronized (this) { 8439 ContentProviderConnection conn; 8440 try { 8441 conn = (ContentProviderConnection)connection; 8442 } catch (ClassCastException e) { 8443 String msg ="removeContentProvider: " + connection 8444 + " not a ContentProviderConnection"; 8445 Slog.w(TAG, msg); 8446 throw new IllegalArgumentException(msg); 8447 } 8448 if (conn == null) { 8449 throw new NullPointerException("connection is null"); 8450 } 8451 if (decProviderCountLocked(conn, null, null, stable)) { 8452 updateOomAdjLocked(); 8453 } 8454 } 8455 } finally { 8456 Binder.restoreCallingIdentity(ident); 8457 } 8458 } 8459 8460 public void removeContentProviderExternal(String name, IBinder token) { 8461 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8462 "Do not have permission in call removeContentProviderExternal()"); 8463 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8464 } 8465 8466 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8467 synchronized (this) { 8468 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8469 if(cpr == null) { 8470 //remove from mProvidersByClass 8471 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8472 return; 8473 } 8474 8475 //update content provider record entry info 8476 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8477 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8478 if (localCpr.hasExternalProcessHandles()) { 8479 if (localCpr.removeExternalProcessHandleLocked(token)) { 8480 updateOomAdjLocked(); 8481 } else { 8482 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8483 + " with no external reference for token: " 8484 + token + "."); 8485 } 8486 } else { 8487 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8488 + " with no external references."); 8489 } 8490 } 8491 } 8492 8493 public final void publishContentProviders(IApplicationThread caller, 8494 List<ContentProviderHolder> providers) { 8495 if (providers == null) { 8496 return; 8497 } 8498 8499 enforceNotIsolatedCaller("publishContentProviders"); 8500 synchronized (this) { 8501 final ProcessRecord r = getRecordForAppLocked(caller); 8502 if (DEBUG_MU) 8503 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8504 if (r == null) { 8505 throw new SecurityException( 8506 "Unable to find app for caller " + caller 8507 + " (pid=" + Binder.getCallingPid() 8508 + ") when publishing content providers"); 8509 } 8510 8511 final long origId = Binder.clearCallingIdentity(); 8512 8513 final int N = providers.size(); 8514 for (int i=0; i<N; i++) { 8515 ContentProviderHolder src = providers.get(i); 8516 if (src == null || src.info == null || src.provider == null) { 8517 continue; 8518 } 8519 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8520 if (DEBUG_MU) 8521 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8522 if (dst != null) { 8523 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8524 mProviderMap.putProviderByClass(comp, dst); 8525 String names[] = dst.info.authority.split(";"); 8526 for (int j = 0; j < names.length; j++) { 8527 mProviderMap.putProviderByName(names[j], dst); 8528 } 8529 8530 int NL = mLaunchingProviders.size(); 8531 int j; 8532 for (j=0; j<NL; j++) { 8533 if (mLaunchingProviders.get(j) == dst) { 8534 mLaunchingProviders.remove(j); 8535 j--; 8536 NL--; 8537 } 8538 } 8539 synchronized (dst) { 8540 dst.provider = src.provider; 8541 dst.proc = r; 8542 dst.notifyAll(); 8543 } 8544 updateOomAdjLocked(r); 8545 } 8546 } 8547 8548 Binder.restoreCallingIdentity(origId); 8549 } 8550 } 8551 8552 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8553 ContentProviderConnection conn; 8554 try { 8555 conn = (ContentProviderConnection)connection; 8556 } catch (ClassCastException e) { 8557 String msg ="refContentProvider: " + connection 8558 + " not a ContentProviderConnection"; 8559 Slog.w(TAG, msg); 8560 throw new IllegalArgumentException(msg); 8561 } 8562 if (conn == null) { 8563 throw new NullPointerException("connection is null"); 8564 } 8565 8566 synchronized (this) { 8567 if (stable > 0) { 8568 conn.numStableIncs += stable; 8569 } 8570 stable = conn.stableCount + stable; 8571 if (stable < 0) { 8572 throw new IllegalStateException("stableCount < 0: " + stable); 8573 } 8574 8575 if (unstable > 0) { 8576 conn.numUnstableIncs += unstable; 8577 } 8578 unstable = conn.unstableCount + unstable; 8579 if (unstable < 0) { 8580 throw new IllegalStateException("unstableCount < 0: " + unstable); 8581 } 8582 8583 if ((stable+unstable) <= 0) { 8584 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8585 + stable + " unstable=" + unstable); 8586 } 8587 conn.stableCount = stable; 8588 conn.unstableCount = unstable; 8589 return !conn.dead; 8590 } 8591 } 8592 8593 public void unstableProviderDied(IBinder connection) { 8594 ContentProviderConnection conn; 8595 try { 8596 conn = (ContentProviderConnection)connection; 8597 } catch (ClassCastException e) { 8598 String msg ="refContentProvider: " + connection 8599 + " not a ContentProviderConnection"; 8600 Slog.w(TAG, msg); 8601 throw new IllegalArgumentException(msg); 8602 } 8603 if (conn == null) { 8604 throw new NullPointerException("connection is null"); 8605 } 8606 8607 // Safely retrieve the content provider associated with the connection. 8608 IContentProvider provider; 8609 synchronized (this) { 8610 provider = conn.provider.provider; 8611 } 8612 8613 if (provider == null) { 8614 // Um, yeah, we're way ahead of you. 8615 return; 8616 } 8617 8618 // Make sure the caller is being honest with us. 8619 if (provider.asBinder().pingBinder()) { 8620 // Er, no, still looks good to us. 8621 synchronized (this) { 8622 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8623 + " says " + conn + " died, but we don't agree"); 8624 return; 8625 } 8626 } 8627 8628 // Well look at that! It's dead! 8629 synchronized (this) { 8630 if (conn.provider.provider != provider) { 8631 // But something changed... good enough. 8632 return; 8633 } 8634 8635 ProcessRecord proc = conn.provider.proc; 8636 if (proc == null || proc.thread == null) { 8637 // Seems like the process is already cleaned up. 8638 return; 8639 } 8640 8641 // As far as we're concerned, this is just like receiving a 8642 // death notification... just a bit prematurely. 8643 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8644 + ") early provider death"); 8645 final long ident = Binder.clearCallingIdentity(); 8646 try { 8647 appDiedLocked(proc, proc.pid, proc.thread); 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 } 8652 } 8653 8654 @Override 8655 public void appNotRespondingViaProvider(IBinder connection) { 8656 enforceCallingPermission( 8657 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8658 8659 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8660 if (conn == null) { 8661 Slog.w(TAG, "ContentProviderConnection is null"); 8662 return; 8663 } 8664 8665 final ProcessRecord host = conn.provider.proc; 8666 if (host == null) { 8667 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8668 return; 8669 } 8670 8671 final long token = Binder.clearCallingIdentity(); 8672 try { 8673 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8674 } finally { 8675 Binder.restoreCallingIdentity(token); 8676 } 8677 } 8678 8679 public final void installSystemProviders() { 8680 List<ProviderInfo> providers; 8681 synchronized (this) { 8682 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8683 providers = generateApplicationProvidersLocked(app); 8684 if (providers != null) { 8685 for (int i=providers.size()-1; i>=0; i--) { 8686 ProviderInfo pi = (ProviderInfo)providers.get(i); 8687 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8688 Slog.w(TAG, "Not installing system proc provider " + pi.name 8689 + ": not system .apk"); 8690 providers.remove(i); 8691 } 8692 } 8693 } 8694 } 8695 if (providers != null) { 8696 mSystemThread.installSystemProviders(providers); 8697 } 8698 8699 mCoreSettingsObserver = new CoreSettingsObserver(this); 8700 8701 mUsageStatsService.monitorPackages(); 8702 } 8703 8704 /** 8705 * Allows app to retrieve the MIME type of a URI without having permission 8706 * to access its content provider. 8707 * 8708 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8709 * 8710 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8711 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8712 */ 8713 public String getProviderMimeType(Uri uri, int userId) { 8714 enforceNotIsolatedCaller("getProviderMimeType"); 8715 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8716 userId, false, true, "getProviderMimeType", null); 8717 final String name = uri.getAuthority(); 8718 final long ident = Binder.clearCallingIdentity(); 8719 ContentProviderHolder holder = null; 8720 8721 try { 8722 holder = getContentProviderExternalUnchecked(name, null, userId); 8723 if (holder != null) { 8724 return holder.provider.getType(uri); 8725 } 8726 } catch (RemoteException e) { 8727 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8728 return null; 8729 } finally { 8730 if (holder != null) { 8731 removeContentProviderExternalUnchecked(name, null, userId); 8732 } 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 8736 return null; 8737 } 8738 8739 // ========================================================= 8740 // GLOBAL MANAGEMENT 8741 // ========================================================= 8742 8743 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8744 boolean isolated) { 8745 String proc = customProcess != null ? customProcess : info.processName; 8746 BatteryStatsImpl.Uid.Proc ps = null; 8747 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8748 int uid = info.uid; 8749 if (isolated) { 8750 int userId = UserHandle.getUserId(uid); 8751 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8752 while (true) { 8753 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8754 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8755 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8756 } 8757 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8758 mNextIsolatedProcessUid++; 8759 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8760 // No process for this uid, use it. 8761 break; 8762 } 8763 stepsLeft--; 8764 if (stepsLeft <= 0) { 8765 return null; 8766 } 8767 } 8768 } 8769 return new ProcessRecord(stats, info, proc, uid); 8770 } 8771 8772 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8773 String abiOverride) { 8774 ProcessRecord app; 8775 if (!isolated) { 8776 app = getProcessRecordLocked(info.processName, info.uid, true); 8777 } else { 8778 app = null; 8779 } 8780 8781 if (app == null) { 8782 app = newProcessRecordLocked(info, null, isolated); 8783 mProcessNames.put(info.processName, app.uid, app); 8784 if (isolated) { 8785 mIsolatedProcesses.put(app.uid, app); 8786 } 8787 updateLruProcessLocked(app, false, null); 8788 updateOomAdjLocked(); 8789 } 8790 8791 // This package really, really can not be stopped. 8792 try { 8793 AppGlobals.getPackageManager().setPackageStoppedState( 8794 info.packageName, false, UserHandle.getUserId(app.uid)); 8795 } catch (RemoteException e) { 8796 } catch (IllegalArgumentException e) { 8797 Slog.w(TAG, "Failed trying to unstop package " 8798 + info.packageName + ": " + e); 8799 } 8800 8801 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8802 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8803 app.persistent = true; 8804 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8805 } 8806 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8807 mPersistentStartingProcesses.add(app); 8808 startProcessLocked(app, "added application", app.processName, 8809 abiOverride); 8810 } 8811 8812 return app; 8813 } 8814 8815 public void unhandledBack() { 8816 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8817 "unhandledBack()"); 8818 8819 synchronized(this) { 8820 final long origId = Binder.clearCallingIdentity(); 8821 try { 8822 getFocusedStack().unhandledBackLocked(); 8823 } finally { 8824 Binder.restoreCallingIdentity(origId); 8825 } 8826 } 8827 } 8828 8829 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8830 enforceNotIsolatedCaller("openContentUri"); 8831 final int userId = UserHandle.getCallingUserId(); 8832 String name = uri.getAuthority(); 8833 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8834 ParcelFileDescriptor pfd = null; 8835 if (cph != null) { 8836 // We record the binder invoker's uid in thread-local storage before 8837 // going to the content provider to open the file. Later, in the code 8838 // that handles all permissions checks, we look for this uid and use 8839 // that rather than the Activity Manager's own uid. The effect is that 8840 // we do the check against the caller's permissions even though it looks 8841 // to the content provider like the Activity Manager itself is making 8842 // the request. 8843 sCallerIdentity.set(new Identity( 8844 Binder.getCallingPid(), Binder.getCallingUid())); 8845 try { 8846 pfd = cph.provider.openFile(null, uri, "r", null); 8847 } catch (FileNotFoundException e) { 8848 // do nothing; pfd will be returned null 8849 } finally { 8850 // Ensure that whatever happens, we clean up the identity state 8851 sCallerIdentity.remove(); 8852 } 8853 8854 // We've got the fd now, so we're done with the provider. 8855 removeContentProviderExternalUnchecked(name, null, userId); 8856 } else { 8857 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8858 } 8859 return pfd; 8860 } 8861 8862 // Actually is sleeping or shutting down or whatever else in the future 8863 // is an inactive state. 8864 public boolean isSleepingOrShuttingDown() { 8865 return mSleeping || mShuttingDown; 8866 } 8867 8868 public boolean isSleeping() { 8869 return mSleeping; 8870 } 8871 8872 void goingToSleep() { 8873 synchronized(this) { 8874 mWentToSleep = true; 8875 updateEventDispatchingLocked(); 8876 goToSleepIfNeededLocked(); 8877 } 8878 } 8879 8880 void finishRunningVoiceLocked() { 8881 if (mRunningVoice) { 8882 mRunningVoice = false; 8883 goToSleepIfNeededLocked(); 8884 } 8885 } 8886 8887 void goToSleepIfNeededLocked() { 8888 if (mWentToSleep && !mRunningVoice) { 8889 if (!mSleeping) { 8890 mSleeping = true; 8891 mStackSupervisor.goingToSleepLocked(); 8892 8893 // Initialize the wake times of all processes. 8894 checkExcessivePowerUsageLocked(false); 8895 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8896 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8897 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8898 } 8899 } 8900 } 8901 8902 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8903 mTaskPersister.notify(task, flush); 8904 } 8905 8906 @Override 8907 public boolean shutdown(int timeout) { 8908 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8909 != PackageManager.PERMISSION_GRANTED) { 8910 throw new SecurityException("Requires permission " 8911 + android.Manifest.permission.SHUTDOWN); 8912 } 8913 8914 boolean timedout = false; 8915 8916 synchronized(this) { 8917 mShuttingDown = true; 8918 updateEventDispatchingLocked(); 8919 timedout = mStackSupervisor.shutdownLocked(timeout); 8920 } 8921 8922 mAppOpsService.shutdown(); 8923 mUsageStatsService.shutdown(); 8924 mBatteryStatsService.shutdown(); 8925 synchronized (this) { 8926 mProcessStats.shutdownLocked(); 8927 } 8928 notifyTaskPersisterLocked(null, true); 8929 8930 return timedout; 8931 } 8932 8933 public final void activitySlept(IBinder token) { 8934 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8935 8936 final long origId = Binder.clearCallingIdentity(); 8937 8938 synchronized (this) { 8939 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8940 if (r != null) { 8941 mStackSupervisor.activitySleptLocked(r); 8942 } 8943 } 8944 8945 Binder.restoreCallingIdentity(origId); 8946 } 8947 8948 void logLockScreen(String msg) { 8949 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8950 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8951 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8952 mStackSupervisor.mDismissKeyguardOnNextActivity); 8953 } 8954 8955 private void comeOutOfSleepIfNeededLocked() { 8956 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8957 if (mSleeping) { 8958 mSleeping = false; 8959 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8960 } 8961 } 8962 } 8963 8964 void wakingUp() { 8965 synchronized(this) { 8966 mWentToSleep = false; 8967 updateEventDispatchingLocked(); 8968 comeOutOfSleepIfNeededLocked(); 8969 } 8970 } 8971 8972 void startRunningVoiceLocked() { 8973 if (!mRunningVoice) { 8974 mRunningVoice = true; 8975 comeOutOfSleepIfNeededLocked(); 8976 } 8977 } 8978 8979 private void updateEventDispatchingLocked() { 8980 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8981 } 8982 8983 public void setLockScreenShown(boolean shown) { 8984 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8985 != PackageManager.PERMISSION_GRANTED) { 8986 throw new SecurityException("Requires permission " 8987 + android.Manifest.permission.DEVICE_POWER); 8988 } 8989 8990 synchronized(this) { 8991 long ident = Binder.clearCallingIdentity(); 8992 try { 8993 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8994 mLockScreenShown = shown; 8995 comeOutOfSleepIfNeededLocked(); 8996 } finally { 8997 Binder.restoreCallingIdentity(ident); 8998 } 8999 } 9000 } 9001 9002 public void stopAppSwitches() { 9003 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9004 != PackageManager.PERMISSION_GRANTED) { 9005 throw new SecurityException("Requires permission " 9006 + android.Manifest.permission.STOP_APP_SWITCHES); 9007 } 9008 9009 synchronized(this) { 9010 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9011 + APP_SWITCH_DELAY_TIME; 9012 mDidAppSwitch = false; 9013 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9014 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9015 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9016 } 9017 } 9018 9019 public void resumeAppSwitches() { 9020 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9021 != PackageManager.PERMISSION_GRANTED) { 9022 throw new SecurityException("Requires permission " 9023 + android.Manifest.permission.STOP_APP_SWITCHES); 9024 } 9025 9026 synchronized(this) { 9027 // Note that we don't execute any pending app switches... we will 9028 // let those wait until either the timeout, or the next start 9029 // activity request. 9030 mAppSwitchesAllowedTime = 0; 9031 } 9032 } 9033 9034 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9035 String name) { 9036 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9037 return true; 9038 } 9039 9040 final int perm = checkComponentPermission( 9041 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9042 callingUid, -1, true); 9043 if (perm == PackageManager.PERMISSION_GRANTED) { 9044 return true; 9045 } 9046 9047 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9048 return false; 9049 } 9050 9051 public void setDebugApp(String packageName, boolean waitForDebugger, 9052 boolean persistent) { 9053 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9054 "setDebugApp()"); 9055 9056 long ident = Binder.clearCallingIdentity(); 9057 try { 9058 // Note that this is not really thread safe if there are multiple 9059 // callers into it at the same time, but that's not a situation we 9060 // care about. 9061 if (persistent) { 9062 final ContentResolver resolver = mContext.getContentResolver(); 9063 Settings.Global.putString( 9064 resolver, Settings.Global.DEBUG_APP, 9065 packageName); 9066 Settings.Global.putInt( 9067 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9068 waitForDebugger ? 1 : 0); 9069 } 9070 9071 synchronized (this) { 9072 if (!persistent) { 9073 mOrigDebugApp = mDebugApp; 9074 mOrigWaitForDebugger = mWaitForDebugger; 9075 } 9076 mDebugApp = packageName; 9077 mWaitForDebugger = waitForDebugger; 9078 mDebugTransient = !persistent; 9079 if (packageName != null) { 9080 forceStopPackageLocked(packageName, -1, false, false, true, true, 9081 false, UserHandle.USER_ALL, "set debug app"); 9082 } 9083 } 9084 } finally { 9085 Binder.restoreCallingIdentity(ident); 9086 } 9087 } 9088 9089 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9090 synchronized (this) { 9091 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9092 if (!isDebuggable) { 9093 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9094 throw new SecurityException("Process not debuggable: " + app.packageName); 9095 } 9096 } 9097 9098 mOpenGlTraceApp = processName; 9099 } 9100 } 9101 9102 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9103 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9104 synchronized (this) { 9105 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9106 if (!isDebuggable) { 9107 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9108 throw new SecurityException("Process not debuggable: " + app.packageName); 9109 } 9110 } 9111 mProfileApp = processName; 9112 mProfileFile = profileFile; 9113 if (mProfileFd != null) { 9114 try { 9115 mProfileFd.close(); 9116 } catch (IOException e) { 9117 } 9118 mProfileFd = null; 9119 } 9120 mProfileFd = profileFd; 9121 mProfileType = 0; 9122 mAutoStopProfiler = autoStopProfiler; 9123 } 9124 } 9125 9126 @Override 9127 public void setAlwaysFinish(boolean enabled) { 9128 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9129 "setAlwaysFinish()"); 9130 9131 Settings.Global.putInt( 9132 mContext.getContentResolver(), 9133 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9134 9135 synchronized (this) { 9136 mAlwaysFinishActivities = enabled; 9137 } 9138 } 9139 9140 @Override 9141 public void setActivityController(IActivityController controller) { 9142 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9143 "setActivityController()"); 9144 synchronized (this) { 9145 mController = controller; 9146 Watchdog.getInstance().setActivityController(controller); 9147 } 9148 } 9149 9150 @Override 9151 public void setUserIsMonkey(boolean userIsMonkey) { 9152 synchronized (this) { 9153 synchronized (mPidsSelfLocked) { 9154 final int callingPid = Binder.getCallingPid(); 9155 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9156 if (precessRecord == null) { 9157 throw new SecurityException("Unknown process: " + callingPid); 9158 } 9159 if (precessRecord.instrumentationUiAutomationConnection == null) { 9160 throw new SecurityException("Only an instrumentation process " 9161 + "with a UiAutomation can call setUserIsMonkey"); 9162 } 9163 } 9164 mUserIsMonkey = userIsMonkey; 9165 } 9166 } 9167 9168 @Override 9169 public boolean isUserAMonkey() { 9170 synchronized (this) { 9171 // If there is a controller also implies the user is a monkey. 9172 return (mUserIsMonkey || mController != null); 9173 } 9174 } 9175 9176 public void requestBugReport() { 9177 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9178 SystemProperties.set("ctl.start", "bugreport"); 9179 } 9180 9181 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9182 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9183 } 9184 9185 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9186 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9187 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9188 } 9189 return KEY_DISPATCHING_TIMEOUT; 9190 } 9191 9192 @Override 9193 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9194 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9195 != PackageManager.PERMISSION_GRANTED) { 9196 throw new SecurityException("Requires permission " 9197 + android.Manifest.permission.FILTER_EVENTS); 9198 } 9199 ProcessRecord proc; 9200 long timeout; 9201 synchronized (this) { 9202 synchronized (mPidsSelfLocked) { 9203 proc = mPidsSelfLocked.get(pid); 9204 } 9205 timeout = getInputDispatchingTimeoutLocked(proc); 9206 } 9207 9208 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9209 return -1; 9210 } 9211 9212 return timeout; 9213 } 9214 9215 /** 9216 * Handle input dispatching timeouts. 9217 * Returns whether input dispatching should be aborted or not. 9218 */ 9219 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9220 final ActivityRecord activity, final ActivityRecord parent, 9221 final boolean aboveSystem, String reason) { 9222 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9223 != PackageManager.PERMISSION_GRANTED) { 9224 throw new SecurityException("Requires permission " 9225 + android.Manifest.permission.FILTER_EVENTS); 9226 } 9227 9228 final String annotation; 9229 if (reason == null) { 9230 annotation = "Input dispatching timed out"; 9231 } else { 9232 annotation = "Input dispatching timed out (" + reason + ")"; 9233 } 9234 9235 if (proc != null) { 9236 synchronized (this) { 9237 if (proc.debugging) { 9238 return false; 9239 } 9240 9241 if (mDidDexOpt) { 9242 // Give more time since we were dexopting. 9243 mDidDexOpt = false; 9244 return false; 9245 } 9246 9247 if (proc.instrumentationClass != null) { 9248 Bundle info = new Bundle(); 9249 info.putString("shortMsg", "keyDispatchingTimedOut"); 9250 info.putString("longMsg", annotation); 9251 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9252 return true; 9253 } 9254 } 9255 mHandler.post(new Runnable() { 9256 @Override 9257 public void run() { 9258 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9259 } 9260 }); 9261 } 9262 9263 return true; 9264 } 9265 9266 public Bundle getAssistContextExtras(int requestType) { 9267 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9268 "getAssistContextExtras()"); 9269 PendingAssistExtras pae; 9270 Bundle extras = new Bundle(); 9271 synchronized (this) { 9272 ActivityRecord activity = getFocusedStack().mResumedActivity; 9273 if (activity == null) { 9274 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9275 return null; 9276 } 9277 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9278 if (activity.app == null || activity.app.thread == null) { 9279 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9280 return extras; 9281 } 9282 if (activity.app.pid == Binder.getCallingPid()) { 9283 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9284 return extras; 9285 } 9286 pae = new PendingAssistExtras(activity); 9287 try { 9288 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9289 requestType); 9290 mPendingAssistExtras.add(pae); 9291 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9292 } catch (RemoteException e) { 9293 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9294 return extras; 9295 } 9296 } 9297 synchronized (pae) { 9298 while (!pae.haveResult) { 9299 try { 9300 pae.wait(); 9301 } catch (InterruptedException e) { 9302 } 9303 } 9304 if (pae.result != null) { 9305 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9306 } 9307 } 9308 synchronized (this) { 9309 mPendingAssistExtras.remove(pae); 9310 mHandler.removeCallbacks(pae); 9311 } 9312 return extras; 9313 } 9314 9315 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9316 PendingAssistExtras pae = (PendingAssistExtras)token; 9317 synchronized (pae) { 9318 pae.result = extras; 9319 pae.haveResult = true; 9320 pae.notifyAll(); 9321 } 9322 } 9323 9324 public void registerProcessObserver(IProcessObserver observer) { 9325 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9326 "registerProcessObserver()"); 9327 synchronized (this) { 9328 mProcessObservers.register(observer); 9329 } 9330 } 9331 9332 @Override 9333 public void unregisterProcessObserver(IProcessObserver observer) { 9334 synchronized (this) { 9335 mProcessObservers.unregister(observer); 9336 } 9337 } 9338 9339 @Override 9340 public boolean convertFromTranslucent(IBinder token) { 9341 final long origId = Binder.clearCallingIdentity(); 9342 try { 9343 synchronized (this) { 9344 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9345 if (r == null) { 9346 return false; 9347 } 9348 if (r.changeWindowTranslucency(true)) { 9349 mWindowManager.setAppFullscreen(token, true); 9350 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9351 return true; 9352 } 9353 return false; 9354 } 9355 } finally { 9356 Binder.restoreCallingIdentity(origId); 9357 } 9358 } 9359 9360 @Override 9361 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9362 final long origId = Binder.clearCallingIdentity(); 9363 try { 9364 synchronized (this) { 9365 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9366 if (r == null) { 9367 return false; 9368 } 9369 if (r.changeWindowTranslucency(false)) { 9370 r.task.stack.convertToTranslucent(r, options); 9371 mWindowManager.setAppFullscreen(token, false); 9372 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9373 return true; 9374 } 9375 return false; 9376 } 9377 } finally { 9378 Binder.restoreCallingIdentity(origId); 9379 } 9380 } 9381 9382 @Override 9383 public ActivityOptions getActivityOptions(IBinder token) { 9384 final long origId = Binder.clearCallingIdentity(); 9385 try { 9386 synchronized (this) { 9387 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9388 if (r != null) { 9389 final ActivityOptions activityOptions = r.pendingOptions; 9390 r.pendingOptions = null; 9391 return activityOptions; 9392 } 9393 return null; 9394 } 9395 } finally { 9396 Binder.restoreCallingIdentity(origId); 9397 } 9398 } 9399 9400 @Override 9401 public void setImmersive(IBinder token, boolean immersive) { 9402 synchronized(this) { 9403 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9404 if (r == null) { 9405 throw new IllegalArgumentException(); 9406 } 9407 r.immersive = immersive; 9408 9409 // update associated state if we're frontmost 9410 if (r == mFocusedActivity) { 9411 if (DEBUG_IMMERSIVE) { 9412 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9413 } 9414 applyUpdateLockStateLocked(r); 9415 } 9416 } 9417 } 9418 9419 @Override 9420 public boolean isImmersive(IBinder token) { 9421 synchronized (this) { 9422 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9423 if (r == null) { 9424 throw new IllegalArgumentException(); 9425 } 9426 return r.immersive; 9427 } 9428 } 9429 9430 public boolean isTopActivityImmersive() { 9431 enforceNotIsolatedCaller("startActivity"); 9432 synchronized (this) { 9433 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9434 return (r != null) ? r.immersive : false; 9435 } 9436 } 9437 9438 public final void enterSafeMode() { 9439 synchronized(this) { 9440 // It only makes sense to do this before the system is ready 9441 // and started launching other packages. 9442 if (!mSystemReady) { 9443 try { 9444 AppGlobals.getPackageManager().enterSafeMode(); 9445 } catch (RemoteException e) { 9446 } 9447 } 9448 9449 mSafeMode = true; 9450 } 9451 } 9452 9453 public final void showSafeModeOverlay() { 9454 View v = LayoutInflater.from(mContext).inflate( 9455 com.android.internal.R.layout.safe_mode, null); 9456 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9457 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9458 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9459 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9460 lp.gravity = Gravity.BOTTOM | Gravity.START; 9461 lp.format = v.getBackground().getOpacity(); 9462 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9463 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9464 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9465 ((WindowManager)mContext.getSystemService( 9466 Context.WINDOW_SERVICE)).addView(v, lp); 9467 } 9468 9469 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9470 if (!(sender instanceof PendingIntentRecord)) { 9471 return; 9472 } 9473 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9474 synchronized (stats) { 9475 if (mBatteryStatsService.isOnBattery()) { 9476 mBatteryStatsService.enforceCallingPermission(); 9477 PendingIntentRecord rec = (PendingIntentRecord)sender; 9478 int MY_UID = Binder.getCallingUid(); 9479 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9480 BatteryStatsImpl.Uid.Pkg pkg = 9481 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9482 sourcePkg != null ? sourcePkg : rec.key.packageName); 9483 pkg.incWakeupsLocked(); 9484 } 9485 } 9486 } 9487 9488 public boolean killPids(int[] pids, String pReason, boolean secure) { 9489 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9490 throw new SecurityException("killPids only available to the system"); 9491 } 9492 String reason = (pReason == null) ? "Unknown" : pReason; 9493 // XXX Note: don't acquire main activity lock here, because the window 9494 // manager calls in with its locks held. 9495 9496 boolean killed = false; 9497 synchronized (mPidsSelfLocked) { 9498 int[] types = new int[pids.length]; 9499 int worstType = 0; 9500 for (int i=0; i<pids.length; i++) { 9501 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9502 if (proc != null) { 9503 int type = proc.setAdj; 9504 types[i] = type; 9505 if (type > worstType) { 9506 worstType = type; 9507 } 9508 } 9509 } 9510 9511 // If the worst oom_adj is somewhere in the cached proc LRU range, 9512 // then constrain it so we will kill all cached procs. 9513 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9514 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9515 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9516 } 9517 9518 // If this is not a secure call, don't let it kill processes that 9519 // are important. 9520 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9521 worstType = ProcessList.SERVICE_ADJ; 9522 } 9523 9524 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9525 for (int i=0; i<pids.length; i++) { 9526 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9527 if (proc == null) { 9528 continue; 9529 } 9530 int adj = proc.setAdj; 9531 if (adj >= worstType && !proc.killedByAm) { 9532 killUnneededProcessLocked(proc, reason); 9533 killed = true; 9534 } 9535 } 9536 } 9537 return killed; 9538 } 9539 9540 @Override 9541 public void killUid(int uid, String reason) { 9542 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9543 throw new SecurityException("killUid only available to the system"); 9544 } 9545 synchronized (this) { 9546 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9547 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9548 reason != null ? reason : "kill uid"); 9549 } 9550 } 9551 9552 @Override 9553 public boolean killProcessesBelowForeground(String reason) { 9554 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9555 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9556 } 9557 9558 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9559 } 9560 9561 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9562 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9563 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9564 } 9565 9566 boolean killed = false; 9567 synchronized (mPidsSelfLocked) { 9568 final int size = mPidsSelfLocked.size(); 9569 for (int i = 0; i < size; i++) { 9570 final int pid = mPidsSelfLocked.keyAt(i); 9571 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9572 if (proc == null) continue; 9573 9574 final int adj = proc.setAdj; 9575 if (adj > belowAdj && !proc.killedByAm) { 9576 killUnneededProcessLocked(proc, reason); 9577 killed = true; 9578 } 9579 } 9580 } 9581 return killed; 9582 } 9583 9584 @Override 9585 public void hang(final IBinder who, boolean allowRestart) { 9586 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9587 != PackageManager.PERMISSION_GRANTED) { 9588 throw new SecurityException("Requires permission " 9589 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9590 } 9591 9592 final IBinder.DeathRecipient death = new DeathRecipient() { 9593 @Override 9594 public void binderDied() { 9595 synchronized (this) { 9596 notifyAll(); 9597 } 9598 } 9599 }; 9600 9601 try { 9602 who.linkToDeath(death, 0); 9603 } catch (RemoteException e) { 9604 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9605 return; 9606 } 9607 9608 synchronized (this) { 9609 Watchdog.getInstance().setAllowRestart(allowRestart); 9610 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9611 synchronized (death) { 9612 while (who.isBinderAlive()) { 9613 try { 9614 death.wait(); 9615 } catch (InterruptedException e) { 9616 } 9617 } 9618 } 9619 Watchdog.getInstance().setAllowRestart(true); 9620 } 9621 } 9622 9623 @Override 9624 public void restart() { 9625 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9626 != PackageManager.PERMISSION_GRANTED) { 9627 throw new SecurityException("Requires permission " 9628 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9629 } 9630 9631 Log.i(TAG, "Sending shutdown broadcast..."); 9632 9633 BroadcastReceiver br = new BroadcastReceiver() { 9634 @Override public void onReceive(Context context, Intent intent) { 9635 // Now the broadcast is done, finish up the low-level shutdown. 9636 Log.i(TAG, "Shutting down activity manager..."); 9637 shutdown(10000); 9638 Log.i(TAG, "Shutdown complete, restarting!"); 9639 Process.killProcess(Process.myPid()); 9640 System.exit(10); 9641 } 9642 }; 9643 9644 // First send the high-level shut down broadcast. 9645 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9646 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9647 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9648 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9649 mContext.sendOrderedBroadcastAsUser(intent, 9650 UserHandle.ALL, null, br, mHandler, 0, null, null); 9651 */ 9652 br.onReceive(mContext, intent); 9653 } 9654 9655 private long getLowRamTimeSinceIdle(long now) { 9656 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9657 } 9658 9659 @Override 9660 public void performIdleMaintenance() { 9661 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9662 != PackageManager.PERMISSION_GRANTED) { 9663 throw new SecurityException("Requires permission " 9664 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9665 } 9666 9667 synchronized (this) { 9668 final long now = SystemClock.uptimeMillis(); 9669 final long timeSinceLastIdle = now - mLastIdleTime; 9670 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9671 mLastIdleTime = now; 9672 mLowRamTimeSinceLastIdle = 0; 9673 if (mLowRamStartTime != 0) { 9674 mLowRamStartTime = now; 9675 } 9676 9677 StringBuilder sb = new StringBuilder(128); 9678 sb.append("Idle maintenance over "); 9679 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9680 sb.append(" low RAM for "); 9681 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9682 Slog.i(TAG, sb.toString()); 9683 9684 // If at least 1/3 of our time since the last idle period has been spent 9685 // with RAM low, then we want to kill processes. 9686 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9687 9688 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9689 ProcessRecord proc = mLruProcesses.get(i); 9690 if (proc.notCachedSinceIdle) { 9691 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9692 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9693 if (doKilling && proc.initialIdlePss != 0 9694 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9695 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9696 + " from " + proc.initialIdlePss + ")"); 9697 } 9698 } 9699 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9700 proc.notCachedSinceIdle = true; 9701 proc.initialIdlePss = 0; 9702 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9703 isSleeping(), now); 9704 } 9705 } 9706 9707 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9708 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9709 } 9710 } 9711 9712 private void retrieveSettings() { 9713 final ContentResolver resolver = mContext.getContentResolver(); 9714 String debugApp = Settings.Global.getString( 9715 resolver, Settings.Global.DEBUG_APP); 9716 boolean waitForDebugger = Settings.Global.getInt( 9717 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9718 boolean alwaysFinishActivities = Settings.Global.getInt( 9719 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9720 boolean forceRtl = Settings.Global.getInt( 9721 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9722 // Transfer any global setting for forcing RTL layout, into a System Property 9723 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9724 9725 Configuration configuration = new Configuration(); 9726 Settings.System.getConfiguration(resolver, configuration); 9727 if (forceRtl) { 9728 // This will take care of setting the correct layout direction flags 9729 configuration.setLayoutDirection(configuration.locale); 9730 } 9731 9732 synchronized (this) { 9733 mDebugApp = mOrigDebugApp = debugApp; 9734 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9735 mAlwaysFinishActivities = alwaysFinishActivities; 9736 // This happens before any activities are started, so we can 9737 // change mConfiguration in-place. 9738 updateConfigurationLocked(configuration, null, false, true); 9739 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9740 } 9741 } 9742 9743 public boolean testIsSystemReady() { 9744 // no need to synchronize(this) just to read & return the value 9745 return mSystemReady; 9746 } 9747 9748 private static File getCalledPreBootReceiversFile() { 9749 File dataDir = Environment.getDataDirectory(); 9750 File systemDir = new File(dataDir, "system"); 9751 File fname = new File(systemDir, "called_pre_boots.dat"); 9752 return fname; 9753 } 9754 9755 static final int LAST_DONE_VERSION = 10000; 9756 9757 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9758 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9759 File file = getCalledPreBootReceiversFile(); 9760 FileInputStream fis = null; 9761 try { 9762 fis = new FileInputStream(file); 9763 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9764 int fvers = dis.readInt(); 9765 if (fvers == LAST_DONE_VERSION) { 9766 String vers = dis.readUTF(); 9767 String codename = dis.readUTF(); 9768 String build = dis.readUTF(); 9769 if (android.os.Build.VERSION.RELEASE.equals(vers) 9770 && android.os.Build.VERSION.CODENAME.equals(codename) 9771 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9772 int num = dis.readInt(); 9773 while (num > 0) { 9774 num--; 9775 String pkg = dis.readUTF(); 9776 String cls = dis.readUTF(); 9777 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9778 } 9779 } 9780 } 9781 } catch (FileNotFoundException e) { 9782 } catch (IOException e) { 9783 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9784 } finally { 9785 if (fis != null) { 9786 try { 9787 fis.close(); 9788 } catch (IOException e) { 9789 } 9790 } 9791 } 9792 return lastDoneReceivers; 9793 } 9794 9795 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9796 File file = getCalledPreBootReceiversFile(); 9797 FileOutputStream fos = null; 9798 DataOutputStream dos = null; 9799 try { 9800 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9801 fos = new FileOutputStream(file); 9802 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9803 dos.writeInt(LAST_DONE_VERSION); 9804 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9805 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9806 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9807 dos.writeInt(list.size()); 9808 for (int i=0; i<list.size(); i++) { 9809 dos.writeUTF(list.get(i).getPackageName()); 9810 dos.writeUTF(list.get(i).getClassName()); 9811 } 9812 } catch (IOException e) { 9813 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9814 file.delete(); 9815 } finally { 9816 FileUtils.sync(fos); 9817 if (dos != null) { 9818 try { 9819 dos.close(); 9820 } catch (IOException e) { 9821 // TODO Auto-generated catch block 9822 e.printStackTrace(); 9823 } 9824 } 9825 } 9826 } 9827 9828 public void systemReady(final Runnable goingCallback) { 9829 synchronized(this) { 9830 if (mSystemReady) { 9831 if (goingCallback != null) goingCallback.run(); 9832 return; 9833 } 9834 9835 if (mRecentTasks == null) { 9836 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9837 if (!mRecentTasks.isEmpty()) { 9838 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9839 } 9840 mTaskPersister.startPersisting(); 9841 } 9842 9843 // Check to see if there are any update receivers to run. 9844 if (!mDidUpdate) { 9845 if (mWaitingUpdate) { 9846 return; 9847 } 9848 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9849 List<ResolveInfo> ris = null; 9850 try { 9851 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9852 intent, null, 0, 0); 9853 } catch (RemoteException e) { 9854 } 9855 if (ris != null) { 9856 for (int i=ris.size()-1; i>=0; i--) { 9857 if ((ris.get(i).activityInfo.applicationInfo.flags 9858 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9859 ris.remove(i); 9860 } 9861 } 9862 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9863 9864 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9865 9866 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9867 for (int i=0; i<ris.size(); i++) { 9868 ActivityInfo ai = ris.get(i).activityInfo; 9869 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9870 if (lastDoneReceivers.contains(comp)) { 9871 // We already did the pre boot receiver for this app with the current 9872 // platform version, so don't do it again... 9873 ris.remove(i); 9874 i--; 9875 // ...however, do keep it as one that has been done, so we don't 9876 // forget about it when rewriting the file of last done receivers. 9877 doneReceivers.add(comp); 9878 } 9879 } 9880 9881 final int[] users = getUsersLocked(); 9882 for (int i=0; i<ris.size(); i++) { 9883 ActivityInfo ai = ris.get(i).activityInfo; 9884 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9885 doneReceivers.add(comp); 9886 intent.setComponent(comp); 9887 for (int j=0; j<users.length; j++) { 9888 IIntentReceiver finisher = null; 9889 if (i == ris.size()-1 && j == users.length-1) { 9890 finisher = new IIntentReceiver.Stub() { 9891 public void performReceive(Intent intent, int resultCode, 9892 String data, Bundle extras, boolean ordered, 9893 boolean sticky, int sendingUser) { 9894 // The raw IIntentReceiver interface is called 9895 // with the AM lock held, so redispatch to 9896 // execute our code without the lock. 9897 mHandler.post(new Runnable() { 9898 public void run() { 9899 synchronized (ActivityManagerService.this) { 9900 mDidUpdate = true; 9901 } 9902 writeLastDonePreBootReceivers(doneReceivers); 9903 showBootMessage(mContext.getText( 9904 R.string.android_upgrading_complete), 9905 false); 9906 systemReady(goingCallback); 9907 } 9908 }); 9909 } 9910 }; 9911 } 9912 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9913 + " for user " + users[j]); 9914 broadcastIntentLocked(null, null, intent, null, finisher, 9915 0, null, null, null, AppOpsManager.OP_NONE, 9916 true, false, MY_PID, Process.SYSTEM_UID, 9917 users[j]); 9918 if (finisher != null) { 9919 mWaitingUpdate = true; 9920 } 9921 } 9922 } 9923 } 9924 if (mWaitingUpdate) { 9925 return; 9926 } 9927 mDidUpdate = true; 9928 } 9929 9930 mAppOpsService.systemReady(); 9931 mUsageStatsService.systemReady(); 9932 mSystemReady = true; 9933 } 9934 9935 ArrayList<ProcessRecord> procsToKill = null; 9936 synchronized(mPidsSelfLocked) { 9937 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9938 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9939 if (!isAllowedWhileBooting(proc.info)){ 9940 if (procsToKill == null) { 9941 procsToKill = new ArrayList<ProcessRecord>(); 9942 } 9943 procsToKill.add(proc); 9944 } 9945 } 9946 } 9947 9948 synchronized(this) { 9949 if (procsToKill != null) { 9950 for (int i=procsToKill.size()-1; i>=0; i--) { 9951 ProcessRecord proc = procsToKill.get(i); 9952 Slog.i(TAG, "Removing system update proc: " + proc); 9953 removeProcessLocked(proc, true, false, "system update done"); 9954 } 9955 } 9956 9957 // Now that we have cleaned up any update processes, we 9958 // are ready to start launching real processes and know that 9959 // we won't trample on them any more. 9960 mProcessesReady = true; 9961 } 9962 9963 Slog.i(TAG, "System now ready"); 9964 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9965 SystemClock.uptimeMillis()); 9966 9967 synchronized(this) { 9968 // Make sure we have no pre-ready processes sitting around. 9969 9970 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9971 ResolveInfo ri = mContext.getPackageManager() 9972 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9973 STOCK_PM_FLAGS); 9974 CharSequence errorMsg = null; 9975 if (ri != null) { 9976 ActivityInfo ai = ri.activityInfo; 9977 ApplicationInfo app = ai.applicationInfo; 9978 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9979 mTopAction = Intent.ACTION_FACTORY_TEST; 9980 mTopData = null; 9981 mTopComponent = new ComponentName(app.packageName, 9982 ai.name); 9983 } else { 9984 errorMsg = mContext.getResources().getText( 9985 com.android.internal.R.string.factorytest_not_system); 9986 } 9987 } else { 9988 errorMsg = mContext.getResources().getText( 9989 com.android.internal.R.string.factorytest_no_action); 9990 } 9991 if (errorMsg != null) { 9992 mTopAction = null; 9993 mTopData = null; 9994 mTopComponent = null; 9995 Message msg = Message.obtain(); 9996 msg.what = SHOW_FACTORY_ERROR_MSG; 9997 msg.getData().putCharSequence("msg", errorMsg); 9998 mHandler.sendMessage(msg); 9999 } 10000 } 10001 } 10002 10003 retrieveSettings(); 10004 10005 synchronized (this) { 10006 readGrantedUriPermissionsLocked(); 10007 } 10008 10009 if (goingCallback != null) goingCallback.run(); 10010 10011 mSystemServiceManager.startUser(mCurrentUserId); 10012 10013 synchronized (this) { 10014 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10015 try { 10016 List apps = AppGlobals.getPackageManager(). 10017 getPersistentApplications(STOCK_PM_FLAGS); 10018 if (apps != null) { 10019 int N = apps.size(); 10020 int i; 10021 for (i=0; i<N; i++) { 10022 ApplicationInfo info 10023 = (ApplicationInfo)apps.get(i); 10024 if (info != null && 10025 !info.packageName.equals("android")) { 10026 addAppLocked(info, false, null /* ABI override */); 10027 } 10028 } 10029 } 10030 } catch (RemoteException ex) { 10031 // pm is in same process, this will never happen. 10032 } 10033 } 10034 10035 // Start up initial activity. 10036 mBooting = true; 10037 10038 try { 10039 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10040 Message msg = Message.obtain(); 10041 msg.what = SHOW_UID_ERROR_MSG; 10042 mHandler.sendMessage(msg); 10043 } 10044 } catch (RemoteException e) { 10045 } 10046 10047 long ident = Binder.clearCallingIdentity(); 10048 try { 10049 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10051 | Intent.FLAG_RECEIVER_FOREGROUND); 10052 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10053 broadcastIntentLocked(null, null, intent, 10054 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10055 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10056 intent = new Intent(Intent.ACTION_USER_STARTING); 10057 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10058 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10059 broadcastIntentLocked(null, null, intent, 10060 null, new IIntentReceiver.Stub() { 10061 @Override 10062 public void performReceive(Intent intent, int resultCode, String data, 10063 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10064 throws RemoteException { 10065 } 10066 }, 0, null, null, 10067 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10068 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10069 } catch (Throwable t) { 10070 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10071 } finally { 10072 Binder.restoreCallingIdentity(ident); 10073 } 10074 mStackSupervisor.resumeTopActivitiesLocked(); 10075 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10076 } 10077 } 10078 10079 private boolean makeAppCrashingLocked(ProcessRecord app, 10080 String shortMsg, String longMsg, String stackTrace) { 10081 app.crashing = true; 10082 app.crashingReport = generateProcessError(app, 10083 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10084 startAppProblemLocked(app); 10085 app.stopFreezingAllLocked(); 10086 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10087 } 10088 10089 private void makeAppNotRespondingLocked(ProcessRecord app, 10090 String activity, String shortMsg, String longMsg) { 10091 app.notResponding = true; 10092 app.notRespondingReport = generateProcessError(app, 10093 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10094 activity, shortMsg, longMsg, null); 10095 startAppProblemLocked(app); 10096 app.stopFreezingAllLocked(); 10097 } 10098 10099 /** 10100 * Generate a process error record, suitable for attachment to a ProcessRecord. 10101 * 10102 * @param app The ProcessRecord in which the error occurred. 10103 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10104 * ActivityManager.AppErrorStateInfo 10105 * @param activity The activity associated with the crash, if known. 10106 * @param shortMsg Short message describing the crash. 10107 * @param longMsg Long message describing the crash. 10108 * @param stackTrace Full crash stack trace, may be null. 10109 * 10110 * @return Returns a fully-formed AppErrorStateInfo record. 10111 */ 10112 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10113 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10114 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10115 10116 report.condition = condition; 10117 report.processName = app.processName; 10118 report.pid = app.pid; 10119 report.uid = app.info.uid; 10120 report.tag = activity; 10121 report.shortMsg = shortMsg; 10122 report.longMsg = longMsg; 10123 report.stackTrace = stackTrace; 10124 10125 return report; 10126 } 10127 10128 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10129 synchronized (this) { 10130 app.crashing = false; 10131 app.crashingReport = null; 10132 app.notResponding = false; 10133 app.notRespondingReport = null; 10134 if (app.anrDialog == fromDialog) { 10135 app.anrDialog = null; 10136 } 10137 if (app.waitDialog == fromDialog) { 10138 app.waitDialog = null; 10139 } 10140 if (app.pid > 0 && app.pid != MY_PID) { 10141 handleAppCrashLocked(app, null, null, null); 10142 killUnneededProcessLocked(app, "user request after error"); 10143 } 10144 } 10145 } 10146 10147 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10148 String stackTrace) { 10149 long now = SystemClock.uptimeMillis(); 10150 10151 Long crashTime; 10152 if (!app.isolated) { 10153 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10154 } else { 10155 crashTime = null; 10156 } 10157 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10158 // This process loses! 10159 Slog.w(TAG, "Process " + app.info.processName 10160 + " has crashed too many times: killing!"); 10161 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10162 app.userId, app.info.processName, app.uid); 10163 mStackSupervisor.handleAppCrashLocked(app); 10164 if (!app.persistent) { 10165 // We don't want to start this process again until the user 10166 // explicitly does so... but for persistent process, we really 10167 // need to keep it running. If a persistent process is actually 10168 // repeatedly crashing, then badness for everyone. 10169 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10170 app.info.processName); 10171 if (!app.isolated) { 10172 // XXX We don't have a way to mark isolated processes 10173 // as bad, since they don't have a peristent identity. 10174 mBadProcesses.put(app.info.processName, app.uid, 10175 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10176 mProcessCrashTimes.remove(app.info.processName, app.uid); 10177 } 10178 app.bad = true; 10179 app.removed = true; 10180 // Don't let services in this process be restarted and potentially 10181 // annoy the user repeatedly. Unless it is persistent, since those 10182 // processes run critical code. 10183 removeProcessLocked(app, false, false, "crash"); 10184 mStackSupervisor.resumeTopActivitiesLocked(); 10185 return false; 10186 } 10187 mStackSupervisor.resumeTopActivitiesLocked(); 10188 } else { 10189 mStackSupervisor.finishTopRunningActivityLocked(app); 10190 } 10191 10192 // Bump up the crash count of any services currently running in the proc. 10193 for (int i=app.services.size()-1; i>=0; i--) { 10194 // Any services running in the application need to be placed 10195 // back in the pending list. 10196 ServiceRecord sr = app.services.valueAt(i); 10197 sr.crashCount++; 10198 } 10199 10200 // If the crashing process is what we consider to be the "home process" and it has been 10201 // replaced by a third-party app, clear the package preferred activities from packages 10202 // with a home activity running in the process to prevent a repeatedly crashing app 10203 // from blocking the user to manually clear the list. 10204 final ArrayList<ActivityRecord> activities = app.activities; 10205 if (app == mHomeProcess && activities.size() > 0 10206 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10207 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10208 final ActivityRecord r = activities.get(activityNdx); 10209 if (r.isHomeActivity()) { 10210 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10211 try { 10212 ActivityThread.getPackageManager() 10213 .clearPackagePreferredActivities(r.packageName); 10214 } catch (RemoteException c) { 10215 // pm is in same process, this will never happen. 10216 } 10217 } 10218 } 10219 } 10220 10221 if (!app.isolated) { 10222 // XXX Can't keep track of crash times for isolated processes, 10223 // because they don't have a perisistent identity. 10224 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10225 } 10226 10227 return true; 10228 } 10229 10230 void startAppProblemLocked(ProcessRecord app) { 10231 if (app.userId == mCurrentUserId) { 10232 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10233 mContext, app.info.packageName, app.info.flags); 10234 } else { 10235 // If this app is not running under the current user, then we 10236 // can't give it a report button because that would require 10237 // launching the report UI under a different user. 10238 app.errorReportReceiver = null; 10239 } 10240 skipCurrentReceiverLocked(app); 10241 } 10242 10243 void skipCurrentReceiverLocked(ProcessRecord app) { 10244 for (BroadcastQueue queue : mBroadcastQueues) { 10245 queue.skipCurrentReceiverLocked(app); 10246 } 10247 } 10248 10249 /** 10250 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10251 * The application process will exit immediately after this call returns. 10252 * @param app object of the crashing app, null for the system server 10253 * @param crashInfo describing the exception 10254 */ 10255 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10256 ProcessRecord r = findAppProcess(app, "Crash"); 10257 final String processName = app == null ? "system_server" 10258 : (r == null ? "unknown" : r.processName); 10259 10260 handleApplicationCrashInner("crash", r, processName, crashInfo); 10261 } 10262 10263 /* Native crash reporting uses this inner version because it needs to be somewhat 10264 * decoupled from the AM-managed cleanup lifecycle 10265 */ 10266 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10267 ApplicationErrorReport.CrashInfo crashInfo) { 10268 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10269 UserHandle.getUserId(Binder.getCallingUid()), processName, 10270 r == null ? -1 : r.info.flags, 10271 crashInfo.exceptionClassName, 10272 crashInfo.exceptionMessage, 10273 crashInfo.throwFileName, 10274 crashInfo.throwLineNumber); 10275 10276 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10277 10278 crashApplication(r, crashInfo); 10279 } 10280 10281 public void handleApplicationStrictModeViolation( 10282 IBinder app, 10283 int violationMask, 10284 StrictMode.ViolationInfo info) { 10285 ProcessRecord r = findAppProcess(app, "StrictMode"); 10286 if (r == null) { 10287 return; 10288 } 10289 10290 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10291 Integer stackFingerprint = info.hashCode(); 10292 boolean logIt = true; 10293 synchronized (mAlreadyLoggedViolatedStacks) { 10294 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10295 logIt = false; 10296 // TODO: sub-sample into EventLog for these, with 10297 // the info.durationMillis? Then we'd get 10298 // the relative pain numbers, without logging all 10299 // the stack traces repeatedly. We'd want to do 10300 // likewise in the client code, which also does 10301 // dup suppression, before the Binder call. 10302 } else { 10303 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10304 mAlreadyLoggedViolatedStacks.clear(); 10305 } 10306 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10307 } 10308 } 10309 if (logIt) { 10310 logStrictModeViolationToDropBox(r, info); 10311 } 10312 } 10313 10314 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10315 AppErrorResult result = new AppErrorResult(); 10316 synchronized (this) { 10317 final long origId = Binder.clearCallingIdentity(); 10318 10319 Message msg = Message.obtain(); 10320 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10321 HashMap<String, Object> data = new HashMap<String, Object>(); 10322 data.put("result", result); 10323 data.put("app", r); 10324 data.put("violationMask", violationMask); 10325 data.put("info", info); 10326 msg.obj = data; 10327 mHandler.sendMessage(msg); 10328 10329 Binder.restoreCallingIdentity(origId); 10330 } 10331 int res = result.get(); 10332 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10333 } 10334 } 10335 10336 // Depending on the policy in effect, there could be a bunch of 10337 // these in quick succession so we try to batch these together to 10338 // minimize disk writes, number of dropbox entries, and maximize 10339 // compression, by having more fewer, larger records. 10340 private void logStrictModeViolationToDropBox( 10341 ProcessRecord process, 10342 StrictMode.ViolationInfo info) { 10343 if (info == null) { 10344 return; 10345 } 10346 final boolean isSystemApp = process == null || 10347 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10348 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10349 final String processName = process == null ? "unknown" : process.processName; 10350 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10351 final DropBoxManager dbox = (DropBoxManager) 10352 mContext.getSystemService(Context.DROPBOX_SERVICE); 10353 10354 // Exit early if the dropbox isn't configured to accept this report type. 10355 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10356 10357 boolean bufferWasEmpty; 10358 boolean needsFlush; 10359 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10360 synchronized (sb) { 10361 bufferWasEmpty = sb.length() == 0; 10362 appendDropBoxProcessHeaders(process, processName, sb); 10363 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10364 sb.append("System-App: ").append(isSystemApp).append("\n"); 10365 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10366 if (info.violationNumThisLoop != 0) { 10367 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10368 } 10369 if (info.numAnimationsRunning != 0) { 10370 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10371 } 10372 if (info.broadcastIntentAction != null) { 10373 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10374 } 10375 if (info.durationMillis != -1) { 10376 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10377 } 10378 if (info.numInstances != -1) { 10379 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10380 } 10381 if (info.tags != null) { 10382 for (String tag : info.tags) { 10383 sb.append("Span-Tag: ").append(tag).append("\n"); 10384 } 10385 } 10386 sb.append("\n"); 10387 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10388 sb.append(info.crashInfo.stackTrace); 10389 } 10390 sb.append("\n"); 10391 10392 // Only buffer up to ~64k. Various logging bits truncate 10393 // things at 128k. 10394 needsFlush = (sb.length() > 64 * 1024); 10395 } 10396 10397 // Flush immediately if the buffer's grown too large, or this 10398 // is a non-system app. Non-system apps are isolated with a 10399 // different tag & policy and not batched. 10400 // 10401 // Batching is useful during internal testing with 10402 // StrictMode settings turned up high. Without batching, 10403 // thousands of separate files could be created on boot. 10404 if (!isSystemApp || needsFlush) { 10405 new Thread("Error dump: " + dropboxTag) { 10406 @Override 10407 public void run() { 10408 String report; 10409 synchronized (sb) { 10410 report = sb.toString(); 10411 sb.delete(0, sb.length()); 10412 sb.trimToSize(); 10413 } 10414 if (report.length() != 0) { 10415 dbox.addText(dropboxTag, report); 10416 } 10417 } 10418 }.start(); 10419 return; 10420 } 10421 10422 // System app batching: 10423 if (!bufferWasEmpty) { 10424 // An existing dropbox-writing thread is outstanding, so 10425 // we don't need to start it up. The existing thread will 10426 // catch the buffer appends we just did. 10427 return; 10428 } 10429 10430 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10431 // (After this point, we shouldn't access AMS internal data structures.) 10432 new Thread("Error dump: " + dropboxTag) { 10433 @Override 10434 public void run() { 10435 // 5 second sleep to let stacks arrive and be batched together 10436 try { 10437 Thread.sleep(5000); // 5 seconds 10438 } catch (InterruptedException e) {} 10439 10440 String errorReport; 10441 synchronized (mStrictModeBuffer) { 10442 errorReport = mStrictModeBuffer.toString(); 10443 if (errorReport.length() == 0) { 10444 return; 10445 } 10446 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10447 mStrictModeBuffer.trimToSize(); 10448 } 10449 dbox.addText(dropboxTag, errorReport); 10450 } 10451 }.start(); 10452 } 10453 10454 /** 10455 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10456 * @param app object of the crashing app, null for the system server 10457 * @param tag reported by the caller 10458 * @param crashInfo describing the context of the error 10459 * @return true if the process should exit immediately (WTF is fatal) 10460 */ 10461 public boolean handleApplicationWtf(IBinder app, String tag, 10462 ApplicationErrorReport.CrashInfo crashInfo) { 10463 ProcessRecord r = findAppProcess(app, "WTF"); 10464 final String processName = app == null ? "system_server" 10465 : (r == null ? "unknown" : r.processName); 10466 10467 EventLog.writeEvent(EventLogTags.AM_WTF, 10468 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10469 processName, 10470 r == null ? -1 : r.info.flags, 10471 tag, crashInfo.exceptionMessage); 10472 10473 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10474 10475 if (r != null && r.pid != Process.myPid() && 10476 Settings.Global.getInt(mContext.getContentResolver(), 10477 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10478 crashApplication(r, crashInfo); 10479 return true; 10480 } else { 10481 return false; 10482 } 10483 } 10484 10485 /** 10486 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10487 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10488 */ 10489 private ProcessRecord findAppProcess(IBinder app, String reason) { 10490 if (app == null) { 10491 return null; 10492 } 10493 10494 synchronized (this) { 10495 final int NP = mProcessNames.getMap().size(); 10496 for (int ip=0; ip<NP; ip++) { 10497 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10498 final int NA = apps.size(); 10499 for (int ia=0; ia<NA; ia++) { 10500 ProcessRecord p = apps.valueAt(ia); 10501 if (p.thread != null && p.thread.asBinder() == app) { 10502 return p; 10503 } 10504 } 10505 } 10506 10507 Slog.w(TAG, "Can't find mystery application for " + reason 10508 + " from pid=" + Binder.getCallingPid() 10509 + " uid=" + Binder.getCallingUid() + ": " + app); 10510 return null; 10511 } 10512 } 10513 10514 /** 10515 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10516 * to append various headers to the dropbox log text. 10517 */ 10518 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10519 StringBuilder sb) { 10520 // Watchdog thread ends up invoking this function (with 10521 // a null ProcessRecord) to add the stack file to dropbox. 10522 // Do not acquire a lock on this (am) in such cases, as it 10523 // could cause a potential deadlock, if and when watchdog 10524 // is invoked due to unavailability of lock on am and it 10525 // would prevent watchdog from killing system_server. 10526 if (process == null) { 10527 sb.append("Process: ").append(processName).append("\n"); 10528 return; 10529 } 10530 // Note: ProcessRecord 'process' is guarded by the service 10531 // instance. (notably process.pkgList, which could otherwise change 10532 // concurrently during execution of this method) 10533 synchronized (this) { 10534 sb.append("Process: ").append(processName).append("\n"); 10535 int flags = process.info.flags; 10536 IPackageManager pm = AppGlobals.getPackageManager(); 10537 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10538 for (int ip=0; ip<process.pkgList.size(); ip++) { 10539 String pkg = process.pkgList.keyAt(ip); 10540 sb.append("Package: ").append(pkg); 10541 try { 10542 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10543 if (pi != null) { 10544 sb.append(" v").append(pi.versionCode); 10545 if (pi.versionName != null) { 10546 sb.append(" (").append(pi.versionName).append(")"); 10547 } 10548 } 10549 } catch (RemoteException e) { 10550 Slog.e(TAG, "Error getting package info: " + pkg, e); 10551 } 10552 sb.append("\n"); 10553 } 10554 } 10555 } 10556 10557 private static String processClass(ProcessRecord process) { 10558 if (process == null || process.pid == MY_PID) { 10559 return "system_server"; 10560 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10561 return "system_app"; 10562 } else { 10563 return "data_app"; 10564 } 10565 } 10566 10567 /** 10568 * Write a description of an error (crash, WTF, ANR) to the drop box. 10569 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10570 * @param process which caused the error, null means the system server 10571 * @param activity which triggered the error, null if unknown 10572 * @param parent activity related to the error, null if unknown 10573 * @param subject line related to the error, null if absent 10574 * @param report in long form describing the error, null if absent 10575 * @param logFile to include in the report, null if none 10576 * @param crashInfo giving an application stack trace, null if absent 10577 */ 10578 public void addErrorToDropBox(String eventType, 10579 ProcessRecord process, String processName, ActivityRecord activity, 10580 ActivityRecord parent, String subject, 10581 final String report, final File logFile, 10582 final ApplicationErrorReport.CrashInfo crashInfo) { 10583 // NOTE -- this must never acquire the ActivityManagerService lock, 10584 // otherwise the watchdog may be prevented from resetting the system. 10585 10586 final String dropboxTag = processClass(process) + "_" + eventType; 10587 final DropBoxManager dbox = (DropBoxManager) 10588 mContext.getSystemService(Context.DROPBOX_SERVICE); 10589 10590 // Exit early if the dropbox isn't configured to accept this report type. 10591 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10592 10593 final StringBuilder sb = new StringBuilder(1024); 10594 appendDropBoxProcessHeaders(process, processName, sb); 10595 if (activity != null) { 10596 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10597 } 10598 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10599 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10600 } 10601 if (parent != null && parent != activity) { 10602 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10603 } 10604 if (subject != null) { 10605 sb.append("Subject: ").append(subject).append("\n"); 10606 } 10607 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10608 if (Debug.isDebuggerConnected()) { 10609 sb.append("Debugger: Connected\n"); 10610 } 10611 sb.append("\n"); 10612 10613 // Do the rest in a worker thread to avoid blocking the caller on I/O 10614 // (After this point, we shouldn't access AMS internal data structures.) 10615 Thread worker = new Thread("Error dump: " + dropboxTag) { 10616 @Override 10617 public void run() { 10618 if (report != null) { 10619 sb.append(report); 10620 } 10621 if (logFile != null) { 10622 try { 10623 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10624 "\n\n[[TRUNCATED]]")); 10625 } catch (IOException e) { 10626 Slog.e(TAG, "Error reading " + logFile, e); 10627 } 10628 } 10629 if (crashInfo != null && crashInfo.stackTrace != null) { 10630 sb.append(crashInfo.stackTrace); 10631 } 10632 10633 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10634 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10635 if (lines > 0) { 10636 sb.append("\n"); 10637 10638 // Merge several logcat streams, and take the last N lines 10639 InputStreamReader input = null; 10640 try { 10641 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10642 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10643 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10644 10645 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10646 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10647 input = new InputStreamReader(logcat.getInputStream()); 10648 10649 int num; 10650 char[] buf = new char[8192]; 10651 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10652 } catch (IOException e) { 10653 Slog.e(TAG, "Error running logcat", e); 10654 } finally { 10655 if (input != null) try { input.close(); } catch (IOException e) {} 10656 } 10657 } 10658 10659 dbox.addText(dropboxTag, sb.toString()); 10660 } 10661 }; 10662 10663 if (process == null) { 10664 // If process is null, we are being called from some internal code 10665 // and may be about to die -- run this synchronously. 10666 worker.run(); 10667 } else { 10668 worker.start(); 10669 } 10670 } 10671 10672 /** 10673 * Bring up the "unexpected error" dialog box for a crashing app. 10674 * Deal with edge cases (intercepts from instrumented applications, 10675 * ActivityController, error intent receivers, that sort of thing). 10676 * @param r the application crashing 10677 * @param crashInfo describing the failure 10678 */ 10679 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10680 long timeMillis = System.currentTimeMillis(); 10681 String shortMsg = crashInfo.exceptionClassName; 10682 String longMsg = crashInfo.exceptionMessage; 10683 String stackTrace = crashInfo.stackTrace; 10684 if (shortMsg != null && longMsg != null) { 10685 longMsg = shortMsg + ": " + longMsg; 10686 } else if (shortMsg != null) { 10687 longMsg = shortMsg; 10688 } 10689 10690 AppErrorResult result = new AppErrorResult(); 10691 synchronized (this) { 10692 if (mController != null) { 10693 try { 10694 String name = r != null ? r.processName : null; 10695 int pid = r != null ? r.pid : Binder.getCallingPid(); 10696 if (!mController.appCrashed(name, pid, 10697 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10698 Slog.w(TAG, "Force-killing crashed app " + name 10699 + " at watcher's request"); 10700 Process.killProcess(pid); 10701 return; 10702 } 10703 } catch (RemoteException e) { 10704 mController = null; 10705 Watchdog.getInstance().setActivityController(null); 10706 } 10707 } 10708 10709 final long origId = Binder.clearCallingIdentity(); 10710 10711 // If this process is running instrumentation, finish it. 10712 if (r != null && r.instrumentationClass != null) { 10713 Slog.w(TAG, "Error in app " + r.processName 10714 + " running instrumentation " + r.instrumentationClass + ":"); 10715 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10716 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10717 Bundle info = new Bundle(); 10718 info.putString("shortMsg", shortMsg); 10719 info.putString("longMsg", longMsg); 10720 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10721 Binder.restoreCallingIdentity(origId); 10722 return; 10723 } 10724 10725 // If we can't identify the process or it's already exceeded its crash quota, 10726 // quit right away without showing a crash dialog. 10727 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10728 Binder.restoreCallingIdentity(origId); 10729 return; 10730 } 10731 10732 Message msg = Message.obtain(); 10733 msg.what = SHOW_ERROR_MSG; 10734 HashMap data = new HashMap(); 10735 data.put("result", result); 10736 data.put("app", r); 10737 msg.obj = data; 10738 mHandler.sendMessage(msg); 10739 10740 Binder.restoreCallingIdentity(origId); 10741 } 10742 10743 int res = result.get(); 10744 10745 Intent appErrorIntent = null; 10746 synchronized (this) { 10747 if (r != null && !r.isolated) { 10748 // XXX Can't keep track of crash time for isolated processes, 10749 // since they don't have a persistent identity. 10750 mProcessCrashTimes.put(r.info.processName, r.uid, 10751 SystemClock.uptimeMillis()); 10752 } 10753 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10754 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10755 } 10756 } 10757 10758 if (appErrorIntent != null) { 10759 try { 10760 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10761 } catch (ActivityNotFoundException e) { 10762 Slog.w(TAG, "bug report receiver dissappeared", e); 10763 } 10764 } 10765 } 10766 10767 Intent createAppErrorIntentLocked(ProcessRecord r, 10768 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10769 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10770 if (report == null) { 10771 return null; 10772 } 10773 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10774 result.setComponent(r.errorReportReceiver); 10775 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10776 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10777 return result; 10778 } 10779 10780 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10781 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10782 if (r.errorReportReceiver == null) { 10783 return null; 10784 } 10785 10786 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10787 return null; 10788 } 10789 10790 ApplicationErrorReport report = new ApplicationErrorReport(); 10791 report.packageName = r.info.packageName; 10792 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10793 report.processName = r.processName; 10794 report.time = timeMillis; 10795 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10796 10797 if (r.crashing || r.forceCrashReport) { 10798 report.type = ApplicationErrorReport.TYPE_CRASH; 10799 report.crashInfo = crashInfo; 10800 } else if (r.notResponding) { 10801 report.type = ApplicationErrorReport.TYPE_ANR; 10802 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10803 10804 report.anrInfo.activity = r.notRespondingReport.tag; 10805 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10806 report.anrInfo.info = r.notRespondingReport.longMsg; 10807 } 10808 10809 return report; 10810 } 10811 10812 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10813 enforceNotIsolatedCaller("getProcessesInErrorState"); 10814 // assume our apps are happy - lazy create the list 10815 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10816 10817 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10818 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10819 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10820 10821 synchronized (this) { 10822 10823 // iterate across all processes 10824 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10825 ProcessRecord app = mLruProcesses.get(i); 10826 if (!allUsers && app.userId != userId) { 10827 continue; 10828 } 10829 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10830 // This one's in trouble, so we'll generate a report for it 10831 // crashes are higher priority (in case there's a crash *and* an anr) 10832 ActivityManager.ProcessErrorStateInfo report = null; 10833 if (app.crashing) { 10834 report = app.crashingReport; 10835 } else if (app.notResponding) { 10836 report = app.notRespondingReport; 10837 } 10838 10839 if (report != null) { 10840 if (errList == null) { 10841 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10842 } 10843 errList.add(report); 10844 } else { 10845 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10846 " crashing = " + app.crashing + 10847 " notResponding = " + app.notResponding); 10848 } 10849 } 10850 } 10851 } 10852 10853 return errList; 10854 } 10855 10856 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10857 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10858 if (currApp != null) { 10859 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10860 } 10861 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10862 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10863 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10864 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10865 if (currApp != null) { 10866 currApp.lru = 0; 10867 } 10868 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10869 } else if (adj >= ProcessList.SERVICE_ADJ) { 10870 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10871 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10872 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10873 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10874 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10875 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10876 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10877 } else { 10878 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10879 } 10880 } 10881 10882 private void fillInProcMemInfo(ProcessRecord app, 10883 ActivityManager.RunningAppProcessInfo outInfo) { 10884 outInfo.pid = app.pid; 10885 outInfo.uid = app.info.uid; 10886 if (mHeavyWeightProcess == app) { 10887 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10888 } 10889 if (app.persistent) { 10890 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10891 } 10892 if (app.activities.size() > 0) { 10893 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10894 } 10895 outInfo.lastTrimLevel = app.trimMemoryLevel; 10896 int adj = app.curAdj; 10897 outInfo.importance = oomAdjToImportance(adj, outInfo); 10898 outInfo.importanceReasonCode = app.adjTypeCode; 10899 outInfo.processState = app.curProcState; 10900 } 10901 10902 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10903 enforceNotIsolatedCaller("getRunningAppProcesses"); 10904 // Lazy instantiation of list 10905 List<ActivityManager.RunningAppProcessInfo> runList = null; 10906 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10907 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10908 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10909 synchronized (this) { 10910 // Iterate across all processes 10911 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10912 ProcessRecord app = mLruProcesses.get(i); 10913 if (!allUsers && app.userId != userId) { 10914 continue; 10915 } 10916 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10917 // Generate process state info for running application 10918 ActivityManager.RunningAppProcessInfo currApp = 10919 new ActivityManager.RunningAppProcessInfo(app.processName, 10920 app.pid, app.getPackageList()); 10921 fillInProcMemInfo(app, currApp); 10922 if (app.adjSource instanceof ProcessRecord) { 10923 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10924 currApp.importanceReasonImportance = oomAdjToImportance( 10925 app.adjSourceOom, null); 10926 } else if (app.adjSource instanceof ActivityRecord) { 10927 ActivityRecord r = (ActivityRecord)app.adjSource; 10928 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10929 } 10930 if (app.adjTarget instanceof ComponentName) { 10931 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10932 } 10933 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10934 // + " lru=" + currApp.lru); 10935 if (runList == null) { 10936 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10937 } 10938 runList.add(currApp); 10939 } 10940 } 10941 } 10942 return runList; 10943 } 10944 10945 public List<ApplicationInfo> getRunningExternalApplications() { 10946 enforceNotIsolatedCaller("getRunningExternalApplications"); 10947 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10948 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10949 if (runningApps != null && runningApps.size() > 0) { 10950 Set<String> extList = new HashSet<String>(); 10951 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10952 if (app.pkgList != null) { 10953 for (String pkg : app.pkgList) { 10954 extList.add(pkg); 10955 } 10956 } 10957 } 10958 IPackageManager pm = AppGlobals.getPackageManager(); 10959 for (String pkg : extList) { 10960 try { 10961 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10962 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10963 retList.add(info); 10964 } 10965 } catch (RemoteException e) { 10966 } 10967 } 10968 } 10969 return retList; 10970 } 10971 10972 @Override 10973 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10974 enforceNotIsolatedCaller("getMyMemoryState"); 10975 synchronized (this) { 10976 ProcessRecord proc; 10977 synchronized (mPidsSelfLocked) { 10978 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10979 } 10980 fillInProcMemInfo(proc, outInfo); 10981 } 10982 } 10983 10984 @Override 10985 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10986 if (checkCallingPermission(android.Manifest.permission.DUMP) 10987 != PackageManager.PERMISSION_GRANTED) { 10988 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10989 + Binder.getCallingPid() 10990 + ", uid=" + Binder.getCallingUid() 10991 + " without permission " 10992 + android.Manifest.permission.DUMP); 10993 return; 10994 } 10995 10996 boolean dumpAll = false; 10997 boolean dumpClient = false; 10998 String dumpPackage = null; 10999 11000 int opti = 0; 11001 while (opti < args.length) { 11002 String opt = args[opti]; 11003 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11004 break; 11005 } 11006 opti++; 11007 if ("-a".equals(opt)) { 11008 dumpAll = true; 11009 } else if ("-c".equals(opt)) { 11010 dumpClient = true; 11011 } else if ("-h".equals(opt)) { 11012 pw.println("Activity manager dump options:"); 11013 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11014 pw.println(" cmd may be one of:"); 11015 pw.println(" a[ctivities]: activity stack state"); 11016 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11017 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11018 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11019 pw.println(" o[om]: out of memory management"); 11020 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11021 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11022 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11023 pw.println(" service [COMP_SPEC]: service client-side state"); 11024 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11025 pw.println(" all: dump all activities"); 11026 pw.println(" top: dump the top activity"); 11027 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11028 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11029 pw.println(" a partial substring in a component name, a"); 11030 pw.println(" hex object identifier."); 11031 pw.println(" -a: include all available server state."); 11032 pw.println(" -c: include client state."); 11033 return; 11034 } else { 11035 pw.println("Unknown argument: " + opt + "; use -h for help"); 11036 } 11037 } 11038 11039 long origId = Binder.clearCallingIdentity(); 11040 boolean more = false; 11041 // Is the caller requesting to dump a particular piece of data? 11042 if (opti < args.length) { 11043 String cmd = args[opti]; 11044 opti++; 11045 if ("activities".equals(cmd) || "a".equals(cmd)) { 11046 synchronized (this) { 11047 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11048 } 11049 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11050 String[] newArgs; 11051 String name; 11052 if (opti >= args.length) { 11053 name = null; 11054 newArgs = EMPTY_STRING_ARRAY; 11055 } else { 11056 name = args[opti]; 11057 opti++; 11058 newArgs = new String[args.length - opti]; 11059 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11060 args.length - opti); 11061 } 11062 synchronized (this) { 11063 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11064 } 11065 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11066 String[] newArgs; 11067 String name; 11068 if (opti >= args.length) { 11069 name = null; 11070 newArgs = EMPTY_STRING_ARRAY; 11071 } else { 11072 name = args[opti]; 11073 opti++; 11074 newArgs = new String[args.length - opti]; 11075 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11076 args.length - opti); 11077 } 11078 synchronized (this) { 11079 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11080 } 11081 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11082 String[] newArgs; 11083 String name; 11084 if (opti >= args.length) { 11085 name = null; 11086 newArgs = EMPTY_STRING_ARRAY; 11087 } else { 11088 name = args[opti]; 11089 opti++; 11090 newArgs = new String[args.length - opti]; 11091 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11092 args.length - opti); 11093 } 11094 synchronized (this) { 11095 dumpProcessesLocked(fd, pw, args, opti, true, name); 11096 } 11097 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11098 synchronized (this) { 11099 dumpOomLocked(fd, pw, args, opti, true); 11100 } 11101 } else if ("provider".equals(cmd)) { 11102 String[] newArgs; 11103 String name; 11104 if (opti >= args.length) { 11105 name = null; 11106 newArgs = EMPTY_STRING_ARRAY; 11107 } else { 11108 name = args[opti]; 11109 opti++; 11110 newArgs = new String[args.length - opti]; 11111 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11112 } 11113 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11114 pw.println("No providers match: " + name); 11115 pw.println("Use -h for help."); 11116 } 11117 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11118 synchronized (this) { 11119 dumpProvidersLocked(fd, pw, args, opti, true, null); 11120 } 11121 } else if ("service".equals(cmd)) { 11122 String[] newArgs; 11123 String name; 11124 if (opti >= args.length) { 11125 name = null; 11126 newArgs = EMPTY_STRING_ARRAY; 11127 } else { 11128 name = args[opti]; 11129 opti++; 11130 newArgs = new String[args.length - opti]; 11131 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11132 args.length - opti); 11133 } 11134 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11135 pw.println("No services match: " + name); 11136 pw.println("Use -h for help."); 11137 } 11138 } else if ("package".equals(cmd)) { 11139 String[] newArgs; 11140 if (opti >= args.length) { 11141 pw.println("package: no package name specified"); 11142 pw.println("Use -h for help."); 11143 } else { 11144 dumpPackage = args[opti]; 11145 opti++; 11146 newArgs = new String[args.length - opti]; 11147 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11148 args.length - opti); 11149 args = newArgs; 11150 opti = 0; 11151 more = true; 11152 } 11153 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11154 synchronized (this) { 11155 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11156 } 11157 } else { 11158 // Dumping a single activity? 11159 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11160 pw.println("Bad activity command, or no activities match: " + cmd); 11161 pw.println("Use -h for help."); 11162 } 11163 } 11164 if (!more) { 11165 Binder.restoreCallingIdentity(origId); 11166 return; 11167 } 11168 } 11169 11170 // No piece of data specified, dump everything. 11171 synchronized (this) { 11172 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11173 pw.println(); 11174 if (dumpAll) { 11175 pw.println("-------------------------------------------------------------------------------"); 11176 } 11177 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11178 pw.println(); 11179 if (dumpAll) { 11180 pw.println("-------------------------------------------------------------------------------"); 11181 } 11182 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11183 pw.println(); 11184 if (dumpAll) { 11185 pw.println("-------------------------------------------------------------------------------"); 11186 } 11187 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11188 pw.println(); 11189 if (dumpAll) { 11190 pw.println("-------------------------------------------------------------------------------"); 11191 } 11192 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11193 pw.println(); 11194 if (dumpAll) { 11195 pw.println("-------------------------------------------------------------------------------"); 11196 } 11197 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11198 } 11199 Binder.restoreCallingIdentity(origId); 11200 } 11201 11202 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11203 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11204 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11205 11206 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11207 dumpPackage); 11208 boolean needSep = printedAnything; 11209 11210 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11211 dumpPackage, needSep, " mFocusedActivity: "); 11212 if (printed) { 11213 printedAnything = true; 11214 needSep = false; 11215 } 11216 11217 if (dumpPackage == null) { 11218 if (needSep) { 11219 pw.println(); 11220 } 11221 needSep = true; 11222 printedAnything = true; 11223 mStackSupervisor.dump(pw, " "); 11224 } 11225 11226 if (mRecentTasks.size() > 0) { 11227 boolean printedHeader = false; 11228 11229 final int N = mRecentTasks.size(); 11230 for (int i=0; i<N; i++) { 11231 TaskRecord tr = mRecentTasks.get(i); 11232 if (dumpPackage != null) { 11233 if (tr.realActivity == null || 11234 !dumpPackage.equals(tr.realActivity)) { 11235 continue; 11236 } 11237 } 11238 if (!printedHeader) { 11239 if (needSep) { 11240 pw.println(); 11241 } 11242 pw.println(" Recent tasks:"); 11243 printedHeader = true; 11244 printedAnything = true; 11245 } 11246 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11247 pw.println(tr); 11248 if (dumpAll) { 11249 mRecentTasks.get(i).dump(pw, " "); 11250 } 11251 } 11252 } 11253 11254 if (!printedAnything) { 11255 pw.println(" (nothing)"); 11256 } 11257 } 11258 11259 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11260 int opti, boolean dumpAll, String dumpPackage) { 11261 boolean needSep = false; 11262 boolean printedAnything = false; 11263 int numPers = 0; 11264 11265 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11266 11267 if (dumpAll) { 11268 final int NP = mProcessNames.getMap().size(); 11269 for (int ip=0; ip<NP; ip++) { 11270 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11271 final int NA = procs.size(); 11272 for (int ia=0; ia<NA; ia++) { 11273 ProcessRecord r = procs.valueAt(ia); 11274 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11275 continue; 11276 } 11277 if (!needSep) { 11278 pw.println(" All known processes:"); 11279 needSep = true; 11280 printedAnything = true; 11281 } 11282 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11283 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11284 pw.print(" "); pw.println(r); 11285 r.dump(pw, " "); 11286 if (r.persistent) { 11287 numPers++; 11288 } 11289 } 11290 } 11291 } 11292 11293 if (mIsolatedProcesses.size() > 0) { 11294 boolean printed = false; 11295 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11296 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11297 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11298 continue; 11299 } 11300 if (!printed) { 11301 if (needSep) { 11302 pw.println(); 11303 } 11304 pw.println(" Isolated process list (sorted by uid):"); 11305 printedAnything = true; 11306 printed = true; 11307 needSep = true; 11308 } 11309 pw.println(String.format("%sIsolated #%2d: %s", 11310 " ", i, r.toString())); 11311 } 11312 } 11313 11314 if (mLruProcesses.size() > 0) { 11315 if (needSep) { 11316 pw.println(); 11317 } 11318 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11319 pw.print(" total, non-act at "); 11320 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11321 pw.print(", non-svc at "); 11322 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11323 pw.println("):"); 11324 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11325 needSep = true; 11326 printedAnything = true; 11327 } 11328 11329 if (dumpAll || dumpPackage != null) { 11330 synchronized (mPidsSelfLocked) { 11331 boolean printed = false; 11332 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11333 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11334 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11335 continue; 11336 } 11337 if (!printed) { 11338 if (needSep) pw.println(); 11339 needSep = true; 11340 pw.println(" PID mappings:"); 11341 printed = true; 11342 printedAnything = true; 11343 } 11344 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11345 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11346 } 11347 } 11348 } 11349 11350 if (mForegroundProcesses.size() > 0) { 11351 synchronized (mPidsSelfLocked) { 11352 boolean printed = false; 11353 for (int i=0; i<mForegroundProcesses.size(); i++) { 11354 ProcessRecord r = mPidsSelfLocked.get( 11355 mForegroundProcesses.valueAt(i).pid); 11356 if (dumpPackage != null && (r == null 11357 || !r.pkgList.containsKey(dumpPackage))) { 11358 continue; 11359 } 11360 if (!printed) { 11361 if (needSep) pw.println(); 11362 needSep = true; 11363 pw.println(" Foreground Processes:"); 11364 printed = true; 11365 printedAnything = true; 11366 } 11367 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11368 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11369 } 11370 } 11371 } 11372 11373 if (mPersistentStartingProcesses.size() > 0) { 11374 if (needSep) pw.println(); 11375 needSep = true; 11376 printedAnything = true; 11377 pw.println(" Persisent processes that are starting:"); 11378 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11379 "Starting Norm", "Restarting PERS", dumpPackage); 11380 } 11381 11382 if (mRemovedProcesses.size() > 0) { 11383 if (needSep) pw.println(); 11384 needSep = true; 11385 printedAnything = true; 11386 pw.println(" Processes that are being removed:"); 11387 dumpProcessList(pw, this, mRemovedProcesses, " ", 11388 "Removed Norm", "Removed PERS", dumpPackage); 11389 } 11390 11391 if (mProcessesOnHold.size() > 0) { 11392 if (needSep) pw.println(); 11393 needSep = true; 11394 printedAnything = true; 11395 pw.println(" Processes that are on old until the system is ready:"); 11396 dumpProcessList(pw, this, mProcessesOnHold, " ", 11397 "OnHold Norm", "OnHold PERS", dumpPackage); 11398 } 11399 11400 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11401 11402 if (mProcessCrashTimes.getMap().size() > 0) { 11403 boolean printed = false; 11404 long now = SystemClock.uptimeMillis(); 11405 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11406 final int NP = pmap.size(); 11407 for (int ip=0; ip<NP; ip++) { 11408 String pname = pmap.keyAt(ip); 11409 SparseArray<Long> uids = pmap.valueAt(ip); 11410 final int N = uids.size(); 11411 for (int i=0; i<N; i++) { 11412 int puid = uids.keyAt(i); 11413 ProcessRecord r = mProcessNames.get(pname, puid); 11414 if (dumpPackage != null && (r == null 11415 || !r.pkgList.containsKey(dumpPackage))) { 11416 continue; 11417 } 11418 if (!printed) { 11419 if (needSep) pw.println(); 11420 needSep = true; 11421 pw.println(" Time since processes crashed:"); 11422 printed = true; 11423 printedAnything = true; 11424 } 11425 pw.print(" Process "); pw.print(pname); 11426 pw.print(" uid "); pw.print(puid); 11427 pw.print(": last crashed "); 11428 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11429 pw.println(" ago"); 11430 } 11431 } 11432 } 11433 11434 if (mBadProcesses.getMap().size() > 0) { 11435 boolean printed = false; 11436 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11437 final int NP = pmap.size(); 11438 for (int ip=0; ip<NP; ip++) { 11439 String pname = pmap.keyAt(ip); 11440 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11441 final int N = uids.size(); 11442 for (int i=0; i<N; i++) { 11443 int puid = uids.keyAt(i); 11444 ProcessRecord r = mProcessNames.get(pname, puid); 11445 if (dumpPackage != null && (r == null 11446 || !r.pkgList.containsKey(dumpPackage))) { 11447 continue; 11448 } 11449 if (!printed) { 11450 if (needSep) pw.println(); 11451 needSep = true; 11452 pw.println(" Bad processes:"); 11453 printedAnything = true; 11454 } 11455 BadProcessInfo info = uids.valueAt(i); 11456 pw.print(" Bad process "); pw.print(pname); 11457 pw.print(" uid "); pw.print(puid); 11458 pw.print(": crashed at time "); pw.println(info.time); 11459 if (info.shortMsg != null) { 11460 pw.print(" Short msg: "); pw.println(info.shortMsg); 11461 } 11462 if (info.longMsg != null) { 11463 pw.print(" Long msg: "); pw.println(info.longMsg); 11464 } 11465 if (info.stack != null) { 11466 pw.println(" Stack:"); 11467 int lastPos = 0; 11468 for (int pos=0; pos<info.stack.length(); pos++) { 11469 if (info.stack.charAt(pos) == '\n') { 11470 pw.print(" "); 11471 pw.write(info.stack, lastPos, pos-lastPos); 11472 pw.println(); 11473 lastPos = pos+1; 11474 } 11475 } 11476 if (lastPos < info.stack.length()) { 11477 pw.print(" "); 11478 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11479 pw.println(); 11480 } 11481 } 11482 } 11483 } 11484 } 11485 11486 if (dumpPackage == null) { 11487 pw.println(); 11488 needSep = false; 11489 pw.println(" mStartedUsers:"); 11490 for (int i=0; i<mStartedUsers.size(); i++) { 11491 UserStartedState uss = mStartedUsers.valueAt(i); 11492 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11493 pw.print(": "); uss.dump("", pw); 11494 } 11495 pw.print(" mStartedUserArray: ["); 11496 for (int i=0; i<mStartedUserArray.length; i++) { 11497 if (i > 0) pw.print(", "); 11498 pw.print(mStartedUserArray[i]); 11499 } 11500 pw.println("]"); 11501 pw.print(" mUserLru: ["); 11502 for (int i=0; i<mUserLru.size(); i++) { 11503 if (i > 0) pw.print(", "); 11504 pw.print(mUserLru.get(i)); 11505 } 11506 pw.println("]"); 11507 if (dumpAll) { 11508 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11509 } 11510 } 11511 if (mHomeProcess != null && (dumpPackage == null 11512 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11513 if (needSep) { 11514 pw.println(); 11515 needSep = false; 11516 } 11517 pw.println(" mHomeProcess: " + mHomeProcess); 11518 } 11519 if (mPreviousProcess != null && (dumpPackage == null 11520 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11521 if (needSep) { 11522 pw.println(); 11523 needSep = false; 11524 } 11525 pw.println(" mPreviousProcess: " + mPreviousProcess); 11526 } 11527 if (dumpAll) { 11528 StringBuilder sb = new StringBuilder(128); 11529 sb.append(" mPreviousProcessVisibleTime: "); 11530 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11531 pw.println(sb); 11532 } 11533 if (mHeavyWeightProcess != null && (dumpPackage == null 11534 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11535 if (needSep) { 11536 pw.println(); 11537 needSep = false; 11538 } 11539 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11540 } 11541 if (dumpPackage == null) { 11542 pw.println(" mConfiguration: " + mConfiguration); 11543 } 11544 if (dumpAll) { 11545 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11546 if (mCompatModePackages.getPackages().size() > 0) { 11547 boolean printed = false; 11548 for (Map.Entry<String, Integer> entry 11549 : mCompatModePackages.getPackages().entrySet()) { 11550 String pkg = entry.getKey(); 11551 int mode = entry.getValue(); 11552 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11553 continue; 11554 } 11555 if (!printed) { 11556 pw.println(" mScreenCompatPackages:"); 11557 printed = true; 11558 } 11559 pw.print(" "); pw.print(pkg); pw.print(": "); 11560 pw.print(mode); pw.println(); 11561 } 11562 } 11563 } 11564 if (dumpPackage == null) { 11565 if (mSleeping || mWentToSleep || mLockScreenShown) { 11566 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11567 + " mLockScreenShown " + mLockScreenShown); 11568 } 11569 if (mShuttingDown || mRunningVoice) { 11570 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11571 } 11572 } 11573 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11574 || mOrigWaitForDebugger) { 11575 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11576 || dumpPackage.equals(mOrigDebugApp)) { 11577 if (needSep) { 11578 pw.println(); 11579 needSep = false; 11580 } 11581 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11582 + " mDebugTransient=" + mDebugTransient 11583 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11584 } 11585 } 11586 if (mOpenGlTraceApp != null) { 11587 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11588 if (needSep) { 11589 pw.println(); 11590 needSep = false; 11591 } 11592 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11593 } 11594 } 11595 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11596 || mProfileFd != null) { 11597 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11598 if (needSep) { 11599 pw.println(); 11600 needSep = false; 11601 } 11602 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11603 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11604 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11605 + mAutoStopProfiler); 11606 } 11607 } 11608 if (dumpPackage == null) { 11609 if (mAlwaysFinishActivities || mController != null) { 11610 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11611 + " mController=" + mController); 11612 } 11613 if (dumpAll) { 11614 pw.println(" Total persistent processes: " + numPers); 11615 pw.println(" mProcessesReady=" + mProcessesReady 11616 + " mSystemReady=" + mSystemReady); 11617 pw.println(" mBooting=" + mBooting 11618 + " mBooted=" + mBooted 11619 + " mFactoryTest=" + mFactoryTest); 11620 pw.print(" mLastPowerCheckRealtime="); 11621 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11622 pw.println(""); 11623 pw.print(" mLastPowerCheckUptime="); 11624 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11625 pw.println(""); 11626 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11627 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11628 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11629 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11630 + " (" + mLruProcesses.size() + " total)" 11631 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11632 + " mNumServiceProcs=" + mNumServiceProcs 11633 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11634 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11635 + " mLastMemoryLevel" + mLastMemoryLevel 11636 + " mLastNumProcesses" + mLastNumProcesses); 11637 long now = SystemClock.uptimeMillis(); 11638 pw.print(" mLastIdleTime="); 11639 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11640 pw.print(" mLowRamSinceLastIdle="); 11641 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11642 pw.println(); 11643 } 11644 } 11645 11646 if (!printedAnything) { 11647 pw.println(" (nothing)"); 11648 } 11649 } 11650 11651 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11652 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11653 if (mProcessesToGc.size() > 0) { 11654 boolean printed = false; 11655 long now = SystemClock.uptimeMillis(); 11656 for (int i=0; i<mProcessesToGc.size(); i++) { 11657 ProcessRecord proc = mProcessesToGc.get(i); 11658 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11659 continue; 11660 } 11661 if (!printed) { 11662 if (needSep) pw.println(); 11663 needSep = true; 11664 pw.println(" Processes that are waiting to GC:"); 11665 printed = true; 11666 } 11667 pw.print(" Process "); pw.println(proc); 11668 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11669 pw.print(", last gced="); 11670 pw.print(now-proc.lastRequestedGc); 11671 pw.print(" ms ago, last lowMem="); 11672 pw.print(now-proc.lastLowMemory); 11673 pw.println(" ms ago"); 11674 11675 } 11676 } 11677 return needSep; 11678 } 11679 11680 void printOomLevel(PrintWriter pw, String name, int adj) { 11681 pw.print(" "); 11682 if (adj >= 0) { 11683 pw.print(' '); 11684 if (adj < 10) pw.print(' '); 11685 } else { 11686 if (adj > -10) pw.print(' '); 11687 } 11688 pw.print(adj); 11689 pw.print(": "); 11690 pw.print(name); 11691 pw.print(" ("); 11692 pw.print(mProcessList.getMemLevel(adj)/1024); 11693 pw.println(" kB)"); 11694 } 11695 11696 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11697 int opti, boolean dumpAll) { 11698 boolean needSep = false; 11699 11700 if (mLruProcesses.size() > 0) { 11701 if (needSep) pw.println(); 11702 needSep = true; 11703 pw.println(" OOM levels:"); 11704 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11705 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11706 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11707 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11708 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11709 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11710 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11711 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11712 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11713 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11714 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11715 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11716 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11717 11718 if (needSep) pw.println(); 11719 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11720 pw.print(" total, non-act at "); 11721 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11722 pw.print(", non-svc at "); 11723 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11724 pw.println("):"); 11725 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11726 needSep = true; 11727 } 11728 11729 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11730 11731 pw.println(); 11732 pw.println(" mHomeProcess: " + mHomeProcess); 11733 pw.println(" mPreviousProcess: " + mPreviousProcess); 11734 if (mHeavyWeightProcess != null) { 11735 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11736 } 11737 11738 return true; 11739 } 11740 11741 /** 11742 * There are three ways to call this: 11743 * - no provider specified: dump all the providers 11744 * - a flattened component name that matched an existing provider was specified as the 11745 * first arg: dump that one provider 11746 * - the first arg isn't the flattened component name of an existing provider: 11747 * dump all providers whose component contains the first arg as a substring 11748 */ 11749 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11750 int opti, boolean dumpAll) { 11751 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11752 } 11753 11754 static class ItemMatcher { 11755 ArrayList<ComponentName> components; 11756 ArrayList<String> strings; 11757 ArrayList<Integer> objects; 11758 boolean all; 11759 11760 ItemMatcher() { 11761 all = true; 11762 } 11763 11764 void build(String name) { 11765 ComponentName componentName = ComponentName.unflattenFromString(name); 11766 if (componentName != null) { 11767 if (components == null) { 11768 components = new ArrayList<ComponentName>(); 11769 } 11770 components.add(componentName); 11771 all = false; 11772 } else { 11773 int objectId = 0; 11774 // Not a '/' separated full component name; maybe an object ID? 11775 try { 11776 objectId = Integer.parseInt(name, 16); 11777 if (objects == null) { 11778 objects = new ArrayList<Integer>(); 11779 } 11780 objects.add(objectId); 11781 all = false; 11782 } catch (RuntimeException e) { 11783 // Not an integer; just do string match. 11784 if (strings == null) { 11785 strings = new ArrayList<String>(); 11786 } 11787 strings.add(name); 11788 all = false; 11789 } 11790 } 11791 } 11792 11793 int build(String[] args, int opti) { 11794 for (; opti<args.length; opti++) { 11795 String name = args[opti]; 11796 if ("--".equals(name)) { 11797 return opti+1; 11798 } 11799 build(name); 11800 } 11801 return opti; 11802 } 11803 11804 boolean match(Object object, ComponentName comp) { 11805 if (all) { 11806 return true; 11807 } 11808 if (components != null) { 11809 for (int i=0; i<components.size(); i++) { 11810 if (components.get(i).equals(comp)) { 11811 return true; 11812 } 11813 } 11814 } 11815 if (objects != null) { 11816 for (int i=0; i<objects.size(); i++) { 11817 if (System.identityHashCode(object) == objects.get(i)) { 11818 return true; 11819 } 11820 } 11821 } 11822 if (strings != null) { 11823 String flat = comp.flattenToString(); 11824 for (int i=0; i<strings.size(); i++) { 11825 if (flat.contains(strings.get(i))) { 11826 return true; 11827 } 11828 } 11829 } 11830 return false; 11831 } 11832 } 11833 11834 /** 11835 * There are three things that cmd can be: 11836 * - a flattened component name that matches an existing activity 11837 * - the cmd arg isn't the flattened component name of an existing activity: 11838 * dump all activity whose component contains the cmd as a substring 11839 * - A hex number of the ActivityRecord object instance. 11840 */ 11841 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11842 int opti, boolean dumpAll) { 11843 ArrayList<ActivityRecord> activities; 11844 11845 synchronized (this) { 11846 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11847 } 11848 11849 if (activities.size() <= 0) { 11850 return false; 11851 } 11852 11853 String[] newArgs = new String[args.length - opti]; 11854 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11855 11856 TaskRecord lastTask = null; 11857 boolean needSep = false; 11858 for (int i=activities.size()-1; i>=0; i--) { 11859 ActivityRecord r = activities.get(i); 11860 if (needSep) { 11861 pw.println(); 11862 } 11863 needSep = true; 11864 synchronized (this) { 11865 if (lastTask != r.task) { 11866 lastTask = r.task; 11867 pw.print("TASK "); pw.print(lastTask.affinity); 11868 pw.print(" id="); pw.println(lastTask.taskId); 11869 if (dumpAll) { 11870 lastTask.dump(pw, " "); 11871 } 11872 } 11873 } 11874 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11875 } 11876 return true; 11877 } 11878 11879 /** 11880 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11881 * there is a thread associated with the activity. 11882 */ 11883 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11884 final ActivityRecord r, String[] args, boolean dumpAll) { 11885 String innerPrefix = prefix + " "; 11886 synchronized (this) { 11887 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11888 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11889 pw.print(" pid="); 11890 if (r.app != null) pw.println(r.app.pid); 11891 else pw.println("(not running)"); 11892 if (dumpAll) { 11893 r.dump(pw, innerPrefix); 11894 } 11895 } 11896 if (r.app != null && r.app.thread != null) { 11897 // flush anything that is already in the PrintWriter since the thread is going 11898 // to write to the file descriptor directly 11899 pw.flush(); 11900 try { 11901 TransferPipe tp = new TransferPipe(); 11902 try { 11903 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11904 r.appToken, innerPrefix, args); 11905 tp.go(fd); 11906 } finally { 11907 tp.kill(); 11908 } 11909 } catch (IOException e) { 11910 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11911 } catch (RemoteException e) { 11912 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11913 } 11914 } 11915 } 11916 11917 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11918 int opti, boolean dumpAll, String dumpPackage) { 11919 boolean needSep = false; 11920 boolean onlyHistory = false; 11921 boolean printedAnything = false; 11922 11923 if ("history".equals(dumpPackage)) { 11924 if (opti < args.length && "-s".equals(args[opti])) { 11925 dumpAll = false; 11926 } 11927 onlyHistory = true; 11928 dumpPackage = null; 11929 } 11930 11931 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11932 if (!onlyHistory && dumpAll) { 11933 if (mRegisteredReceivers.size() > 0) { 11934 boolean printed = false; 11935 Iterator it = mRegisteredReceivers.values().iterator(); 11936 while (it.hasNext()) { 11937 ReceiverList r = (ReceiverList)it.next(); 11938 if (dumpPackage != null && (r.app == null || 11939 !dumpPackage.equals(r.app.info.packageName))) { 11940 continue; 11941 } 11942 if (!printed) { 11943 pw.println(" Registered Receivers:"); 11944 needSep = true; 11945 printed = true; 11946 printedAnything = true; 11947 } 11948 pw.print(" * "); pw.println(r); 11949 r.dump(pw, " "); 11950 } 11951 } 11952 11953 if (mReceiverResolver.dump(pw, needSep ? 11954 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11955 " ", dumpPackage, false)) { 11956 needSep = true; 11957 printedAnything = true; 11958 } 11959 } 11960 11961 for (BroadcastQueue q : mBroadcastQueues) { 11962 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11963 printedAnything |= needSep; 11964 } 11965 11966 needSep = true; 11967 11968 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11969 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11970 if (needSep) { 11971 pw.println(); 11972 } 11973 needSep = true; 11974 printedAnything = true; 11975 pw.print(" Sticky broadcasts for user "); 11976 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11977 StringBuilder sb = new StringBuilder(128); 11978 for (Map.Entry<String, ArrayList<Intent>> ent 11979 : mStickyBroadcasts.valueAt(user).entrySet()) { 11980 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11981 if (dumpAll) { 11982 pw.println(":"); 11983 ArrayList<Intent> intents = ent.getValue(); 11984 final int N = intents.size(); 11985 for (int i=0; i<N; i++) { 11986 sb.setLength(0); 11987 sb.append(" Intent: "); 11988 intents.get(i).toShortString(sb, false, true, false, false); 11989 pw.println(sb.toString()); 11990 Bundle bundle = intents.get(i).getExtras(); 11991 if (bundle != null) { 11992 pw.print(" "); 11993 pw.println(bundle.toString()); 11994 } 11995 } 11996 } else { 11997 pw.println(""); 11998 } 11999 } 12000 } 12001 } 12002 12003 if (!onlyHistory && dumpAll) { 12004 pw.println(); 12005 for (BroadcastQueue queue : mBroadcastQueues) { 12006 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12007 + queue.mBroadcastsScheduled); 12008 } 12009 pw.println(" mHandler:"); 12010 mHandler.dump(new PrintWriterPrinter(pw), " "); 12011 needSep = true; 12012 printedAnything = true; 12013 } 12014 12015 if (!printedAnything) { 12016 pw.println(" (nothing)"); 12017 } 12018 } 12019 12020 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12021 int opti, boolean dumpAll, String dumpPackage) { 12022 boolean needSep; 12023 boolean printedAnything = false; 12024 12025 ItemMatcher matcher = new ItemMatcher(); 12026 matcher.build(args, opti); 12027 12028 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12029 12030 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12031 printedAnything |= needSep; 12032 12033 if (mLaunchingProviders.size() > 0) { 12034 boolean printed = false; 12035 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12036 ContentProviderRecord r = mLaunchingProviders.get(i); 12037 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12038 continue; 12039 } 12040 if (!printed) { 12041 if (needSep) pw.println(); 12042 needSep = true; 12043 pw.println(" Launching content providers:"); 12044 printed = true; 12045 printedAnything = true; 12046 } 12047 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12048 pw.println(r); 12049 } 12050 } 12051 12052 if (mGrantedUriPermissions.size() > 0) { 12053 boolean printed = false; 12054 int dumpUid = -2; 12055 if (dumpPackage != null) { 12056 try { 12057 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12058 } catch (NameNotFoundException e) { 12059 dumpUid = -1; 12060 } 12061 } 12062 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12063 int uid = mGrantedUriPermissions.keyAt(i); 12064 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12065 continue; 12066 } 12067 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12068 if (!printed) { 12069 if (needSep) pw.println(); 12070 needSep = true; 12071 pw.println(" Granted Uri Permissions:"); 12072 printed = true; 12073 printedAnything = true; 12074 } 12075 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12076 for (UriPermission perm : perms.values()) { 12077 pw.print(" "); pw.println(perm); 12078 if (dumpAll) { 12079 perm.dump(pw, " "); 12080 } 12081 } 12082 } 12083 } 12084 12085 if (!printedAnything) { 12086 pw.println(" (nothing)"); 12087 } 12088 } 12089 12090 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12091 int opti, boolean dumpAll, String dumpPackage) { 12092 boolean printed = false; 12093 12094 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12095 12096 if (mIntentSenderRecords.size() > 0) { 12097 Iterator<WeakReference<PendingIntentRecord>> it 12098 = mIntentSenderRecords.values().iterator(); 12099 while (it.hasNext()) { 12100 WeakReference<PendingIntentRecord> ref = it.next(); 12101 PendingIntentRecord rec = ref != null ? ref.get(): null; 12102 if (dumpPackage != null && (rec == null 12103 || !dumpPackage.equals(rec.key.packageName))) { 12104 continue; 12105 } 12106 printed = true; 12107 if (rec != null) { 12108 pw.print(" * "); pw.println(rec); 12109 if (dumpAll) { 12110 rec.dump(pw, " "); 12111 } 12112 } else { 12113 pw.print(" * "); pw.println(ref); 12114 } 12115 } 12116 } 12117 12118 if (!printed) { 12119 pw.println(" (nothing)"); 12120 } 12121 } 12122 12123 private static final int dumpProcessList(PrintWriter pw, 12124 ActivityManagerService service, List list, 12125 String prefix, String normalLabel, String persistentLabel, 12126 String dumpPackage) { 12127 int numPers = 0; 12128 final int N = list.size()-1; 12129 for (int i=N; i>=0; i--) { 12130 ProcessRecord r = (ProcessRecord)list.get(i); 12131 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12132 continue; 12133 } 12134 pw.println(String.format("%s%s #%2d: %s", 12135 prefix, (r.persistent ? persistentLabel : normalLabel), 12136 i, r.toString())); 12137 if (r.persistent) { 12138 numPers++; 12139 } 12140 } 12141 return numPers; 12142 } 12143 12144 private static final boolean dumpProcessOomList(PrintWriter pw, 12145 ActivityManagerService service, List<ProcessRecord> origList, 12146 String prefix, String normalLabel, String persistentLabel, 12147 boolean inclDetails, String dumpPackage) { 12148 12149 ArrayList<Pair<ProcessRecord, Integer>> list 12150 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12151 for (int i=0; i<origList.size(); i++) { 12152 ProcessRecord r = origList.get(i); 12153 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12154 continue; 12155 } 12156 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12157 } 12158 12159 if (list.size() <= 0) { 12160 return false; 12161 } 12162 12163 Comparator<Pair<ProcessRecord, Integer>> comparator 12164 = new Comparator<Pair<ProcessRecord, Integer>>() { 12165 @Override 12166 public int compare(Pair<ProcessRecord, Integer> object1, 12167 Pair<ProcessRecord, Integer> object2) { 12168 if (object1.first.setAdj != object2.first.setAdj) { 12169 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12170 } 12171 if (object1.second.intValue() != object2.second.intValue()) { 12172 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12173 } 12174 return 0; 12175 } 12176 }; 12177 12178 Collections.sort(list, comparator); 12179 12180 final long curRealtime = SystemClock.elapsedRealtime(); 12181 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12182 final long curUptime = SystemClock.uptimeMillis(); 12183 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12184 12185 for (int i=list.size()-1; i>=0; i--) { 12186 ProcessRecord r = list.get(i).first; 12187 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12188 char schedGroup; 12189 switch (r.setSchedGroup) { 12190 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12191 schedGroup = 'B'; 12192 break; 12193 case Process.THREAD_GROUP_DEFAULT: 12194 schedGroup = 'F'; 12195 break; 12196 default: 12197 schedGroup = '?'; 12198 break; 12199 } 12200 char foreground; 12201 if (r.foregroundActivities) { 12202 foreground = 'A'; 12203 } else if (r.foregroundServices) { 12204 foreground = 'S'; 12205 } else { 12206 foreground = ' '; 12207 } 12208 String procState = ProcessList.makeProcStateString(r.curProcState); 12209 pw.print(prefix); 12210 pw.print(r.persistent ? persistentLabel : normalLabel); 12211 pw.print(" #"); 12212 int num = (origList.size()-1)-list.get(i).second; 12213 if (num < 10) pw.print(' '); 12214 pw.print(num); 12215 pw.print(": "); 12216 pw.print(oomAdj); 12217 pw.print(' '); 12218 pw.print(schedGroup); 12219 pw.print('/'); 12220 pw.print(foreground); 12221 pw.print('/'); 12222 pw.print(procState); 12223 pw.print(" trm:"); 12224 if (r.trimMemoryLevel < 10) pw.print(' '); 12225 pw.print(r.trimMemoryLevel); 12226 pw.print(' '); 12227 pw.print(r.toShortString()); 12228 pw.print(" ("); 12229 pw.print(r.adjType); 12230 pw.println(')'); 12231 if (r.adjSource != null || r.adjTarget != null) { 12232 pw.print(prefix); 12233 pw.print(" "); 12234 if (r.adjTarget instanceof ComponentName) { 12235 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12236 } else if (r.adjTarget != null) { 12237 pw.print(r.adjTarget.toString()); 12238 } else { 12239 pw.print("{null}"); 12240 } 12241 pw.print("<="); 12242 if (r.adjSource instanceof ProcessRecord) { 12243 pw.print("Proc{"); 12244 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12245 pw.println("}"); 12246 } else if (r.adjSource != null) { 12247 pw.println(r.adjSource.toString()); 12248 } else { 12249 pw.println("{null}"); 12250 } 12251 } 12252 if (inclDetails) { 12253 pw.print(prefix); 12254 pw.print(" "); 12255 pw.print("oom: max="); pw.print(r.maxAdj); 12256 pw.print(" curRaw="); pw.print(r.curRawAdj); 12257 pw.print(" setRaw="); pw.print(r.setRawAdj); 12258 pw.print(" cur="); pw.print(r.curAdj); 12259 pw.print(" set="); pw.println(r.setAdj); 12260 pw.print(prefix); 12261 pw.print(" "); 12262 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12263 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12264 pw.print(" lastPss="); pw.print(r.lastPss); 12265 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12266 pw.print(prefix); 12267 pw.print(" "); 12268 pw.print("keeping="); pw.print(r.keeping); 12269 pw.print(" cached="); pw.print(r.cached); 12270 pw.print(" empty="); pw.print(r.empty); 12271 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12272 12273 if (!r.keeping) { 12274 if (r.lastWakeTime != 0) { 12275 long wtime; 12276 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12277 synchronized (stats) { 12278 wtime = stats.getProcessWakeTime(r.info.uid, 12279 r.pid, curRealtime); 12280 } 12281 long timeUsed = wtime - r.lastWakeTime; 12282 pw.print(prefix); 12283 pw.print(" "); 12284 pw.print("keep awake over "); 12285 TimeUtils.formatDuration(realtimeSince, pw); 12286 pw.print(" used "); 12287 TimeUtils.formatDuration(timeUsed, pw); 12288 pw.print(" ("); 12289 pw.print((timeUsed*100)/realtimeSince); 12290 pw.println("%)"); 12291 } 12292 if (r.lastCpuTime != 0) { 12293 long timeUsed = r.curCpuTime - r.lastCpuTime; 12294 pw.print(prefix); 12295 pw.print(" "); 12296 pw.print("run cpu over "); 12297 TimeUtils.formatDuration(uptimeSince, pw); 12298 pw.print(" used "); 12299 TimeUtils.formatDuration(timeUsed, pw); 12300 pw.print(" ("); 12301 pw.print((timeUsed*100)/uptimeSince); 12302 pw.println("%)"); 12303 } 12304 } 12305 } 12306 } 12307 return true; 12308 } 12309 12310 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12311 ArrayList<ProcessRecord> procs; 12312 synchronized (this) { 12313 if (args != null && args.length > start 12314 && args[start].charAt(0) != '-') { 12315 procs = new ArrayList<ProcessRecord>(); 12316 int pid = -1; 12317 try { 12318 pid = Integer.parseInt(args[start]); 12319 } catch (NumberFormatException e) { 12320 } 12321 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12322 ProcessRecord proc = mLruProcesses.get(i); 12323 if (proc.pid == pid) { 12324 procs.add(proc); 12325 } else if (proc.processName.equals(args[start])) { 12326 procs.add(proc); 12327 } 12328 } 12329 if (procs.size() <= 0) { 12330 return null; 12331 } 12332 } else { 12333 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12334 } 12335 } 12336 return procs; 12337 } 12338 12339 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12340 PrintWriter pw, String[] args) { 12341 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12342 if (procs == null) { 12343 pw.println("No process found for: " + args[0]); 12344 return; 12345 } 12346 12347 long uptime = SystemClock.uptimeMillis(); 12348 long realtime = SystemClock.elapsedRealtime(); 12349 pw.println("Applications Graphics Acceleration Info:"); 12350 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12351 12352 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12353 ProcessRecord r = procs.get(i); 12354 if (r.thread != null) { 12355 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12356 pw.flush(); 12357 try { 12358 TransferPipe tp = new TransferPipe(); 12359 try { 12360 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12361 tp.go(fd); 12362 } finally { 12363 tp.kill(); 12364 } 12365 } catch (IOException e) { 12366 pw.println("Failure while dumping the app: " + r); 12367 pw.flush(); 12368 } catch (RemoteException e) { 12369 pw.println("Got a RemoteException while dumping the app " + r); 12370 pw.flush(); 12371 } 12372 } 12373 } 12374 } 12375 12376 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12377 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12378 if (procs == null) { 12379 pw.println("No process found for: " + args[0]); 12380 return; 12381 } 12382 12383 pw.println("Applications Database Info:"); 12384 12385 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12386 ProcessRecord r = procs.get(i); 12387 if (r.thread != null) { 12388 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12389 pw.flush(); 12390 try { 12391 TransferPipe tp = new TransferPipe(); 12392 try { 12393 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12394 tp.go(fd); 12395 } finally { 12396 tp.kill(); 12397 } 12398 } catch (IOException e) { 12399 pw.println("Failure while dumping the app: " + r); 12400 pw.flush(); 12401 } catch (RemoteException e) { 12402 pw.println("Got a RemoteException while dumping the app " + r); 12403 pw.flush(); 12404 } 12405 } 12406 } 12407 } 12408 12409 final static class MemItem { 12410 final boolean isProc; 12411 final String label; 12412 final String shortLabel; 12413 final long pss; 12414 final int id; 12415 final boolean hasActivities; 12416 ArrayList<MemItem> subitems; 12417 12418 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12419 boolean _hasActivities) { 12420 isProc = true; 12421 label = _label; 12422 shortLabel = _shortLabel; 12423 pss = _pss; 12424 id = _id; 12425 hasActivities = _hasActivities; 12426 } 12427 12428 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12429 isProc = false; 12430 label = _label; 12431 shortLabel = _shortLabel; 12432 pss = _pss; 12433 id = _id; 12434 hasActivities = false; 12435 } 12436 } 12437 12438 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12439 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12440 if (sort && !isCompact) { 12441 Collections.sort(items, new Comparator<MemItem>() { 12442 @Override 12443 public int compare(MemItem lhs, MemItem rhs) { 12444 if (lhs.pss < rhs.pss) { 12445 return 1; 12446 } else if (lhs.pss > rhs.pss) { 12447 return -1; 12448 } 12449 return 0; 12450 } 12451 }); 12452 } 12453 12454 for (int i=0; i<items.size(); i++) { 12455 MemItem mi = items.get(i); 12456 if (!isCompact) { 12457 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12458 } else if (mi.isProc) { 12459 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12460 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12461 pw.println(mi.hasActivities ? ",a" : ",e"); 12462 } else { 12463 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12464 pw.println(mi.pss); 12465 } 12466 if (mi.subitems != null) { 12467 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12468 true, isCompact); 12469 } 12470 } 12471 } 12472 12473 // These are in KB. 12474 static final long[] DUMP_MEM_BUCKETS = new long[] { 12475 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12476 120*1024, 160*1024, 200*1024, 12477 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12478 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12479 }; 12480 12481 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12482 boolean stackLike) { 12483 int start = label.lastIndexOf('.'); 12484 if (start >= 0) start++; 12485 else start = 0; 12486 int end = label.length(); 12487 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12488 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12489 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12490 out.append(bucket); 12491 out.append(stackLike ? "MB." : "MB "); 12492 out.append(label, start, end); 12493 return; 12494 } 12495 } 12496 out.append(memKB/1024); 12497 out.append(stackLike ? "MB." : "MB "); 12498 out.append(label, start, end); 12499 } 12500 12501 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12502 ProcessList.NATIVE_ADJ, 12503 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12504 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12505 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12506 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12507 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12508 }; 12509 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12510 "Native", 12511 "System", "Persistent", "Foreground", 12512 "Visible", "Perceptible", 12513 "Heavy Weight", "Backup", 12514 "A Services", "Home", 12515 "Previous", "B Services", "Cached" 12516 }; 12517 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12518 "native", 12519 "sys", "pers", "fore", 12520 "vis", "percept", 12521 "heavy", "backup", 12522 "servicea", "home", 12523 "prev", "serviceb", "cached" 12524 }; 12525 12526 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12527 long realtime, boolean isCheckinRequest, boolean isCompact) { 12528 if (isCheckinRequest || isCompact) { 12529 // short checkin version 12530 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12531 } else { 12532 pw.println("Applications Memory Usage (kB):"); 12533 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12534 } 12535 } 12536 12537 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12538 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12539 boolean dumpDetails = false; 12540 boolean dumpFullDetails = false; 12541 boolean dumpDalvik = false; 12542 boolean oomOnly = false; 12543 boolean isCompact = false; 12544 boolean localOnly = false; 12545 12546 int opti = 0; 12547 while (opti < args.length) { 12548 String opt = args[opti]; 12549 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12550 break; 12551 } 12552 opti++; 12553 if ("-a".equals(opt)) { 12554 dumpDetails = true; 12555 dumpFullDetails = true; 12556 dumpDalvik = true; 12557 } else if ("-d".equals(opt)) { 12558 dumpDalvik = true; 12559 } else if ("-c".equals(opt)) { 12560 isCompact = true; 12561 } else if ("--oom".equals(opt)) { 12562 oomOnly = true; 12563 } else if ("--local".equals(opt)) { 12564 localOnly = true; 12565 } else if ("-h".equals(opt)) { 12566 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12567 pw.println(" -a: include all available information for each process."); 12568 pw.println(" -d: include dalvik details when dumping process details."); 12569 pw.println(" -c: dump in a compact machine-parseable representation."); 12570 pw.println(" --oom: only show processes organized by oom adj."); 12571 pw.println(" --local: only collect details locally, don't call process."); 12572 pw.println("If [process] is specified it can be the name or "); 12573 pw.println("pid of a specific process to dump."); 12574 return; 12575 } else { 12576 pw.println("Unknown argument: " + opt + "; use -h for help"); 12577 } 12578 } 12579 12580 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12581 long uptime = SystemClock.uptimeMillis(); 12582 long realtime = SystemClock.elapsedRealtime(); 12583 final long[] tmpLong = new long[1]; 12584 12585 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12586 if (procs == null) { 12587 // No Java processes. Maybe they want to print a native process. 12588 if (args != null && args.length > opti 12589 && args[opti].charAt(0) != '-') { 12590 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12591 = new ArrayList<ProcessCpuTracker.Stats>(); 12592 updateCpuStatsNow(); 12593 int findPid = -1; 12594 try { 12595 findPid = Integer.parseInt(args[opti]); 12596 } catch (NumberFormatException e) { 12597 } 12598 synchronized (mProcessCpuThread) { 12599 final int N = mProcessCpuTracker.countStats(); 12600 for (int i=0; i<N; i++) { 12601 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12602 if (st.pid == findPid || (st.baseName != null 12603 && st.baseName.equals(args[opti]))) { 12604 nativeProcs.add(st); 12605 } 12606 } 12607 } 12608 if (nativeProcs.size() > 0) { 12609 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12610 isCompact); 12611 Debug.MemoryInfo mi = null; 12612 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12613 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12614 final int pid = r.pid; 12615 if (!isCheckinRequest && dumpDetails) { 12616 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12617 } 12618 if (mi == null) { 12619 mi = new Debug.MemoryInfo(); 12620 } 12621 if (dumpDetails || (!brief && !oomOnly)) { 12622 Debug.getMemoryInfo(pid, mi); 12623 } else { 12624 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12625 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12626 } 12627 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12628 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12629 if (isCheckinRequest) { 12630 pw.println(); 12631 } 12632 } 12633 return; 12634 } 12635 } 12636 pw.println("No process found for: " + args[opti]); 12637 return; 12638 } 12639 12640 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12641 dumpDetails = true; 12642 } 12643 12644 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12645 12646 String[] innerArgs = new String[args.length-opti]; 12647 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12648 12649 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12650 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12651 long nativePss=0, dalvikPss=0, otherPss=0; 12652 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12653 12654 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12655 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12656 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12657 12658 long totalPss = 0; 12659 long cachedPss = 0; 12660 12661 Debug.MemoryInfo mi = null; 12662 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12663 final ProcessRecord r = procs.get(i); 12664 final IApplicationThread thread; 12665 final int pid; 12666 final int oomAdj; 12667 final boolean hasActivities; 12668 synchronized (this) { 12669 thread = r.thread; 12670 pid = r.pid; 12671 oomAdj = r.getSetAdjWithServices(); 12672 hasActivities = r.activities.size() > 0; 12673 } 12674 if (thread != null) { 12675 if (!isCheckinRequest && dumpDetails) { 12676 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12677 } 12678 if (mi == null) { 12679 mi = new Debug.MemoryInfo(); 12680 } 12681 if (dumpDetails || (!brief && !oomOnly)) { 12682 Debug.getMemoryInfo(pid, mi); 12683 } else { 12684 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12685 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12686 } 12687 if (dumpDetails) { 12688 if (localOnly) { 12689 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12690 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12691 if (isCheckinRequest) { 12692 pw.println(); 12693 } 12694 } else { 12695 try { 12696 pw.flush(); 12697 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12698 dumpDalvik, innerArgs); 12699 } catch (RemoteException e) { 12700 if (!isCheckinRequest) { 12701 pw.println("Got RemoteException!"); 12702 pw.flush(); 12703 } 12704 } 12705 } 12706 } 12707 12708 final long myTotalPss = mi.getTotalPss(); 12709 final long myTotalUss = mi.getTotalUss(); 12710 12711 synchronized (this) { 12712 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12713 // Record this for posterity if the process has been stable. 12714 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12715 } 12716 } 12717 12718 if (!isCheckinRequest && mi != null) { 12719 totalPss += myTotalPss; 12720 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12721 (hasActivities ? " / activities)" : ")"), 12722 r.processName, myTotalPss, pid, hasActivities); 12723 procMems.add(pssItem); 12724 procMemsMap.put(pid, pssItem); 12725 12726 nativePss += mi.nativePss; 12727 dalvikPss += mi.dalvikPss; 12728 otherPss += mi.otherPss; 12729 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12730 long mem = mi.getOtherPss(j); 12731 miscPss[j] += mem; 12732 otherPss -= mem; 12733 } 12734 12735 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12736 cachedPss += myTotalPss; 12737 } 12738 12739 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12740 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12741 || oomIndex == (oomPss.length-1)) { 12742 oomPss[oomIndex] += myTotalPss; 12743 if (oomProcs[oomIndex] == null) { 12744 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12745 } 12746 oomProcs[oomIndex].add(pssItem); 12747 break; 12748 } 12749 } 12750 } 12751 } 12752 } 12753 12754 long nativeProcTotalPss = 0; 12755 12756 if (!isCheckinRequest && procs.size() > 1) { 12757 // If we are showing aggregations, also look for native processes to 12758 // include so that our aggregations are more accurate. 12759 updateCpuStatsNow(); 12760 synchronized (mProcessCpuThread) { 12761 final int N = mProcessCpuTracker.countStats(); 12762 for (int i=0; i<N; i++) { 12763 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12764 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12765 if (mi == null) { 12766 mi = new Debug.MemoryInfo(); 12767 } 12768 if (!brief && !oomOnly) { 12769 Debug.getMemoryInfo(st.pid, mi); 12770 } else { 12771 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12772 mi.nativePrivateDirty = (int)tmpLong[0]; 12773 } 12774 12775 final long myTotalPss = mi.getTotalPss(); 12776 totalPss += myTotalPss; 12777 nativeProcTotalPss += myTotalPss; 12778 12779 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12780 st.name, myTotalPss, st.pid, false); 12781 procMems.add(pssItem); 12782 12783 nativePss += mi.nativePss; 12784 dalvikPss += mi.dalvikPss; 12785 otherPss += mi.otherPss; 12786 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12787 long mem = mi.getOtherPss(j); 12788 miscPss[j] += mem; 12789 otherPss -= mem; 12790 } 12791 oomPss[0] += myTotalPss; 12792 if (oomProcs[0] == null) { 12793 oomProcs[0] = new ArrayList<MemItem>(); 12794 } 12795 oomProcs[0].add(pssItem); 12796 } 12797 } 12798 } 12799 12800 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12801 12802 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12803 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12804 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12805 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12806 String label = Debug.MemoryInfo.getOtherLabel(j); 12807 catMems.add(new MemItem(label, label, miscPss[j], j)); 12808 } 12809 12810 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12811 for (int j=0; j<oomPss.length; j++) { 12812 if (oomPss[j] != 0) { 12813 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12814 : DUMP_MEM_OOM_LABEL[j]; 12815 MemItem item = new MemItem(label, label, oomPss[j], 12816 DUMP_MEM_OOM_ADJ[j]); 12817 item.subitems = oomProcs[j]; 12818 oomMems.add(item); 12819 } 12820 } 12821 12822 if (!brief && !oomOnly && !isCompact) { 12823 pw.println(); 12824 pw.println("Total PSS by process:"); 12825 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12826 pw.println(); 12827 } 12828 if (!isCompact) { 12829 pw.println("Total PSS by OOM adjustment:"); 12830 } 12831 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12832 if (!brief && !oomOnly) { 12833 PrintWriter out = categoryPw != null ? categoryPw : pw; 12834 if (!isCompact) { 12835 out.println(); 12836 out.println("Total PSS by category:"); 12837 } 12838 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12839 } 12840 if (!isCompact) { 12841 pw.println(); 12842 } 12843 MemInfoReader memInfo = new MemInfoReader(); 12844 memInfo.readMemInfo(); 12845 if (nativeProcTotalPss > 0) { 12846 synchronized (this) { 12847 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12848 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12849 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12850 nativeProcTotalPss); 12851 } 12852 } 12853 if (!brief) { 12854 if (!isCompact) { 12855 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12856 pw.print(" kB (status "); 12857 switch (mLastMemoryLevel) { 12858 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12859 pw.println("normal)"); 12860 break; 12861 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12862 pw.println("moderate)"); 12863 break; 12864 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12865 pw.println("low)"); 12866 break; 12867 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12868 pw.println("critical)"); 12869 break; 12870 default: 12871 pw.print(mLastMemoryLevel); 12872 pw.println(")"); 12873 break; 12874 } 12875 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12876 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12877 pw.print(cachedPss); pw.print(" cached pss + "); 12878 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12879 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12880 } else { 12881 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12882 pw.print(cachedPss + memInfo.getCachedSizeKb() 12883 + memInfo.getFreeSizeKb()); pw.print(","); 12884 pw.println(totalPss - cachedPss); 12885 } 12886 } 12887 if (!isCompact) { 12888 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12889 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12890 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12891 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12892 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12893 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12894 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12895 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12896 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12897 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12898 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12899 } 12900 if (!brief) { 12901 if (memInfo.getZramTotalSizeKb() != 0) { 12902 if (!isCompact) { 12903 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12904 pw.print(" kB physical used for "); 12905 pw.print(memInfo.getSwapTotalSizeKb() 12906 - memInfo.getSwapFreeSizeKb()); 12907 pw.print(" kB in swap ("); 12908 pw.print(memInfo.getSwapTotalSizeKb()); 12909 pw.println(" kB total swap)"); 12910 } else { 12911 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12912 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12913 pw.println(memInfo.getSwapFreeSizeKb()); 12914 } 12915 } 12916 final int[] SINGLE_LONG_FORMAT = new int[] { 12917 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12918 }; 12919 long[] longOut = new long[1]; 12920 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12921 SINGLE_LONG_FORMAT, null, longOut, null); 12922 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12923 longOut[0] = 0; 12924 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12925 SINGLE_LONG_FORMAT, null, longOut, null); 12926 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12927 longOut[0] = 0; 12928 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12929 SINGLE_LONG_FORMAT, null, longOut, null); 12930 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12931 longOut[0] = 0; 12932 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12933 SINGLE_LONG_FORMAT, null, longOut, null); 12934 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12935 if (!isCompact) { 12936 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12937 pw.print(" KSM: "); pw.print(sharing); 12938 pw.print(" kB saved from shared "); 12939 pw.print(shared); pw.println(" kB"); 12940 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12941 pw.print(voltile); pw.println(" kB volatile"); 12942 } 12943 pw.print(" Tuning: "); 12944 pw.print(ActivityManager.staticGetMemoryClass()); 12945 pw.print(" (large "); 12946 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12947 pw.print("), oom "); 12948 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12949 pw.print(" kB"); 12950 pw.print(", restore limit "); 12951 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12952 pw.print(" kB"); 12953 if (ActivityManager.isLowRamDeviceStatic()) { 12954 pw.print(" (low-ram)"); 12955 } 12956 if (ActivityManager.isHighEndGfx()) { 12957 pw.print(" (high-end-gfx)"); 12958 } 12959 pw.println(); 12960 } else { 12961 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12962 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12963 pw.println(voltile); 12964 pw.print("tuning,"); 12965 pw.print(ActivityManager.staticGetMemoryClass()); 12966 pw.print(','); 12967 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12968 pw.print(','); 12969 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12970 if (ActivityManager.isLowRamDeviceStatic()) { 12971 pw.print(",low-ram"); 12972 } 12973 if (ActivityManager.isHighEndGfx()) { 12974 pw.print(",high-end-gfx"); 12975 } 12976 pw.println(); 12977 } 12978 } 12979 } 12980 } 12981 12982 /** 12983 * Searches array of arguments for the specified string 12984 * @param args array of argument strings 12985 * @param value value to search for 12986 * @return true if the value is contained in the array 12987 */ 12988 private static boolean scanArgs(String[] args, String value) { 12989 if (args != null) { 12990 for (String arg : args) { 12991 if (value.equals(arg)) { 12992 return true; 12993 } 12994 } 12995 } 12996 return false; 12997 } 12998 12999 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13000 ContentProviderRecord cpr, boolean always) { 13001 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13002 13003 if (!inLaunching || always) { 13004 synchronized (cpr) { 13005 cpr.launchingApp = null; 13006 cpr.notifyAll(); 13007 } 13008 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13009 String names[] = cpr.info.authority.split(";"); 13010 for (int j = 0; j < names.length; j++) { 13011 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13012 } 13013 } 13014 13015 for (int i=0; i<cpr.connections.size(); i++) { 13016 ContentProviderConnection conn = cpr.connections.get(i); 13017 if (conn.waiting) { 13018 // If this connection is waiting for the provider, then we don't 13019 // need to mess with its process unless we are always removing 13020 // or for some reason the provider is not currently launching. 13021 if (inLaunching && !always) { 13022 continue; 13023 } 13024 } 13025 ProcessRecord capp = conn.client; 13026 conn.dead = true; 13027 if (conn.stableCount > 0) { 13028 if (!capp.persistent && capp.thread != null 13029 && capp.pid != 0 13030 && capp.pid != MY_PID) { 13031 killUnneededProcessLocked(capp, "depends on provider " 13032 + cpr.name.flattenToShortString() 13033 + " in dying proc " + (proc != null ? proc.processName : "??")); 13034 } 13035 } else if (capp.thread != null && conn.provider.provider != null) { 13036 try { 13037 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13038 } catch (RemoteException e) { 13039 } 13040 // In the protocol here, we don't expect the client to correctly 13041 // clean up this connection, we'll just remove it. 13042 cpr.connections.remove(i); 13043 conn.client.conProviders.remove(conn); 13044 } 13045 } 13046 13047 if (inLaunching && always) { 13048 mLaunchingProviders.remove(cpr); 13049 } 13050 return inLaunching; 13051 } 13052 13053 /** 13054 * Main code for cleaning up a process when it has gone away. This is 13055 * called both as a result of the process dying, or directly when stopping 13056 * a process when running in single process mode. 13057 */ 13058 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13059 boolean restarting, boolean allowRestart, int index) { 13060 if (index >= 0) { 13061 removeLruProcessLocked(app); 13062 ProcessList.remove(app.pid); 13063 } 13064 13065 mProcessesToGc.remove(app); 13066 mPendingPssProcesses.remove(app); 13067 13068 // Dismiss any open dialogs. 13069 if (app.crashDialog != null && !app.forceCrashReport) { 13070 app.crashDialog.dismiss(); 13071 app.crashDialog = null; 13072 } 13073 if (app.anrDialog != null) { 13074 app.anrDialog.dismiss(); 13075 app.anrDialog = null; 13076 } 13077 if (app.waitDialog != null) { 13078 app.waitDialog.dismiss(); 13079 app.waitDialog = null; 13080 } 13081 13082 app.crashing = false; 13083 app.notResponding = false; 13084 13085 app.resetPackageList(mProcessStats); 13086 app.unlinkDeathRecipient(); 13087 app.makeInactive(mProcessStats); 13088 app.waitingToKill = null; 13089 app.forcingToForeground = null; 13090 updateProcessForegroundLocked(app, false, false); 13091 app.foregroundActivities = false; 13092 app.hasShownUi = false; 13093 app.treatLikeActivity = false; 13094 app.hasAboveClient = false; 13095 app.hasClientActivities = false; 13096 13097 mServices.killServicesLocked(app, allowRestart); 13098 13099 boolean restart = false; 13100 13101 // Remove published content providers. 13102 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13103 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13104 final boolean always = app.bad || !allowRestart; 13105 if (removeDyingProviderLocked(app, cpr, always) || always) { 13106 // We left the provider in the launching list, need to 13107 // restart it. 13108 restart = true; 13109 } 13110 13111 cpr.provider = null; 13112 cpr.proc = null; 13113 } 13114 app.pubProviders.clear(); 13115 13116 // Take care of any launching providers waiting for this process. 13117 if (checkAppInLaunchingProvidersLocked(app, false)) { 13118 restart = true; 13119 } 13120 13121 // Unregister from connected content providers. 13122 if (!app.conProviders.isEmpty()) { 13123 for (int i=0; i<app.conProviders.size(); i++) { 13124 ContentProviderConnection conn = app.conProviders.get(i); 13125 conn.provider.connections.remove(conn); 13126 } 13127 app.conProviders.clear(); 13128 } 13129 13130 // At this point there may be remaining entries in mLaunchingProviders 13131 // where we were the only one waiting, so they are no longer of use. 13132 // Look for these and clean up if found. 13133 // XXX Commented out for now. Trying to figure out a way to reproduce 13134 // the actual situation to identify what is actually going on. 13135 if (false) { 13136 for (int i=0; i<mLaunchingProviders.size(); i++) { 13137 ContentProviderRecord cpr = (ContentProviderRecord) 13138 mLaunchingProviders.get(i); 13139 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13140 synchronized (cpr) { 13141 cpr.launchingApp = null; 13142 cpr.notifyAll(); 13143 } 13144 } 13145 } 13146 } 13147 13148 skipCurrentReceiverLocked(app); 13149 13150 // Unregister any receivers. 13151 for (int i=app.receivers.size()-1; i>=0; i--) { 13152 removeReceiverLocked(app.receivers.valueAt(i)); 13153 } 13154 app.receivers.clear(); 13155 13156 // If the app is undergoing backup, tell the backup manager about it 13157 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13158 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13159 + mBackupTarget.appInfo + " died during backup"); 13160 try { 13161 IBackupManager bm = IBackupManager.Stub.asInterface( 13162 ServiceManager.getService(Context.BACKUP_SERVICE)); 13163 bm.agentDisconnected(app.info.packageName); 13164 } catch (RemoteException e) { 13165 // can't happen; backup manager is local 13166 } 13167 } 13168 13169 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13170 ProcessChangeItem item = mPendingProcessChanges.get(i); 13171 if (item.pid == app.pid) { 13172 mPendingProcessChanges.remove(i); 13173 mAvailProcessChanges.add(item); 13174 } 13175 } 13176 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13177 13178 // If the caller is restarting this app, then leave it in its 13179 // current lists and let the caller take care of it. 13180 if (restarting) { 13181 return; 13182 } 13183 13184 if (!app.persistent || app.isolated) { 13185 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13186 "Removing non-persistent process during cleanup: " + app); 13187 mProcessNames.remove(app.processName, app.uid); 13188 mIsolatedProcesses.remove(app.uid); 13189 if (mHeavyWeightProcess == app) { 13190 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13191 mHeavyWeightProcess.userId, 0)); 13192 mHeavyWeightProcess = null; 13193 } 13194 } else if (!app.removed) { 13195 // This app is persistent, so we need to keep its record around. 13196 // If it is not already on the pending app list, add it there 13197 // and start a new process for it. 13198 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13199 mPersistentStartingProcesses.add(app); 13200 restart = true; 13201 } 13202 } 13203 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13204 "Clean-up removing on hold: " + app); 13205 mProcessesOnHold.remove(app); 13206 13207 if (app == mHomeProcess) { 13208 mHomeProcess = null; 13209 } 13210 if (app == mPreviousProcess) { 13211 mPreviousProcess = null; 13212 } 13213 13214 if (restart && !app.isolated) { 13215 // We have components that still need to be running in the 13216 // process, so re-launch it. 13217 mProcessNames.put(app.processName, app.uid, app); 13218 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13219 } else if (app.pid > 0 && app.pid != MY_PID) { 13220 // Goodbye! 13221 boolean removed; 13222 synchronized (mPidsSelfLocked) { 13223 mPidsSelfLocked.remove(app.pid); 13224 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13225 } 13226 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13227 app.processName, app.info.uid); 13228 if (app.isolated) { 13229 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13230 } 13231 app.setPid(0); 13232 } 13233 } 13234 13235 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13236 // Look through the content providers we are waiting to have launched, 13237 // and if any run in this process then either schedule a restart of 13238 // the process or kill the client waiting for it if this process has 13239 // gone bad. 13240 int NL = mLaunchingProviders.size(); 13241 boolean restart = false; 13242 for (int i=0; i<NL; i++) { 13243 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13244 if (cpr.launchingApp == app) { 13245 if (!alwaysBad && !app.bad) { 13246 restart = true; 13247 } else { 13248 removeDyingProviderLocked(app, cpr, true); 13249 // cpr should have been removed from mLaunchingProviders 13250 NL = mLaunchingProviders.size(); 13251 i--; 13252 } 13253 } 13254 } 13255 return restart; 13256 } 13257 13258 // ========================================================= 13259 // SERVICES 13260 // ========================================================= 13261 13262 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13263 int flags) { 13264 enforceNotIsolatedCaller("getServices"); 13265 synchronized (this) { 13266 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13267 } 13268 } 13269 13270 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13271 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13272 synchronized (this) { 13273 return mServices.getRunningServiceControlPanelLocked(name); 13274 } 13275 } 13276 13277 public ComponentName startService(IApplicationThread caller, Intent service, 13278 String resolvedType, int userId) { 13279 enforceNotIsolatedCaller("startService"); 13280 // Refuse possible leaked file descriptors 13281 if (service != null && service.hasFileDescriptors() == true) { 13282 throw new IllegalArgumentException("File descriptors passed in Intent"); 13283 } 13284 13285 if (DEBUG_SERVICE) 13286 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13287 synchronized(this) { 13288 final int callingPid = Binder.getCallingPid(); 13289 final int callingUid = Binder.getCallingUid(); 13290 final long origId = Binder.clearCallingIdentity(); 13291 ComponentName res = mServices.startServiceLocked(caller, service, 13292 resolvedType, callingPid, callingUid, userId); 13293 Binder.restoreCallingIdentity(origId); 13294 return res; 13295 } 13296 } 13297 13298 ComponentName startServiceInPackage(int uid, 13299 Intent service, String resolvedType, int userId) { 13300 synchronized(this) { 13301 if (DEBUG_SERVICE) 13302 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13303 final long origId = Binder.clearCallingIdentity(); 13304 ComponentName res = mServices.startServiceLocked(null, service, 13305 resolvedType, -1, uid, userId); 13306 Binder.restoreCallingIdentity(origId); 13307 return res; 13308 } 13309 } 13310 13311 public int stopService(IApplicationThread caller, Intent service, 13312 String resolvedType, int userId) { 13313 enforceNotIsolatedCaller("stopService"); 13314 // Refuse possible leaked file descriptors 13315 if (service != null && service.hasFileDescriptors() == true) { 13316 throw new IllegalArgumentException("File descriptors passed in Intent"); 13317 } 13318 13319 synchronized(this) { 13320 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13321 } 13322 } 13323 13324 public IBinder peekService(Intent service, String resolvedType) { 13325 enforceNotIsolatedCaller("peekService"); 13326 // Refuse possible leaked file descriptors 13327 if (service != null && service.hasFileDescriptors() == true) { 13328 throw new IllegalArgumentException("File descriptors passed in Intent"); 13329 } 13330 synchronized(this) { 13331 return mServices.peekServiceLocked(service, resolvedType); 13332 } 13333 } 13334 13335 public boolean stopServiceToken(ComponentName className, IBinder token, 13336 int startId) { 13337 synchronized(this) { 13338 return mServices.stopServiceTokenLocked(className, token, startId); 13339 } 13340 } 13341 13342 public void setServiceForeground(ComponentName className, IBinder token, 13343 int id, Notification notification, boolean removeNotification) { 13344 synchronized(this) { 13345 mServices.setServiceForegroundLocked(className, token, id, notification, 13346 removeNotification); 13347 } 13348 } 13349 13350 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13351 boolean requireFull, String name, String callerPackage) { 13352 final int callingUserId = UserHandle.getUserId(callingUid); 13353 if (callingUserId != userId) { 13354 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13355 if ((requireFull || checkComponentPermission( 13356 android.Manifest.permission.INTERACT_ACROSS_USERS, 13357 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13358 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13359 callingPid, callingUid, -1, true) 13360 != PackageManager.PERMISSION_GRANTED) { 13361 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13362 // In this case, they would like to just execute as their 13363 // owner user instead of failing. 13364 userId = callingUserId; 13365 } else { 13366 StringBuilder builder = new StringBuilder(128); 13367 builder.append("Permission Denial: "); 13368 builder.append(name); 13369 if (callerPackage != null) { 13370 builder.append(" from "); 13371 builder.append(callerPackage); 13372 } 13373 builder.append(" asks to run as user "); 13374 builder.append(userId); 13375 builder.append(" but is calling from user "); 13376 builder.append(UserHandle.getUserId(callingUid)); 13377 builder.append("; this requires "); 13378 builder.append(INTERACT_ACROSS_USERS_FULL); 13379 if (!requireFull) { 13380 builder.append(" or "); 13381 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13382 } 13383 String msg = builder.toString(); 13384 Slog.w(TAG, msg); 13385 throw new SecurityException(msg); 13386 } 13387 } 13388 } 13389 if (userId == UserHandle.USER_CURRENT 13390 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13391 // Note that we may be accessing this outside of a lock... 13392 // shouldn't be a big deal, if this is being called outside 13393 // of a locked context there is intrinsically a race with 13394 // the value the caller will receive and someone else changing it. 13395 userId = mCurrentUserId; 13396 } 13397 if (!allowAll && userId < 0) { 13398 throw new IllegalArgumentException( 13399 "Call does not support special user #" + userId); 13400 } 13401 } 13402 return userId; 13403 } 13404 13405 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13406 String className, int flags) { 13407 boolean result = false; 13408 // For apps that don't have pre-defined UIDs, check for permission 13409 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13410 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13411 if (ActivityManager.checkUidPermission( 13412 android.Manifest.permission.INTERACT_ACROSS_USERS, 13413 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13414 ComponentName comp = new ComponentName(aInfo.packageName, className); 13415 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13416 + " requests FLAG_SINGLE_USER, but app does not hold " 13417 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13418 Slog.w(TAG, msg); 13419 throw new SecurityException(msg); 13420 } 13421 // Permission passed 13422 result = true; 13423 } 13424 } else if ("system".equals(componentProcessName)) { 13425 result = true; 13426 } else { 13427 // App with pre-defined UID, check if it's a persistent app 13428 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13429 } 13430 if (DEBUG_MU) { 13431 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13432 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13433 } 13434 return result; 13435 } 13436 13437 /** 13438 * Checks to see if the caller is in the same app as the singleton 13439 * component, or the component is in a special app. It allows special apps 13440 * to export singleton components but prevents exporting singleton 13441 * components for regular apps. 13442 */ 13443 boolean isValidSingletonCall(int callingUid, int componentUid) { 13444 int componentAppId = UserHandle.getAppId(componentUid); 13445 return UserHandle.isSameApp(callingUid, componentUid) 13446 || componentAppId == Process.SYSTEM_UID 13447 || componentAppId == Process.PHONE_UID 13448 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13449 == PackageManager.PERMISSION_GRANTED; 13450 } 13451 13452 public int bindService(IApplicationThread caller, IBinder token, 13453 Intent service, String resolvedType, 13454 IServiceConnection connection, int flags, int userId) { 13455 enforceNotIsolatedCaller("bindService"); 13456 // Refuse possible leaked file descriptors 13457 if (service != null && service.hasFileDescriptors() == true) { 13458 throw new IllegalArgumentException("File descriptors passed in Intent"); 13459 } 13460 13461 synchronized(this) { 13462 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13463 connection, flags, userId); 13464 } 13465 } 13466 13467 public boolean unbindService(IServiceConnection connection) { 13468 synchronized (this) { 13469 return mServices.unbindServiceLocked(connection); 13470 } 13471 } 13472 13473 public void publishService(IBinder token, Intent intent, IBinder service) { 13474 // Refuse possible leaked file descriptors 13475 if (intent != null && intent.hasFileDescriptors() == true) { 13476 throw new IllegalArgumentException("File descriptors passed in Intent"); 13477 } 13478 13479 synchronized(this) { 13480 if (!(token instanceof ServiceRecord)) { 13481 throw new IllegalArgumentException("Invalid service token"); 13482 } 13483 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13484 } 13485 } 13486 13487 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13488 // Refuse possible leaked file descriptors 13489 if (intent != null && intent.hasFileDescriptors() == true) { 13490 throw new IllegalArgumentException("File descriptors passed in Intent"); 13491 } 13492 13493 synchronized(this) { 13494 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13495 } 13496 } 13497 13498 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13499 synchronized(this) { 13500 if (!(token instanceof ServiceRecord)) { 13501 throw new IllegalArgumentException("Invalid service token"); 13502 } 13503 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13504 } 13505 } 13506 13507 // ========================================================= 13508 // BACKUP AND RESTORE 13509 // ========================================================= 13510 13511 // Cause the target app to be launched if necessary and its backup agent 13512 // instantiated. The backup agent will invoke backupAgentCreated() on the 13513 // activity manager to announce its creation. 13514 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13515 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13516 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13517 13518 synchronized(this) { 13519 // !!! TODO: currently no check here that we're already bound 13520 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13521 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13522 synchronized (stats) { 13523 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13524 } 13525 13526 // Backup agent is now in use, its package can't be stopped. 13527 try { 13528 AppGlobals.getPackageManager().setPackageStoppedState( 13529 app.packageName, false, UserHandle.getUserId(app.uid)); 13530 } catch (RemoteException e) { 13531 } catch (IllegalArgumentException e) { 13532 Slog.w(TAG, "Failed trying to unstop package " 13533 + app.packageName + ": " + e); 13534 } 13535 13536 BackupRecord r = new BackupRecord(ss, app, backupMode); 13537 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13538 ? new ComponentName(app.packageName, app.backupAgentName) 13539 : new ComponentName("android", "FullBackupAgent"); 13540 // startProcessLocked() returns existing proc's record if it's already running 13541 ProcessRecord proc = startProcessLocked(app.processName, app, 13542 false, 0, "backup", hostingName, false, false, false); 13543 if (proc == null) { 13544 Slog.e(TAG, "Unable to start backup agent process " + r); 13545 return false; 13546 } 13547 13548 r.app = proc; 13549 mBackupTarget = r; 13550 mBackupAppName = app.packageName; 13551 13552 // Try not to kill the process during backup 13553 updateOomAdjLocked(proc); 13554 13555 // If the process is already attached, schedule the creation of the backup agent now. 13556 // If it is not yet live, this will be done when it attaches to the framework. 13557 if (proc.thread != null) { 13558 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13559 try { 13560 proc.thread.scheduleCreateBackupAgent(app, 13561 compatibilityInfoForPackageLocked(app), backupMode); 13562 } catch (RemoteException e) { 13563 // Will time out on the backup manager side 13564 } 13565 } else { 13566 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13567 } 13568 // Invariants: at this point, the target app process exists and the application 13569 // is either already running or in the process of coming up. mBackupTarget and 13570 // mBackupAppName describe the app, so that when it binds back to the AM we 13571 // know that it's scheduled for a backup-agent operation. 13572 } 13573 13574 return true; 13575 } 13576 13577 @Override 13578 public void clearPendingBackup() { 13579 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13580 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13581 13582 synchronized (this) { 13583 mBackupTarget = null; 13584 mBackupAppName = null; 13585 } 13586 } 13587 13588 // A backup agent has just come up 13589 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13590 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13591 + " = " + agent); 13592 13593 synchronized(this) { 13594 if (!agentPackageName.equals(mBackupAppName)) { 13595 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13596 return; 13597 } 13598 } 13599 13600 long oldIdent = Binder.clearCallingIdentity(); 13601 try { 13602 IBackupManager bm = IBackupManager.Stub.asInterface( 13603 ServiceManager.getService(Context.BACKUP_SERVICE)); 13604 bm.agentConnected(agentPackageName, agent); 13605 } catch (RemoteException e) { 13606 // can't happen; the backup manager service is local 13607 } catch (Exception e) { 13608 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13609 e.printStackTrace(); 13610 } finally { 13611 Binder.restoreCallingIdentity(oldIdent); 13612 } 13613 } 13614 13615 // done with this agent 13616 public void unbindBackupAgent(ApplicationInfo appInfo) { 13617 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13618 if (appInfo == null) { 13619 Slog.w(TAG, "unbind backup agent for null app"); 13620 return; 13621 } 13622 13623 synchronized(this) { 13624 try { 13625 if (mBackupAppName == null) { 13626 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13627 return; 13628 } 13629 13630 if (!mBackupAppName.equals(appInfo.packageName)) { 13631 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13632 return; 13633 } 13634 13635 // Not backing this app up any more; reset its OOM adjustment 13636 final ProcessRecord proc = mBackupTarget.app; 13637 updateOomAdjLocked(proc); 13638 13639 // If the app crashed during backup, 'thread' will be null here 13640 if (proc.thread != null) { 13641 try { 13642 proc.thread.scheduleDestroyBackupAgent(appInfo, 13643 compatibilityInfoForPackageLocked(appInfo)); 13644 } catch (Exception e) { 13645 Slog.e(TAG, "Exception when unbinding backup agent:"); 13646 e.printStackTrace(); 13647 } 13648 } 13649 } finally { 13650 mBackupTarget = null; 13651 mBackupAppName = null; 13652 } 13653 } 13654 } 13655 // ========================================================= 13656 // BROADCASTS 13657 // ========================================================= 13658 13659 private final List getStickiesLocked(String action, IntentFilter filter, 13660 List cur, int userId) { 13661 final ContentResolver resolver = mContext.getContentResolver(); 13662 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13663 if (stickies == null) { 13664 return cur; 13665 } 13666 final ArrayList<Intent> list = stickies.get(action); 13667 if (list == null) { 13668 return cur; 13669 } 13670 int N = list.size(); 13671 for (int i=0; i<N; i++) { 13672 Intent intent = list.get(i); 13673 if (filter.match(resolver, intent, true, TAG) >= 0) { 13674 if (cur == null) { 13675 cur = new ArrayList<Intent>(); 13676 } 13677 cur.add(intent); 13678 } 13679 } 13680 return cur; 13681 } 13682 13683 boolean isPendingBroadcastProcessLocked(int pid) { 13684 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13685 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13686 } 13687 13688 void skipPendingBroadcastLocked(int pid) { 13689 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13690 for (BroadcastQueue queue : mBroadcastQueues) { 13691 queue.skipPendingBroadcastLocked(pid); 13692 } 13693 } 13694 13695 // The app just attached; send any pending broadcasts that it should receive 13696 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13697 boolean didSomething = false; 13698 for (BroadcastQueue queue : mBroadcastQueues) { 13699 didSomething |= queue.sendPendingBroadcastsLocked(app); 13700 } 13701 return didSomething; 13702 } 13703 13704 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13705 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13706 enforceNotIsolatedCaller("registerReceiver"); 13707 int callingUid; 13708 int callingPid; 13709 synchronized(this) { 13710 ProcessRecord callerApp = null; 13711 if (caller != null) { 13712 callerApp = getRecordForAppLocked(caller); 13713 if (callerApp == null) { 13714 throw new SecurityException( 13715 "Unable to find app for caller " + caller 13716 + " (pid=" + Binder.getCallingPid() 13717 + ") when registering receiver " + receiver); 13718 } 13719 if (callerApp.info.uid != Process.SYSTEM_UID && 13720 !callerApp.pkgList.containsKey(callerPackage) && 13721 !"android".equals(callerPackage)) { 13722 throw new SecurityException("Given caller package " + callerPackage 13723 + " is not running in process " + callerApp); 13724 } 13725 callingUid = callerApp.info.uid; 13726 callingPid = callerApp.pid; 13727 } else { 13728 callerPackage = null; 13729 callingUid = Binder.getCallingUid(); 13730 callingPid = Binder.getCallingPid(); 13731 } 13732 13733 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13734 true, true, "registerReceiver", callerPackage); 13735 13736 List allSticky = null; 13737 13738 // Look for any matching sticky broadcasts... 13739 Iterator actions = filter.actionsIterator(); 13740 if (actions != null) { 13741 while (actions.hasNext()) { 13742 String action = (String)actions.next(); 13743 allSticky = getStickiesLocked(action, filter, allSticky, 13744 UserHandle.USER_ALL); 13745 allSticky = getStickiesLocked(action, filter, allSticky, 13746 UserHandle.getUserId(callingUid)); 13747 } 13748 } else { 13749 allSticky = getStickiesLocked(null, filter, allSticky, 13750 UserHandle.USER_ALL); 13751 allSticky = getStickiesLocked(null, filter, allSticky, 13752 UserHandle.getUserId(callingUid)); 13753 } 13754 13755 // The first sticky in the list is returned directly back to 13756 // the client. 13757 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13758 13759 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13760 + ": " + sticky); 13761 13762 if (receiver == null) { 13763 return sticky; 13764 } 13765 13766 ReceiverList rl 13767 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13768 if (rl == null) { 13769 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13770 userId, receiver); 13771 if (rl.app != null) { 13772 rl.app.receivers.add(rl); 13773 } else { 13774 try { 13775 receiver.asBinder().linkToDeath(rl, 0); 13776 } catch (RemoteException e) { 13777 return sticky; 13778 } 13779 rl.linkedToDeath = true; 13780 } 13781 mRegisteredReceivers.put(receiver.asBinder(), rl); 13782 } else if (rl.uid != callingUid) { 13783 throw new IllegalArgumentException( 13784 "Receiver requested to register for uid " + callingUid 13785 + " was previously registered for uid " + rl.uid); 13786 } else if (rl.pid != callingPid) { 13787 throw new IllegalArgumentException( 13788 "Receiver requested to register for pid " + callingPid 13789 + " was previously registered for pid " + rl.pid); 13790 } else if (rl.userId != userId) { 13791 throw new IllegalArgumentException( 13792 "Receiver requested to register for user " + userId 13793 + " was previously registered for user " + rl.userId); 13794 } 13795 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13796 permission, callingUid, userId); 13797 rl.add(bf); 13798 if (!bf.debugCheck()) { 13799 Slog.w(TAG, "==> For Dynamic broadast"); 13800 } 13801 mReceiverResolver.addFilter(bf); 13802 13803 // Enqueue broadcasts for all existing stickies that match 13804 // this filter. 13805 if (allSticky != null) { 13806 ArrayList receivers = new ArrayList(); 13807 receivers.add(bf); 13808 13809 int N = allSticky.size(); 13810 for (int i=0; i<N; i++) { 13811 Intent intent = (Intent)allSticky.get(i); 13812 BroadcastQueue queue = broadcastQueueForIntent(intent); 13813 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13814 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13815 null, null, false, true, true, -1); 13816 queue.enqueueParallelBroadcastLocked(r); 13817 queue.scheduleBroadcastsLocked(); 13818 } 13819 } 13820 13821 return sticky; 13822 } 13823 } 13824 13825 public void unregisterReceiver(IIntentReceiver receiver) { 13826 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13827 13828 final long origId = Binder.clearCallingIdentity(); 13829 try { 13830 boolean doTrim = false; 13831 13832 synchronized(this) { 13833 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13834 if (rl != null) { 13835 if (rl.curBroadcast != null) { 13836 BroadcastRecord r = rl.curBroadcast; 13837 final boolean doNext = finishReceiverLocked( 13838 receiver.asBinder(), r.resultCode, r.resultData, 13839 r.resultExtras, r.resultAbort); 13840 if (doNext) { 13841 doTrim = true; 13842 r.queue.processNextBroadcast(false); 13843 } 13844 } 13845 13846 if (rl.app != null) { 13847 rl.app.receivers.remove(rl); 13848 } 13849 removeReceiverLocked(rl); 13850 if (rl.linkedToDeath) { 13851 rl.linkedToDeath = false; 13852 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13853 } 13854 } 13855 } 13856 13857 // If we actually concluded any broadcasts, we might now be able 13858 // to trim the recipients' apps from our working set 13859 if (doTrim) { 13860 trimApplications(); 13861 return; 13862 } 13863 13864 } finally { 13865 Binder.restoreCallingIdentity(origId); 13866 } 13867 } 13868 13869 void removeReceiverLocked(ReceiverList rl) { 13870 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13871 int N = rl.size(); 13872 for (int i=0; i<N; i++) { 13873 mReceiverResolver.removeFilter(rl.get(i)); 13874 } 13875 } 13876 13877 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13878 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13879 ProcessRecord r = mLruProcesses.get(i); 13880 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13881 try { 13882 r.thread.dispatchPackageBroadcast(cmd, packages); 13883 } catch (RemoteException ex) { 13884 } 13885 } 13886 } 13887 } 13888 13889 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13890 int[] users) { 13891 List<ResolveInfo> receivers = null; 13892 try { 13893 HashSet<ComponentName> singleUserReceivers = null; 13894 boolean scannedFirstReceivers = false; 13895 for (int user : users) { 13896 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13897 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13898 if (user != 0 && newReceivers != null) { 13899 // If this is not the primary user, we need to check for 13900 // any receivers that should be filtered out. 13901 for (int i=0; i<newReceivers.size(); i++) { 13902 ResolveInfo ri = newReceivers.get(i); 13903 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13904 newReceivers.remove(i); 13905 i--; 13906 } 13907 } 13908 } 13909 if (newReceivers != null && newReceivers.size() == 0) { 13910 newReceivers = null; 13911 } 13912 if (receivers == null) { 13913 receivers = newReceivers; 13914 } else if (newReceivers != null) { 13915 // We need to concatenate the additional receivers 13916 // found with what we have do far. This would be easy, 13917 // but we also need to de-dup any receivers that are 13918 // singleUser. 13919 if (!scannedFirstReceivers) { 13920 // Collect any single user receivers we had already retrieved. 13921 scannedFirstReceivers = true; 13922 for (int i=0; i<receivers.size(); i++) { 13923 ResolveInfo ri = receivers.get(i); 13924 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13925 ComponentName cn = new ComponentName( 13926 ri.activityInfo.packageName, ri.activityInfo.name); 13927 if (singleUserReceivers == null) { 13928 singleUserReceivers = new HashSet<ComponentName>(); 13929 } 13930 singleUserReceivers.add(cn); 13931 } 13932 } 13933 } 13934 // Add the new results to the existing results, tracking 13935 // and de-dupping single user receivers. 13936 for (int i=0; i<newReceivers.size(); i++) { 13937 ResolveInfo ri = newReceivers.get(i); 13938 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13939 ComponentName cn = new ComponentName( 13940 ri.activityInfo.packageName, ri.activityInfo.name); 13941 if (singleUserReceivers == null) { 13942 singleUserReceivers = new HashSet<ComponentName>(); 13943 } 13944 if (!singleUserReceivers.contains(cn)) { 13945 singleUserReceivers.add(cn); 13946 receivers.add(ri); 13947 } 13948 } else { 13949 receivers.add(ri); 13950 } 13951 } 13952 } 13953 } 13954 } catch (RemoteException ex) { 13955 // pm is in same process, this will never happen. 13956 } 13957 return receivers; 13958 } 13959 13960 private final int broadcastIntentLocked(ProcessRecord callerApp, 13961 String callerPackage, Intent intent, String resolvedType, 13962 IIntentReceiver resultTo, int resultCode, String resultData, 13963 Bundle map, String requiredPermission, int appOp, 13964 boolean ordered, boolean sticky, int callingPid, int callingUid, 13965 int userId) { 13966 intent = new Intent(intent); 13967 13968 // By default broadcasts do not go to stopped apps. 13969 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13970 13971 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13972 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13973 + " ordered=" + ordered + " userid=" + userId); 13974 if ((resultTo != null) && !ordered) { 13975 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13976 } 13977 13978 userId = handleIncomingUser(callingPid, callingUid, userId, 13979 true, false, "broadcast", callerPackage); 13980 13981 // Make sure that the user who is receiving this broadcast is started. 13982 // If not, we will just skip it. 13983 13984 13985 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13986 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13987 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13988 Slog.w(TAG, "Skipping broadcast of " + intent 13989 + ": user " + userId + " is stopped"); 13990 return ActivityManager.BROADCAST_SUCCESS; 13991 } 13992 } 13993 13994 /* 13995 * Prevent non-system code (defined here to be non-persistent 13996 * processes) from sending protected broadcasts. 13997 */ 13998 int callingAppId = UserHandle.getAppId(callingUid); 13999 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14000 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14001 || callingAppId == Process.NFC_UID || callingUid == 0) { 14002 // Always okay. 14003 } else if (callerApp == null || !callerApp.persistent) { 14004 try { 14005 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14006 intent.getAction())) { 14007 String msg = "Permission Denial: not allowed to send broadcast " 14008 + intent.getAction() + " from pid=" 14009 + callingPid + ", uid=" + callingUid; 14010 Slog.w(TAG, msg); 14011 throw new SecurityException(msg); 14012 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14013 // Special case for compatibility: we don't want apps to send this, 14014 // but historically it has not been protected and apps may be using it 14015 // to poke their own app widget. So, instead of making it protected, 14016 // just limit it to the caller. 14017 if (callerApp == null) { 14018 String msg = "Permission Denial: not allowed to send broadcast " 14019 + intent.getAction() + " from unknown caller."; 14020 Slog.w(TAG, msg); 14021 throw new SecurityException(msg); 14022 } else if (intent.getComponent() != null) { 14023 // They are good enough to send to an explicit component... verify 14024 // it is being sent to the calling app. 14025 if (!intent.getComponent().getPackageName().equals( 14026 callerApp.info.packageName)) { 14027 String msg = "Permission Denial: not allowed to send broadcast " 14028 + intent.getAction() + " to " 14029 + intent.getComponent().getPackageName() + " from " 14030 + callerApp.info.packageName; 14031 Slog.w(TAG, msg); 14032 throw new SecurityException(msg); 14033 } 14034 } else { 14035 // Limit broadcast to their own package. 14036 intent.setPackage(callerApp.info.packageName); 14037 } 14038 } 14039 } catch (RemoteException e) { 14040 Slog.w(TAG, "Remote exception", e); 14041 return ActivityManager.BROADCAST_SUCCESS; 14042 } 14043 } 14044 14045 // Handle special intents: if this broadcast is from the package 14046 // manager about a package being removed, we need to remove all of 14047 // its activities from the history stack. 14048 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14049 intent.getAction()); 14050 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14051 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14052 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14053 || uidRemoved) { 14054 if (checkComponentPermission( 14055 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14056 callingPid, callingUid, -1, true) 14057 == PackageManager.PERMISSION_GRANTED) { 14058 if (uidRemoved) { 14059 final Bundle intentExtras = intent.getExtras(); 14060 final int uid = intentExtras != null 14061 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14062 if (uid >= 0) { 14063 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14064 synchronized (bs) { 14065 bs.removeUidStatsLocked(uid); 14066 } 14067 mAppOpsService.uidRemoved(uid); 14068 } 14069 } else { 14070 // If resources are unavailable just force stop all 14071 // those packages and flush the attribute cache as well. 14072 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14073 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14074 if (list != null && (list.length > 0)) { 14075 for (String pkg : list) { 14076 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14077 "storage unmount"); 14078 } 14079 sendPackageBroadcastLocked( 14080 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14081 } 14082 } else { 14083 Uri data = intent.getData(); 14084 String ssp; 14085 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14086 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14087 intent.getAction()); 14088 boolean fullUninstall = removed && 14089 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14090 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14091 forceStopPackageLocked(ssp, UserHandle.getAppId( 14092 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14093 false, fullUninstall, userId, 14094 removed ? "pkg removed" : "pkg changed"); 14095 } 14096 if (removed) { 14097 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14098 new String[] {ssp}, userId); 14099 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14100 mAppOpsService.packageRemoved( 14101 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14102 14103 // Remove all permissions granted from/to this package 14104 removeUriPermissionsForPackageLocked(ssp, userId, true); 14105 } 14106 } 14107 } 14108 } 14109 } 14110 } else { 14111 String msg = "Permission Denial: " + intent.getAction() 14112 + " broadcast from " + callerPackage + " (pid=" + callingPid 14113 + ", uid=" + callingUid + ")" 14114 + " requires " 14115 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14116 Slog.w(TAG, msg); 14117 throw new SecurityException(msg); 14118 } 14119 14120 // Special case for adding a package: by default turn on compatibility 14121 // mode. 14122 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14123 Uri data = intent.getData(); 14124 String ssp; 14125 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14126 mCompatModePackages.handlePackageAddedLocked(ssp, 14127 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14128 } 14129 } 14130 14131 /* 14132 * If this is the time zone changed action, queue up a message that will reset the timezone 14133 * of all currently running processes. This message will get queued up before the broadcast 14134 * happens. 14135 */ 14136 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14137 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14138 } 14139 14140 /* 14141 * If the user set the time, let all running processes know. 14142 */ 14143 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14144 final int is24Hour = intent.getBooleanExtra( 14145 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14146 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14147 } 14148 14149 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14150 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14151 } 14152 14153 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14154 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14155 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14156 } 14157 14158 // Add to the sticky list if requested. 14159 if (sticky) { 14160 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14161 callingPid, callingUid) 14162 != PackageManager.PERMISSION_GRANTED) { 14163 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14164 + callingPid + ", uid=" + callingUid 14165 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14166 Slog.w(TAG, msg); 14167 throw new SecurityException(msg); 14168 } 14169 if (requiredPermission != null) { 14170 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14171 + " and enforce permission " + requiredPermission); 14172 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14173 } 14174 if (intent.getComponent() != null) { 14175 throw new SecurityException( 14176 "Sticky broadcasts can't target a specific component"); 14177 } 14178 // We use userId directly here, since the "all" target is maintained 14179 // as a separate set of sticky broadcasts. 14180 if (userId != UserHandle.USER_ALL) { 14181 // But first, if this is not a broadcast to all users, then 14182 // make sure it doesn't conflict with an existing broadcast to 14183 // all users. 14184 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14185 UserHandle.USER_ALL); 14186 if (stickies != null) { 14187 ArrayList<Intent> list = stickies.get(intent.getAction()); 14188 if (list != null) { 14189 int N = list.size(); 14190 int i; 14191 for (i=0; i<N; i++) { 14192 if (intent.filterEquals(list.get(i))) { 14193 throw new IllegalArgumentException( 14194 "Sticky broadcast " + intent + " for user " 14195 + userId + " conflicts with existing global broadcast"); 14196 } 14197 } 14198 } 14199 } 14200 } 14201 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14202 if (stickies == null) { 14203 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14204 mStickyBroadcasts.put(userId, stickies); 14205 } 14206 ArrayList<Intent> list = stickies.get(intent.getAction()); 14207 if (list == null) { 14208 list = new ArrayList<Intent>(); 14209 stickies.put(intent.getAction(), list); 14210 } 14211 int N = list.size(); 14212 int i; 14213 for (i=0; i<N; i++) { 14214 if (intent.filterEquals(list.get(i))) { 14215 // This sticky already exists, replace it. 14216 list.set(i, new Intent(intent)); 14217 break; 14218 } 14219 } 14220 if (i >= N) { 14221 list.add(new Intent(intent)); 14222 } 14223 } 14224 14225 int[] users; 14226 if (userId == UserHandle.USER_ALL) { 14227 // Caller wants broadcast to go to all started users. 14228 users = mStartedUserArray; 14229 } else { 14230 // Caller wants broadcast to go to one specific user. 14231 users = new int[] {userId}; 14232 } 14233 14234 // Figure out who all will receive this broadcast. 14235 List receivers = null; 14236 List<BroadcastFilter> registeredReceivers = null; 14237 // Need to resolve the intent to interested receivers... 14238 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14239 == 0) { 14240 receivers = collectReceiverComponents(intent, resolvedType, users); 14241 } 14242 if (intent.getComponent() == null) { 14243 registeredReceivers = mReceiverResolver.queryIntent(intent, 14244 resolvedType, false, userId); 14245 } 14246 14247 final boolean replacePending = 14248 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14249 14250 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14251 + " replacePending=" + replacePending); 14252 14253 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14254 if (!ordered && NR > 0) { 14255 // If we are not serializing this broadcast, then send the 14256 // registered receivers separately so they don't wait for the 14257 // components to be launched. 14258 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14259 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14260 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14261 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14262 ordered, sticky, false, userId); 14263 if (DEBUG_BROADCAST) Slog.v( 14264 TAG, "Enqueueing parallel broadcast " + r); 14265 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14266 if (!replaced) { 14267 queue.enqueueParallelBroadcastLocked(r); 14268 queue.scheduleBroadcastsLocked(); 14269 } 14270 registeredReceivers = null; 14271 NR = 0; 14272 } 14273 14274 // Merge into one list. 14275 int ir = 0; 14276 if (receivers != null) { 14277 // A special case for PACKAGE_ADDED: do not allow the package 14278 // being added to see this broadcast. This prevents them from 14279 // using this as a back door to get run as soon as they are 14280 // installed. Maybe in the future we want to have a special install 14281 // broadcast or such for apps, but we'd like to deliberately make 14282 // this decision. 14283 String skipPackages[] = null; 14284 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14285 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14286 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14287 Uri data = intent.getData(); 14288 if (data != null) { 14289 String pkgName = data.getSchemeSpecificPart(); 14290 if (pkgName != null) { 14291 skipPackages = new String[] { pkgName }; 14292 } 14293 } 14294 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14295 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14296 } 14297 if (skipPackages != null && (skipPackages.length > 0)) { 14298 for (String skipPackage : skipPackages) { 14299 if (skipPackage != null) { 14300 int NT = receivers.size(); 14301 for (int it=0; it<NT; it++) { 14302 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14303 if (curt.activityInfo.packageName.equals(skipPackage)) { 14304 receivers.remove(it); 14305 it--; 14306 NT--; 14307 } 14308 } 14309 } 14310 } 14311 } 14312 14313 int NT = receivers != null ? receivers.size() : 0; 14314 int it = 0; 14315 ResolveInfo curt = null; 14316 BroadcastFilter curr = null; 14317 while (it < NT && ir < NR) { 14318 if (curt == null) { 14319 curt = (ResolveInfo)receivers.get(it); 14320 } 14321 if (curr == null) { 14322 curr = registeredReceivers.get(ir); 14323 } 14324 if (curr.getPriority() >= curt.priority) { 14325 // Insert this broadcast record into the final list. 14326 receivers.add(it, curr); 14327 ir++; 14328 curr = null; 14329 it++; 14330 NT++; 14331 } else { 14332 // Skip to the next ResolveInfo in the final list. 14333 it++; 14334 curt = null; 14335 } 14336 } 14337 } 14338 while (ir < NR) { 14339 if (receivers == null) { 14340 receivers = new ArrayList(); 14341 } 14342 receivers.add(registeredReceivers.get(ir)); 14343 ir++; 14344 } 14345 14346 if ((receivers != null && receivers.size() > 0) 14347 || resultTo != null) { 14348 BroadcastQueue queue = broadcastQueueForIntent(intent); 14349 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14350 callerPackage, callingPid, callingUid, resolvedType, 14351 requiredPermission, appOp, receivers, resultTo, resultCode, 14352 resultData, map, ordered, sticky, false, userId); 14353 if (DEBUG_BROADCAST) Slog.v( 14354 TAG, "Enqueueing ordered broadcast " + r 14355 + ": prev had " + queue.mOrderedBroadcasts.size()); 14356 if (DEBUG_BROADCAST) { 14357 int seq = r.intent.getIntExtra("seq", -1); 14358 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14359 } 14360 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14361 if (!replaced) { 14362 queue.enqueueOrderedBroadcastLocked(r); 14363 queue.scheduleBroadcastsLocked(); 14364 } 14365 } 14366 14367 return ActivityManager.BROADCAST_SUCCESS; 14368 } 14369 14370 final Intent verifyBroadcastLocked(Intent intent) { 14371 // Refuse possible leaked file descriptors 14372 if (intent != null && intent.hasFileDescriptors() == true) { 14373 throw new IllegalArgumentException("File descriptors passed in Intent"); 14374 } 14375 14376 int flags = intent.getFlags(); 14377 14378 if (!mProcessesReady) { 14379 // if the caller really truly claims to know what they're doing, go 14380 // ahead and allow the broadcast without launching any receivers 14381 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14382 intent = new Intent(intent); 14383 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14384 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14385 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14386 + " before boot completion"); 14387 throw new IllegalStateException("Cannot broadcast before boot completed"); 14388 } 14389 } 14390 14391 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14392 throw new IllegalArgumentException( 14393 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14394 } 14395 14396 return intent; 14397 } 14398 14399 public final int broadcastIntent(IApplicationThread caller, 14400 Intent intent, String resolvedType, IIntentReceiver resultTo, 14401 int resultCode, String resultData, Bundle map, 14402 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14403 enforceNotIsolatedCaller("broadcastIntent"); 14404 synchronized(this) { 14405 intent = verifyBroadcastLocked(intent); 14406 14407 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14408 final int callingPid = Binder.getCallingPid(); 14409 final int callingUid = Binder.getCallingUid(); 14410 final long origId = Binder.clearCallingIdentity(); 14411 int res = broadcastIntentLocked(callerApp, 14412 callerApp != null ? callerApp.info.packageName : null, 14413 intent, resolvedType, resultTo, 14414 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14415 callingPid, callingUid, userId); 14416 Binder.restoreCallingIdentity(origId); 14417 return res; 14418 } 14419 } 14420 14421 int broadcastIntentInPackage(String packageName, int uid, 14422 Intent intent, String resolvedType, IIntentReceiver resultTo, 14423 int resultCode, String resultData, Bundle map, 14424 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14425 synchronized(this) { 14426 intent = verifyBroadcastLocked(intent); 14427 14428 final long origId = Binder.clearCallingIdentity(); 14429 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14430 resultTo, resultCode, resultData, map, requiredPermission, 14431 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14432 Binder.restoreCallingIdentity(origId); 14433 return res; 14434 } 14435 } 14436 14437 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14438 // Refuse possible leaked file descriptors 14439 if (intent != null && intent.hasFileDescriptors() == true) { 14440 throw new IllegalArgumentException("File descriptors passed in Intent"); 14441 } 14442 14443 userId = handleIncomingUser(Binder.getCallingPid(), 14444 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14445 14446 synchronized(this) { 14447 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14448 != PackageManager.PERMISSION_GRANTED) { 14449 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14450 + Binder.getCallingPid() 14451 + ", uid=" + Binder.getCallingUid() 14452 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14453 Slog.w(TAG, msg); 14454 throw new SecurityException(msg); 14455 } 14456 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14457 if (stickies != null) { 14458 ArrayList<Intent> list = stickies.get(intent.getAction()); 14459 if (list != null) { 14460 int N = list.size(); 14461 int i; 14462 for (i=0; i<N; i++) { 14463 if (intent.filterEquals(list.get(i))) { 14464 list.remove(i); 14465 break; 14466 } 14467 } 14468 if (list.size() <= 0) { 14469 stickies.remove(intent.getAction()); 14470 } 14471 } 14472 if (stickies.size() <= 0) { 14473 mStickyBroadcasts.remove(userId); 14474 } 14475 } 14476 } 14477 } 14478 14479 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14480 String resultData, Bundle resultExtras, boolean resultAbort) { 14481 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14482 if (r == null) { 14483 Slog.w(TAG, "finishReceiver called but not found on queue"); 14484 return false; 14485 } 14486 14487 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14488 } 14489 14490 void backgroundServicesFinishedLocked(int userId) { 14491 for (BroadcastQueue queue : mBroadcastQueues) { 14492 queue.backgroundServicesFinishedLocked(userId); 14493 } 14494 } 14495 14496 public void finishReceiver(IBinder who, int resultCode, String resultData, 14497 Bundle resultExtras, boolean resultAbort) { 14498 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14499 14500 // Refuse possible leaked file descriptors 14501 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14502 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14503 } 14504 14505 final long origId = Binder.clearCallingIdentity(); 14506 try { 14507 boolean doNext = false; 14508 BroadcastRecord r; 14509 14510 synchronized(this) { 14511 r = broadcastRecordForReceiverLocked(who); 14512 if (r != null) { 14513 doNext = r.queue.finishReceiverLocked(r, resultCode, 14514 resultData, resultExtras, resultAbort, true); 14515 } 14516 } 14517 14518 if (doNext) { 14519 r.queue.processNextBroadcast(false); 14520 } 14521 trimApplications(); 14522 } finally { 14523 Binder.restoreCallingIdentity(origId); 14524 } 14525 } 14526 14527 // ========================================================= 14528 // INSTRUMENTATION 14529 // ========================================================= 14530 14531 public boolean startInstrumentation(ComponentName className, 14532 String profileFile, int flags, Bundle arguments, 14533 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14534 int userId, String abiOverride) { 14535 enforceNotIsolatedCaller("startInstrumentation"); 14536 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14537 userId, false, true, "startInstrumentation", null); 14538 // Refuse possible leaked file descriptors 14539 if (arguments != null && arguments.hasFileDescriptors()) { 14540 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14541 } 14542 14543 synchronized(this) { 14544 InstrumentationInfo ii = null; 14545 ApplicationInfo ai = null; 14546 try { 14547 ii = mContext.getPackageManager().getInstrumentationInfo( 14548 className, STOCK_PM_FLAGS); 14549 ai = AppGlobals.getPackageManager().getApplicationInfo( 14550 ii.targetPackage, STOCK_PM_FLAGS, userId); 14551 } catch (PackageManager.NameNotFoundException e) { 14552 } catch (RemoteException e) { 14553 } 14554 if (ii == null) { 14555 reportStartInstrumentationFailure(watcher, className, 14556 "Unable to find instrumentation info for: " + className); 14557 return false; 14558 } 14559 if (ai == null) { 14560 reportStartInstrumentationFailure(watcher, className, 14561 "Unable to find instrumentation target package: " + ii.targetPackage); 14562 return false; 14563 } 14564 14565 int match = mContext.getPackageManager().checkSignatures( 14566 ii.targetPackage, ii.packageName); 14567 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14568 String msg = "Permission Denial: starting instrumentation " 14569 + className + " from pid=" 14570 + Binder.getCallingPid() 14571 + ", uid=" + Binder.getCallingPid() 14572 + " not allowed because package " + ii.packageName 14573 + " does not have a signature matching the target " 14574 + ii.targetPackage; 14575 reportStartInstrumentationFailure(watcher, className, msg); 14576 throw new SecurityException(msg); 14577 } 14578 14579 final long origId = Binder.clearCallingIdentity(); 14580 // Instrumentation can kill and relaunch even persistent processes 14581 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14582 "start instr"); 14583 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14584 app.instrumentationClass = className; 14585 app.instrumentationInfo = ai; 14586 app.instrumentationProfileFile = profileFile; 14587 app.instrumentationArguments = arguments; 14588 app.instrumentationWatcher = watcher; 14589 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14590 app.instrumentationResultClass = className; 14591 Binder.restoreCallingIdentity(origId); 14592 } 14593 14594 return true; 14595 } 14596 14597 /** 14598 * Report errors that occur while attempting to start Instrumentation. Always writes the 14599 * error to the logs, but if somebody is watching, send the report there too. This enables 14600 * the "am" command to report errors with more information. 14601 * 14602 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14603 * @param cn The component name of the instrumentation. 14604 * @param report The error report. 14605 */ 14606 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14607 ComponentName cn, String report) { 14608 Slog.w(TAG, report); 14609 try { 14610 if (watcher != null) { 14611 Bundle results = new Bundle(); 14612 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14613 results.putString("Error", report); 14614 watcher.instrumentationStatus(cn, -1, results); 14615 } 14616 } catch (RemoteException e) { 14617 Slog.w(TAG, e); 14618 } 14619 } 14620 14621 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14622 if (app.instrumentationWatcher != null) { 14623 try { 14624 // NOTE: IInstrumentationWatcher *must* be oneway here 14625 app.instrumentationWatcher.instrumentationFinished( 14626 app.instrumentationClass, 14627 resultCode, 14628 results); 14629 } catch (RemoteException e) { 14630 } 14631 } 14632 if (app.instrumentationUiAutomationConnection != null) { 14633 try { 14634 app.instrumentationUiAutomationConnection.shutdown(); 14635 } catch (RemoteException re) { 14636 /* ignore */ 14637 } 14638 // Only a UiAutomation can set this flag and now that 14639 // it is finished we make sure it is reset to its default. 14640 mUserIsMonkey = false; 14641 } 14642 app.instrumentationWatcher = null; 14643 app.instrumentationUiAutomationConnection = null; 14644 app.instrumentationClass = null; 14645 app.instrumentationInfo = null; 14646 app.instrumentationProfileFile = null; 14647 app.instrumentationArguments = null; 14648 14649 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14650 "finished inst"); 14651 } 14652 14653 public void finishInstrumentation(IApplicationThread target, 14654 int resultCode, Bundle results) { 14655 int userId = UserHandle.getCallingUserId(); 14656 // Refuse possible leaked file descriptors 14657 if (results != null && results.hasFileDescriptors()) { 14658 throw new IllegalArgumentException("File descriptors passed in Intent"); 14659 } 14660 14661 synchronized(this) { 14662 ProcessRecord app = getRecordForAppLocked(target); 14663 if (app == null) { 14664 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14665 return; 14666 } 14667 final long origId = Binder.clearCallingIdentity(); 14668 finishInstrumentationLocked(app, resultCode, results); 14669 Binder.restoreCallingIdentity(origId); 14670 } 14671 } 14672 14673 // ========================================================= 14674 // CONFIGURATION 14675 // ========================================================= 14676 14677 public ConfigurationInfo getDeviceConfigurationInfo() { 14678 ConfigurationInfo config = new ConfigurationInfo(); 14679 synchronized (this) { 14680 config.reqTouchScreen = mConfiguration.touchscreen; 14681 config.reqKeyboardType = mConfiguration.keyboard; 14682 config.reqNavigation = mConfiguration.navigation; 14683 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14684 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14685 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14686 } 14687 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14688 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14689 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14690 } 14691 config.reqGlEsVersion = GL_ES_VERSION; 14692 } 14693 return config; 14694 } 14695 14696 ActivityStack getFocusedStack() { 14697 return mStackSupervisor.getFocusedStack(); 14698 } 14699 14700 public Configuration getConfiguration() { 14701 Configuration ci; 14702 synchronized(this) { 14703 ci = new Configuration(mConfiguration); 14704 } 14705 return ci; 14706 } 14707 14708 public void updatePersistentConfiguration(Configuration values) { 14709 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14710 "updateConfiguration()"); 14711 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14712 "updateConfiguration()"); 14713 if (values == null) { 14714 throw new NullPointerException("Configuration must not be null"); 14715 } 14716 14717 synchronized(this) { 14718 final long origId = Binder.clearCallingIdentity(); 14719 updateConfigurationLocked(values, null, true, false); 14720 Binder.restoreCallingIdentity(origId); 14721 } 14722 } 14723 14724 public void updateConfiguration(Configuration values) { 14725 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14726 "updateConfiguration()"); 14727 14728 synchronized(this) { 14729 if (values == null && mWindowManager != null) { 14730 // sentinel: fetch the current configuration from the window manager 14731 values = mWindowManager.computeNewConfiguration(); 14732 } 14733 14734 if (mWindowManager != null) { 14735 mProcessList.applyDisplaySize(mWindowManager); 14736 } 14737 14738 final long origId = Binder.clearCallingIdentity(); 14739 if (values != null) { 14740 Settings.System.clearConfiguration(values); 14741 } 14742 updateConfigurationLocked(values, null, false, false); 14743 Binder.restoreCallingIdentity(origId); 14744 } 14745 } 14746 14747 /** 14748 * Do either or both things: (1) change the current configuration, and (2) 14749 * make sure the given activity is running with the (now) current 14750 * configuration. Returns true if the activity has been left running, or 14751 * false if <var>starting</var> is being destroyed to match the new 14752 * configuration. 14753 * @param persistent TODO 14754 */ 14755 boolean updateConfigurationLocked(Configuration values, 14756 ActivityRecord starting, boolean persistent, boolean initLocale) { 14757 int changes = 0; 14758 14759 if (values != null) { 14760 Configuration newConfig = new Configuration(mConfiguration); 14761 changes = newConfig.updateFrom(values); 14762 if (changes != 0) { 14763 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14764 Slog.i(TAG, "Updating configuration to: " + values); 14765 } 14766 14767 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14768 14769 if (values.locale != null && !initLocale) { 14770 saveLocaleLocked(values.locale, 14771 !values.locale.equals(mConfiguration.locale), 14772 values.userSetLocale); 14773 } 14774 14775 mConfigurationSeq++; 14776 if (mConfigurationSeq <= 0) { 14777 mConfigurationSeq = 1; 14778 } 14779 newConfig.seq = mConfigurationSeq; 14780 mConfiguration = newConfig; 14781 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14782 mUsageStatsService.noteStartConfig(newConfig); 14783 14784 final Configuration configCopy = new Configuration(mConfiguration); 14785 14786 // TODO: If our config changes, should we auto dismiss any currently 14787 // showing dialogs? 14788 mShowDialogs = shouldShowDialogs(newConfig); 14789 14790 AttributeCache ac = AttributeCache.instance(); 14791 if (ac != null) { 14792 ac.updateConfiguration(configCopy); 14793 } 14794 14795 // Make sure all resources in our process are updated 14796 // right now, so that anyone who is going to retrieve 14797 // resource values after we return will be sure to get 14798 // the new ones. This is especially important during 14799 // boot, where the first config change needs to guarantee 14800 // all resources have that config before following boot 14801 // code is executed. 14802 mSystemThread.applyConfigurationToResources(configCopy); 14803 14804 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14805 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14806 msg.obj = new Configuration(configCopy); 14807 mHandler.sendMessage(msg); 14808 } 14809 14810 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14811 ProcessRecord app = mLruProcesses.get(i); 14812 try { 14813 if (app.thread != null) { 14814 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14815 + app.processName + " new config " + mConfiguration); 14816 app.thread.scheduleConfigurationChanged(configCopy); 14817 } 14818 } catch (Exception e) { 14819 } 14820 } 14821 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14822 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14823 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14824 | Intent.FLAG_RECEIVER_FOREGROUND); 14825 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14826 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14827 Process.SYSTEM_UID, UserHandle.USER_ALL); 14828 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14829 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14830 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14831 broadcastIntentLocked(null, null, intent, 14832 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14833 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14834 } 14835 } 14836 } 14837 14838 boolean kept = true; 14839 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14840 // mainStack is null during startup. 14841 if (mainStack != null) { 14842 if (changes != 0 && starting == null) { 14843 // If the configuration changed, and the caller is not already 14844 // in the process of starting an activity, then find the top 14845 // activity to check if its configuration needs to change. 14846 starting = mainStack.topRunningActivityLocked(null); 14847 } 14848 14849 if (starting != null) { 14850 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14851 // And we need to make sure at this point that all other activities 14852 // are made visible with the correct configuration. 14853 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14854 } 14855 } 14856 14857 if (values != null && mWindowManager != null) { 14858 mWindowManager.setNewConfiguration(mConfiguration); 14859 } 14860 14861 return kept; 14862 } 14863 14864 /** 14865 * Decide based on the configuration whether we should shouw the ANR, 14866 * crash, etc dialogs. The idea is that if there is no affordnace to 14867 * press the on-screen buttons, we shouldn't show the dialog. 14868 * 14869 * A thought: SystemUI might also want to get told about this, the Power 14870 * dialog / global actions also might want different behaviors. 14871 */ 14872 private static final boolean shouldShowDialogs(Configuration config) { 14873 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14874 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14875 } 14876 14877 /** 14878 * Save the locale. You must be inside a synchronized (this) block. 14879 */ 14880 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14881 if(isDiff) { 14882 SystemProperties.set("user.language", l.getLanguage()); 14883 SystemProperties.set("user.region", l.getCountry()); 14884 } 14885 14886 if(isPersist) { 14887 SystemProperties.set("persist.sys.language", l.getLanguage()); 14888 SystemProperties.set("persist.sys.country", l.getCountry()); 14889 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14890 } 14891 } 14892 14893 @Override 14894 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14895 ActivityRecord srec = ActivityRecord.forToken(token); 14896 return srec != null && srec.task.affinity != null && 14897 srec.task.affinity.equals(destAffinity); 14898 } 14899 14900 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14901 Intent resultData) { 14902 14903 synchronized (this) { 14904 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14905 if (stack != null) { 14906 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14907 } 14908 return false; 14909 } 14910 } 14911 14912 public int getLaunchedFromUid(IBinder activityToken) { 14913 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14914 if (srec == null) { 14915 return -1; 14916 } 14917 return srec.launchedFromUid; 14918 } 14919 14920 public String getLaunchedFromPackage(IBinder activityToken) { 14921 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14922 if (srec == null) { 14923 return null; 14924 } 14925 return srec.launchedFromPackage; 14926 } 14927 14928 // ========================================================= 14929 // LIFETIME MANAGEMENT 14930 // ========================================================= 14931 14932 // Returns which broadcast queue the app is the current [or imminent] receiver 14933 // on, or 'null' if the app is not an active broadcast recipient. 14934 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14935 BroadcastRecord r = app.curReceiver; 14936 if (r != null) { 14937 return r.queue; 14938 } 14939 14940 // It's not the current receiver, but it might be starting up to become one 14941 synchronized (this) { 14942 for (BroadcastQueue queue : mBroadcastQueues) { 14943 r = queue.mPendingBroadcast; 14944 if (r != null && r.curApp == app) { 14945 // found it; report which queue it's in 14946 return queue; 14947 } 14948 } 14949 } 14950 14951 return null; 14952 } 14953 14954 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14955 boolean doingAll, long now) { 14956 if (mAdjSeq == app.adjSeq) { 14957 // This adjustment has already been computed. 14958 return app.curRawAdj; 14959 } 14960 14961 if (app.thread == null) { 14962 app.adjSeq = mAdjSeq; 14963 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14964 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14965 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14966 } 14967 14968 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14969 app.adjSource = null; 14970 app.adjTarget = null; 14971 app.empty = false; 14972 app.cached = false; 14973 14974 final int activitiesSize = app.activities.size(); 14975 14976 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14977 // The max adjustment doesn't allow this app to be anything 14978 // below foreground, so it is not worth doing work for it. 14979 app.adjType = "fixed"; 14980 app.adjSeq = mAdjSeq; 14981 app.curRawAdj = app.maxAdj; 14982 app.foregroundActivities = false; 14983 app.keeping = true; 14984 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14985 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14986 // System processes can do UI, and when they do we want to have 14987 // them trim their memory after the user leaves the UI. To 14988 // facilitate this, here we need to determine whether or not it 14989 // is currently showing UI. 14990 app.systemNoUi = true; 14991 if (app == TOP_APP) { 14992 app.systemNoUi = false; 14993 } else if (activitiesSize > 0) { 14994 for (int j = 0; j < activitiesSize; j++) { 14995 final ActivityRecord r = app.activities.get(j); 14996 if (r.visible) { 14997 app.systemNoUi = false; 14998 } 14999 } 15000 } 15001 if (!app.systemNoUi) { 15002 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15003 } 15004 return (app.curAdj=app.maxAdj); 15005 } 15006 15007 app.keeping = false; 15008 app.systemNoUi = false; 15009 15010 // Determine the importance of the process, starting with most 15011 // important to least, and assign an appropriate OOM adjustment. 15012 int adj; 15013 int schedGroup; 15014 int procState; 15015 boolean foregroundActivities = false; 15016 BroadcastQueue queue; 15017 if (app == TOP_APP) { 15018 // The last app on the list is the foreground app. 15019 adj = ProcessList.FOREGROUND_APP_ADJ; 15020 schedGroup = Process.THREAD_GROUP_DEFAULT; 15021 app.adjType = "top-activity"; 15022 foregroundActivities = true; 15023 procState = ActivityManager.PROCESS_STATE_TOP; 15024 } else if (app.instrumentationClass != null) { 15025 // Don't want to kill running instrumentation. 15026 adj = ProcessList.FOREGROUND_APP_ADJ; 15027 schedGroup = Process.THREAD_GROUP_DEFAULT; 15028 app.adjType = "instrumentation"; 15029 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15030 } else if ((queue = isReceivingBroadcast(app)) != null) { 15031 // An app that is currently receiving a broadcast also 15032 // counts as being in the foreground for OOM killer purposes. 15033 // It's placed in a sched group based on the nature of the 15034 // broadcast as reflected by which queue it's active in. 15035 adj = ProcessList.FOREGROUND_APP_ADJ; 15036 schedGroup = (queue == mFgBroadcastQueue) 15037 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15038 app.adjType = "broadcast"; 15039 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15040 } else if (app.executingServices.size() > 0) { 15041 // An app that is currently executing a service callback also 15042 // counts as being in the foreground. 15043 adj = ProcessList.FOREGROUND_APP_ADJ; 15044 schedGroup = app.execServicesFg ? 15045 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15046 app.adjType = "exec-service"; 15047 procState = ActivityManager.PROCESS_STATE_SERVICE; 15048 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15049 } else { 15050 // As far as we know the process is empty. We may change our mind later. 15051 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15052 // At this point we don't actually know the adjustment. Use the cached adj 15053 // value that the caller wants us to. 15054 adj = cachedAdj; 15055 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15056 app.cached = true; 15057 app.empty = true; 15058 app.adjType = "cch-empty"; 15059 } 15060 15061 // Examine all activities if not already foreground. 15062 if (!foregroundActivities && activitiesSize > 0) { 15063 for (int j = 0; j < activitiesSize; j++) { 15064 final ActivityRecord r = app.activities.get(j); 15065 if (r.app != app) { 15066 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15067 + app + "?!?"); 15068 continue; 15069 } 15070 if (r.visible) { 15071 // App has a visible activity; only upgrade adjustment. 15072 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15073 adj = ProcessList.VISIBLE_APP_ADJ; 15074 app.adjType = "visible"; 15075 } 15076 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15077 procState = ActivityManager.PROCESS_STATE_TOP; 15078 } 15079 schedGroup = Process.THREAD_GROUP_DEFAULT; 15080 app.cached = false; 15081 app.empty = false; 15082 foregroundActivities = true; 15083 break; 15084 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15085 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15086 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15087 app.adjType = "pausing"; 15088 } 15089 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15090 procState = ActivityManager.PROCESS_STATE_TOP; 15091 } 15092 schedGroup = Process.THREAD_GROUP_DEFAULT; 15093 app.cached = false; 15094 app.empty = false; 15095 foregroundActivities = true; 15096 } else if (r.state == ActivityState.STOPPING) { 15097 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15098 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15099 app.adjType = "stopping"; 15100 } 15101 // For the process state, we will at this point consider the 15102 // process to be cached. It will be cached either as an activity 15103 // or empty depending on whether the activity is finishing. We do 15104 // this so that we can treat the process as cached for purposes of 15105 // memory trimming (determing current memory level, trim command to 15106 // send to process) since there can be an arbitrary number of stopping 15107 // processes and they should soon all go into the cached state. 15108 if (!r.finishing) { 15109 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15110 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15111 } 15112 } 15113 app.cached = false; 15114 app.empty = false; 15115 foregroundActivities = true; 15116 } else { 15117 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15118 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15119 app.adjType = "cch-act"; 15120 } 15121 } 15122 } 15123 } 15124 15125 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15126 if (app.foregroundServices) { 15127 // The user is aware of this app, so make it visible. 15128 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15129 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15130 app.cached = false; 15131 app.adjType = "fg-service"; 15132 schedGroup = Process.THREAD_GROUP_DEFAULT; 15133 } else if (app.forcingToForeground != null) { 15134 // The user is aware of this app, so make it visible. 15135 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15136 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15137 app.cached = false; 15138 app.adjType = "force-fg"; 15139 app.adjSource = app.forcingToForeground; 15140 schedGroup = Process.THREAD_GROUP_DEFAULT; 15141 } 15142 } 15143 15144 if (app == mHeavyWeightProcess) { 15145 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15146 // We don't want to kill the current heavy-weight process. 15147 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15148 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15149 app.cached = false; 15150 app.adjType = "heavy"; 15151 } 15152 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15153 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15154 } 15155 } 15156 15157 if (app == mHomeProcess) { 15158 if (adj > ProcessList.HOME_APP_ADJ) { 15159 // This process is hosting what we currently consider to be the 15160 // home app, so we don't want to let it go into the background. 15161 adj = ProcessList.HOME_APP_ADJ; 15162 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15163 app.cached = false; 15164 app.adjType = "home"; 15165 } 15166 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15167 procState = ActivityManager.PROCESS_STATE_HOME; 15168 } 15169 } 15170 15171 if (app == mPreviousProcess && app.activities.size() > 0) { 15172 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15173 // This was the previous process that showed UI to the user. 15174 // We want to try to keep it around more aggressively, to give 15175 // a good experience around switching between two apps. 15176 adj = ProcessList.PREVIOUS_APP_ADJ; 15177 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15178 app.cached = false; 15179 app.adjType = "previous"; 15180 } 15181 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15182 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15183 } 15184 } 15185 15186 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15187 + " reason=" + app.adjType); 15188 15189 // By default, we use the computed adjustment. It may be changed if 15190 // there are applications dependent on our services or providers, but 15191 // this gives us a baseline and makes sure we don't get into an 15192 // infinite recursion. 15193 app.adjSeq = mAdjSeq; 15194 app.curRawAdj = adj; 15195 app.hasStartedServices = false; 15196 15197 if (mBackupTarget != null && app == mBackupTarget.app) { 15198 // If possible we want to avoid killing apps while they're being backed up 15199 if (adj > ProcessList.BACKUP_APP_ADJ) { 15200 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15201 adj = ProcessList.BACKUP_APP_ADJ; 15202 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15203 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15204 } 15205 app.adjType = "backup"; 15206 app.cached = false; 15207 } 15208 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15209 procState = ActivityManager.PROCESS_STATE_BACKUP; 15210 } 15211 } 15212 15213 boolean mayBeTop = false; 15214 15215 for (int is = app.services.size()-1; 15216 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15217 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15218 || procState > ActivityManager.PROCESS_STATE_TOP); 15219 is--) { 15220 ServiceRecord s = app.services.valueAt(is); 15221 if (s.startRequested) { 15222 app.hasStartedServices = true; 15223 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15224 procState = ActivityManager.PROCESS_STATE_SERVICE; 15225 } 15226 if (app.hasShownUi && app != mHomeProcess) { 15227 // If this process has shown some UI, let it immediately 15228 // go to the LRU list because it may be pretty heavy with 15229 // UI stuff. We'll tag it with a label just to help 15230 // debug and understand what is going on. 15231 if (adj > ProcessList.SERVICE_ADJ) { 15232 app.adjType = "cch-started-ui-services"; 15233 } 15234 } else { 15235 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15236 // This service has seen some activity within 15237 // recent memory, so we will keep its process ahead 15238 // of the background processes. 15239 if (adj > ProcessList.SERVICE_ADJ) { 15240 adj = ProcessList.SERVICE_ADJ; 15241 app.adjType = "started-services"; 15242 app.cached = false; 15243 } 15244 } 15245 // If we have let the service slide into the background 15246 // state, still have some text describing what it is doing 15247 // even though the service no longer has an impact. 15248 if (adj > ProcessList.SERVICE_ADJ) { 15249 app.adjType = "cch-started-services"; 15250 } 15251 } 15252 // Don't kill this process because it is doing work; it 15253 // has said it is doing work. 15254 app.keeping = true; 15255 } 15256 for (int conni = s.connections.size()-1; 15257 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15258 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15259 || procState > ActivityManager.PROCESS_STATE_TOP); 15260 conni--) { 15261 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15262 for (int i = 0; 15263 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15264 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15265 || procState > ActivityManager.PROCESS_STATE_TOP); 15266 i++) { 15267 // XXX should compute this based on the max of 15268 // all connected clients. 15269 ConnectionRecord cr = clist.get(i); 15270 if (cr.binding.client == app) { 15271 // Binding to ourself is not interesting. 15272 continue; 15273 } 15274 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15275 ProcessRecord client = cr.binding.client; 15276 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15277 TOP_APP, doingAll, now); 15278 int clientProcState = client.curProcState; 15279 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15280 // If the other app is cached for any reason, for purposes here 15281 // we are going to consider it empty. The specific cached state 15282 // doesn't propagate except under certain conditions. 15283 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15284 } 15285 String adjType = null; 15286 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15287 // Not doing bind OOM management, so treat 15288 // this guy more like a started service. 15289 if (app.hasShownUi && app != mHomeProcess) { 15290 // If this process has shown some UI, let it immediately 15291 // go to the LRU list because it may be pretty heavy with 15292 // UI stuff. We'll tag it with a label just to help 15293 // debug and understand what is going on. 15294 if (adj > clientAdj) { 15295 adjType = "cch-bound-ui-services"; 15296 } 15297 app.cached = false; 15298 clientAdj = adj; 15299 clientProcState = procState; 15300 } else { 15301 if (now >= (s.lastActivity 15302 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15303 // This service has not seen activity within 15304 // recent memory, so allow it to drop to the 15305 // LRU list if there is no other reason to keep 15306 // it around. We'll also tag it with a label just 15307 // to help debug and undertand what is going on. 15308 if (adj > clientAdj) { 15309 adjType = "cch-bound-services"; 15310 } 15311 clientAdj = adj; 15312 } 15313 } 15314 } 15315 if (adj > clientAdj) { 15316 // If this process has recently shown UI, and 15317 // the process that is binding to it is less 15318 // important than being visible, then we don't 15319 // care about the binding as much as we care 15320 // about letting this process get into the LRU 15321 // list to be killed and restarted if needed for 15322 // memory. 15323 if (app.hasShownUi && app != mHomeProcess 15324 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15325 adjType = "cch-bound-ui-services"; 15326 } else { 15327 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15328 |Context.BIND_IMPORTANT)) != 0) { 15329 adj = clientAdj; 15330 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15331 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15332 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15333 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15334 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15335 adj = clientAdj; 15336 } else { 15337 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15338 adj = ProcessList.VISIBLE_APP_ADJ; 15339 } 15340 } 15341 if (!client.cached) { 15342 app.cached = false; 15343 } 15344 if (client.keeping) { 15345 app.keeping = true; 15346 } 15347 adjType = "service"; 15348 } 15349 } 15350 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15351 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15352 schedGroup = Process.THREAD_GROUP_DEFAULT; 15353 } 15354 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15355 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15356 // Special handling of clients who are in the top state. 15357 // We *may* want to consider this process to be in the 15358 // top state as well, but only if there is not another 15359 // reason for it to be running. Being on the top is a 15360 // special state, meaning you are specifically running 15361 // for the current top app. If the process is already 15362 // running in the background for some other reason, it 15363 // is more important to continue considering it to be 15364 // in the background state. 15365 mayBeTop = true; 15366 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15367 } else { 15368 // Special handling for above-top states (persistent 15369 // processes). These should not bring the current process 15370 // into the top state, since they are not on top. Instead 15371 // give them the best state after that. 15372 clientProcState = 15373 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15374 } 15375 } 15376 } else { 15377 if (clientProcState < 15378 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15379 clientProcState = 15380 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15381 } 15382 } 15383 if (procState > clientProcState) { 15384 procState = clientProcState; 15385 } 15386 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15387 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15388 app.pendingUiClean = true; 15389 } 15390 if (adjType != null) { 15391 app.adjType = adjType; 15392 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15393 .REASON_SERVICE_IN_USE; 15394 app.adjSource = cr.binding.client; 15395 app.adjSourceOom = clientAdj; 15396 app.adjTarget = s.name; 15397 } 15398 } 15399 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15400 app.treatLikeActivity = true; 15401 } 15402 final ActivityRecord a = cr.activity; 15403 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15404 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15405 (a.visible || a.state == ActivityState.RESUMED 15406 || a.state == ActivityState.PAUSING)) { 15407 adj = ProcessList.FOREGROUND_APP_ADJ; 15408 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15409 schedGroup = Process.THREAD_GROUP_DEFAULT; 15410 } 15411 app.cached = false; 15412 app.adjType = "service"; 15413 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15414 .REASON_SERVICE_IN_USE; 15415 app.adjSource = a; 15416 app.adjSourceOom = adj; 15417 app.adjTarget = s.name; 15418 } 15419 } 15420 } 15421 } 15422 } 15423 15424 for (int provi = app.pubProviders.size()-1; 15425 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15426 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15427 || procState > ActivityManager.PROCESS_STATE_TOP); 15428 provi--) { 15429 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15430 for (int i = cpr.connections.size()-1; 15431 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15432 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15433 || procState > ActivityManager.PROCESS_STATE_TOP); 15434 i--) { 15435 ContentProviderConnection conn = cpr.connections.get(i); 15436 ProcessRecord client = conn.client; 15437 if (client == app) { 15438 // Being our own client is not interesting. 15439 continue; 15440 } 15441 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15442 int clientProcState = client.curProcState; 15443 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15444 // If the other app is cached for any reason, for purposes here 15445 // we are going to consider it empty. 15446 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15447 } 15448 if (adj > clientAdj) { 15449 if (app.hasShownUi && app != mHomeProcess 15450 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15451 app.adjType = "cch-ui-provider"; 15452 } else { 15453 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15454 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15455 app.adjType = "provider"; 15456 } 15457 app.cached &= client.cached; 15458 app.keeping |= client.keeping; 15459 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15460 .REASON_PROVIDER_IN_USE; 15461 app.adjSource = client; 15462 app.adjSourceOom = clientAdj; 15463 app.adjTarget = cpr.name; 15464 } 15465 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15466 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15467 // Special handling of clients who are in the top state. 15468 // We *may* want to consider this process to be in the 15469 // top state as well, but only if there is not another 15470 // reason for it to be running. Being on the top is a 15471 // special state, meaning you are specifically running 15472 // for the current top app. If the process is already 15473 // running in the background for some other reason, it 15474 // is more important to continue considering it to be 15475 // in the background state. 15476 mayBeTop = true; 15477 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15478 } else { 15479 // Special handling for above-top states (persistent 15480 // processes). These should not bring the current process 15481 // into the top state, since they are not on top. Instead 15482 // give them the best state after that. 15483 clientProcState = 15484 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15485 } 15486 } 15487 if (procState > clientProcState) { 15488 procState = clientProcState; 15489 } 15490 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15491 schedGroup = Process.THREAD_GROUP_DEFAULT; 15492 } 15493 } 15494 // If the provider has external (non-framework) process 15495 // dependencies, ensure that its adjustment is at least 15496 // FOREGROUND_APP_ADJ. 15497 if (cpr.hasExternalProcessHandles()) { 15498 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15499 adj = ProcessList.FOREGROUND_APP_ADJ; 15500 schedGroup = Process.THREAD_GROUP_DEFAULT; 15501 app.cached = false; 15502 app.keeping = true; 15503 app.adjType = "provider"; 15504 app.adjTarget = cpr.name; 15505 } 15506 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15507 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15508 } 15509 } 15510 } 15511 15512 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15513 // A client of one of our services or providers is in the top state. We 15514 // *may* want to be in the top state, but not if we are already running in 15515 // the background for some other reason. For the decision here, we are going 15516 // to pick out a few specific states that we want to remain in when a client 15517 // is top (states that tend to be longer-term) and otherwise allow it to go 15518 // to the top state. 15519 switch (procState) { 15520 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15521 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15522 case ActivityManager.PROCESS_STATE_SERVICE: 15523 // These all are longer-term states, so pull them up to the top 15524 // of the background states, but not all the way to the top state. 15525 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15526 break; 15527 default: 15528 // Otherwise, top is a better choice, so take it. 15529 procState = ActivityManager.PROCESS_STATE_TOP; 15530 break; 15531 } 15532 } 15533 15534 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15535 if (app.hasClientActivities) { 15536 // This is a cached process, but with client activities. Mark it so. 15537 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15538 app.adjType = "cch-client-act"; 15539 } else if (app.treatLikeActivity) { 15540 // This is a cached process, but somebody wants us to treat it like it has 15541 // an activity, okay! 15542 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15543 app.adjType = "cch-as-act"; 15544 } 15545 } 15546 15547 if (adj == ProcessList.SERVICE_ADJ) { 15548 if (doingAll) { 15549 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15550 mNewNumServiceProcs++; 15551 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15552 if (!app.serviceb) { 15553 // This service isn't far enough down on the LRU list to 15554 // normally be a B service, but if we are low on RAM and it 15555 // is large we want to force it down since we would prefer to 15556 // keep launcher over it. 15557 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15558 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15559 app.serviceHighRam = true; 15560 app.serviceb = true; 15561 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15562 } else { 15563 mNewNumAServiceProcs++; 15564 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15565 } 15566 } else { 15567 app.serviceHighRam = false; 15568 } 15569 } 15570 if (app.serviceb) { 15571 adj = ProcessList.SERVICE_B_ADJ; 15572 } 15573 } 15574 15575 app.curRawAdj = adj; 15576 15577 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15578 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15579 if (adj > app.maxAdj) { 15580 adj = app.maxAdj; 15581 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15582 schedGroup = Process.THREAD_GROUP_DEFAULT; 15583 } 15584 } 15585 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15586 app.keeping = true; 15587 } 15588 15589 // Do final modification to adj. Everything we do between here and applying 15590 // the final setAdj must be done in this function, because we will also use 15591 // it when computing the final cached adj later. Note that we don't need to 15592 // worry about this for max adj above, since max adj will always be used to 15593 // keep it out of the cached vaues. 15594 app.curAdj = app.modifyRawOomAdj(adj); 15595 app.curSchedGroup = schedGroup; 15596 app.curProcState = procState; 15597 app.foregroundActivities = foregroundActivities; 15598 15599 return app.curRawAdj; 15600 } 15601 15602 /** 15603 * Schedule PSS collection of a process. 15604 */ 15605 void requestPssLocked(ProcessRecord proc, int procState) { 15606 if (mPendingPssProcesses.contains(proc)) { 15607 return; 15608 } 15609 if (mPendingPssProcesses.size() == 0) { 15610 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15611 } 15612 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15613 proc.pssProcState = procState; 15614 mPendingPssProcesses.add(proc); 15615 } 15616 15617 /** 15618 * Schedule PSS collection of all processes. 15619 */ 15620 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15621 if (!always) { 15622 if (now < (mLastFullPssTime + 15623 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15624 return; 15625 } 15626 } 15627 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15628 mLastFullPssTime = now; 15629 mFullPssPending = true; 15630 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15631 mPendingPssProcesses.clear(); 15632 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15633 ProcessRecord app = mLruProcesses.get(i); 15634 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15635 app.pssProcState = app.setProcState; 15636 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15637 isSleeping(), now); 15638 mPendingPssProcesses.add(app); 15639 } 15640 } 15641 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15642 } 15643 15644 /** 15645 * Ask a given process to GC right now. 15646 */ 15647 final void performAppGcLocked(ProcessRecord app) { 15648 try { 15649 app.lastRequestedGc = SystemClock.uptimeMillis(); 15650 if (app.thread != null) { 15651 if (app.reportLowMemory) { 15652 app.reportLowMemory = false; 15653 app.thread.scheduleLowMemory(); 15654 } else { 15655 app.thread.processInBackground(); 15656 } 15657 } 15658 } catch (Exception e) { 15659 // whatever. 15660 } 15661 } 15662 15663 /** 15664 * Returns true if things are idle enough to perform GCs. 15665 */ 15666 private final boolean canGcNowLocked() { 15667 boolean processingBroadcasts = false; 15668 for (BroadcastQueue q : mBroadcastQueues) { 15669 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15670 processingBroadcasts = true; 15671 } 15672 } 15673 return !processingBroadcasts 15674 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15675 } 15676 15677 /** 15678 * Perform GCs on all processes that are waiting for it, but only 15679 * if things are idle. 15680 */ 15681 final void performAppGcsLocked() { 15682 final int N = mProcessesToGc.size(); 15683 if (N <= 0) { 15684 return; 15685 } 15686 if (canGcNowLocked()) { 15687 while (mProcessesToGc.size() > 0) { 15688 ProcessRecord proc = mProcessesToGc.remove(0); 15689 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15690 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15691 <= SystemClock.uptimeMillis()) { 15692 // To avoid spamming the system, we will GC processes one 15693 // at a time, waiting a few seconds between each. 15694 performAppGcLocked(proc); 15695 scheduleAppGcsLocked(); 15696 return; 15697 } else { 15698 // It hasn't been long enough since we last GCed this 15699 // process... put it in the list to wait for its time. 15700 addProcessToGcListLocked(proc); 15701 break; 15702 } 15703 } 15704 } 15705 15706 scheduleAppGcsLocked(); 15707 } 15708 } 15709 15710 /** 15711 * If all looks good, perform GCs on all processes waiting for them. 15712 */ 15713 final void performAppGcsIfAppropriateLocked() { 15714 if (canGcNowLocked()) { 15715 performAppGcsLocked(); 15716 return; 15717 } 15718 // Still not idle, wait some more. 15719 scheduleAppGcsLocked(); 15720 } 15721 15722 /** 15723 * Schedule the execution of all pending app GCs. 15724 */ 15725 final void scheduleAppGcsLocked() { 15726 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15727 15728 if (mProcessesToGc.size() > 0) { 15729 // Schedule a GC for the time to the next process. 15730 ProcessRecord proc = mProcessesToGc.get(0); 15731 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15732 15733 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15734 long now = SystemClock.uptimeMillis(); 15735 if (when < (now+GC_TIMEOUT)) { 15736 when = now + GC_TIMEOUT; 15737 } 15738 mHandler.sendMessageAtTime(msg, when); 15739 } 15740 } 15741 15742 /** 15743 * Add a process to the array of processes waiting to be GCed. Keeps the 15744 * list in sorted order by the last GC time. The process can't already be 15745 * on the list. 15746 */ 15747 final void addProcessToGcListLocked(ProcessRecord proc) { 15748 boolean added = false; 15749 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15750 if (mProcessesToGc.get(i).lastRequestedGc < 15751 proc.lastRequestedGc) { 15752 added = true; 15753 mProcessesToGc.add(i+1, proc); 15754 break; 15755 } 15756 } 15757 if (!added) { 15758 mProcessesToGc.add(0, proc); 15759 } 15760 } 15761 15762 /** 15763 * Set up to ask a process to GC itself. This will either do it 15764 * immediately, or put it on the list of processes to gc the next 15765 * time things are idle. 15766 */ 15767 final void scheduleAppGcLocked(ProcessRecord app) { 15768 long now = SystemClock.uptimeMillis(); 15769 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15770 return; 15771 } 15772 if (!mProcessesToGc.contains(app)) { 15773 addProcessToGcListLocked(app); 15774 scheduleAppGcsLocked(); 15775 } 15776 } 15777 15778 final void checkExcessivePowerUsageLocked(boolean doKills) { 15779 updateCpuStatsNow(); 15780 15781 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15782 boolean doWakeKills = doKills; 15783 boolean doCpuKills = doKills; 15784 if (mLastPowerCheckRealtime == 0) { 15785 doWakeKills = false; 15786 } 15787 if (mLastPowerCheckUptime == 0) { 15788 doCpuKills = false; 15789 } 15790 if (stats.isScreenOn()) { 15791 doWakeKills = false; 15792 } 15793 final long curRealtime = SystemClock.elapsedRealtime(); 15794 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15795 final long curUptime = SystemClock.uptimeMillis(); 15796 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15797 mLastPowerCheckRealtime = curRealtime; 15798 mLastPowerCheckUptime = curUptime; 15799 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15800 doWakeKills = false; 15801 } 15802 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15803 doCpuKills = false; 15804 } 15805 int i = mLruProcesses.size(); 15806 while (i > 0) { 15807 i--; 15808 ProcessRecord app = mLruProcesses.get(i); 15809 if (!app.keeping) { 15810 long wtime; 15811 synchronized (stats) { 15812 wtime = stats.getProcessWakeTime(app.info.uid, 15813 app.pid, curRealtime); 15814 } 15815 long wtimeUsed = wtime - app.lastWakeTime; 15816 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15817 if (DEBUG_POWER) { 15818 StringBuilder sb = new StringBuilder(128); 15819 sb.append("Wake for "); 15820 app.toShortString(sb); 15821 sb.append(": over "); 15822 TimeUtils.formatDuration(realtimeSince, sb); 15823 sb.append(" used "); 15824 TimeUtils.formatDuration(wtimeUsed, sb); 15825 sb.append(" ("); 15826 sb.append((wtimeUsed*100)/realtimeSince); 15827 sb.append("%)"); 15828 Slog.i(TAG, sb.toString()); 15829 sb.setLength(0); 15830 sb.append("CPU for "); 15831 app.toShortString(sb); 15832 sb.append(": over "); 15833 TimeUtils.formatDuration(uptimeSince, sb); 15834 sb.append(" used "); 15835 TimeUtils.formatDuration(cputimeUsed, sb); 15836 sb.append(" ("); 15837 sb.append((cputimeUsed*100)/uptimeSince); 15838 sb.append("%)"); 15839 Slog.i(TAG, sb.toString()); 15840 } 15841 // If a process has held a wake lock for more 15842 // than 50% of the time during this period, 15843 // that sounds bad. Kill! 15844 if (doWakeKills && realtimeSince > 0 15845 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15846 synchronized (stats) { 15847 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15848 realtimeSince, wtimeUsed); 15849 } 15850 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15851 + " during " + realtimeSince); 15852 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15853 } else if (doCpuKills && uptimeSince > 0 15854 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15855 synchronized (stats) { 15856 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15857 uptimeSince, cputimeUsed); 15858 } 15859 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15860 + " during " + uptimeSince); 15861 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15862 } else { 15863 app.lastWakeTime = wtime; 15864 app.lastCpuTime = app.curCpuTime; 15865 } 15866 } 15867 } 15868 } 15869 15870 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15871 ProcessRecord TOP_APP, boolean doingAll, long now) { 15872 boolean success = true; 15873 15874 if (app.curRawAdj != app.setRawAdj) { 15875 if (wasKeeping && !app.keeping) { 15876 // This app is no longer something we want to keep. Note 15877 // its current wake lock time to later know to kill it if 15878 // it is not behaving well. 15879 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15880 synchronized (stats) { 15881 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15882 app.pid, SystemClock.elapsedRealtime()); 15883 } 15884 app.lastCpuTime = app.curCpuTime; 15885 } 15886 15887 app.setRawAdj = app.curRawAdj; 15888 } 15889 15890 int changes = 0; 15891 15892 if (app.curAdj != app.setAdj) { 15893 ProcessList.setOomAdj(app.pid, app.curAdj); 15894 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15895 TAG, "Set " + app.pid + " " + app.processName + 15896 " adj " + app.curAdj + ": " + app.adjType); 15897 app.setAdj = app.curAdj; 15898 } 15899 15900 if (app.setSchedGroup != app.curSchedGroup) { 15901 app.setSchedGroup = app.curSchedGroup; 15902 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15903 "Setting process group of " + app.processName 15904 + " to " + app.curSchedGroup); 15905 if (app.waitingToKill != null && 15906 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15907 killUnneededProcessLocked(app, app.waitingToKill); 15908 success = false; 15909 } else { 15910 if (true) { 15911 long oldId = Binder.clearCallingIdentity(); 15912 try { 15913 Process.setProcessGroup(app.pid, app.curSchedGroup); 15914 } catch (Exception e) { 15915 Slog.w(TAG, "Failed setting process group of " + app.pid 15916 + " to " + app.curSchedGroup); 15917 e.printStackTrace(); 15918 } finally { 15919 Binder.restoreCallingIdentity(oldId); 15920 } 15921 } else { 15922 if (app.thread != null) { 15923 try { 15924 app.thread.setSchedulingGroup(app.curSchedGroup); 15925 } catch (RemoteException e) { 15926 } 15927 } 15928 } 15929 Process.setSwappiness(app.pid, 15930 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15931 } 15932 } 15933 if (app.repForegroundActivities != app.foregroundActivities) { 15934 app.repForegroundActivities = app.foregroundActivities; 15935 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15936 } 15937 if (app.repProcState != app.curProcState) { 15938 app.repProcState = app.curProcState; 15939 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15940 if (app.thread != null) { 15941 try { 15942 if (false) { 15943 //RuntimeException h = new RuntimeException("here"); 15944 Slog.i(TAG, "Sending new process state " + app.repProcState 15945 + " to " + app /*, h*/); 15946 } 15947 app.thread.setProcessState(app.repProcState); 15948 } catch (RemoteException e) { 15949 } 15950 } 15951 } 15952 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15953 app.setProcState)) { 15954 app.lastStateTime = now; 15955 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15956 isSleeping(), now); 15957 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15958 + ProcessList.makeProcStateString(app.setProcState) + " to " 15959 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15960 + (app.nextPssTime-now) + ": " + app); 15961 } else { 15962 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15963 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15964 requestPssLocked(app, app.setProcState); 15965 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15966 isSleeping(), now); 15967 } else if (false && DEBUG_PSS) { 15968 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15969 } 15970 } 15971 if (app.setProcState != app.curProcState) { 15972 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15973 "Proc state change of " + app.processName 15974 + " to " + app.curProcState); 15975 app.setProcState = app.curProcState; 15976 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15977 app.notCachedSinceIdle = false; 15978 } 15979 if (!doingAll) { 15980 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15981 } else { 15982 app.procStateChanged = true; 15983 } 15984 } 15985 15986 if (changes != 0) { 15987 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15988 int i = mPendingProcessChanges.size()-1; 15989 ProcessChangeItem item = null; 15990 while (i >= 0) { 15991 item = mPendingProcessChanges.get(i); 15992 if (item.pid == app.pid) { 15993 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15994 break; 15995 } 15996 i--; 15997 } 15998 if (i < 0) { 15999 // No existing item in pending changes; need a new one. 16000 final int NA = mAvailProcessChanges.size(); 16001 if (NA > 0) { 16002 item = mAvailProcessChanges.remove(NA-1); 16003 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16004 } else { 16005 item = new ProcessChangeItem(); 16006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16007 } 16008 item.changes = 0; 16009 item.pid = app.pid; 16010 item.uid = app.info.uid; 16011 if (mPendingProcessChanges.size() == 0) { 16012 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16013 "*** Enqueueing dispatch processes changed!"); 16014 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16015 } 16016 mPendingProcessChanges.add(item); 16017 } 16018 item.changes |= changes; 16019 item.processState = app.repProcState; 16020 item.foregroundActivities = app.repForegroundActivities; 16021 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16022 + Integer.toHexString(System.identityHashCode(item)) 16023 + " " + app.toShortString() + ": changes=" + item.changes 16024 + " procState=" + item.processState 16025 + " foreground=" + item.foregroundActivities 16026 + " type=" + app.adjType + " source=" + app.adjSource 16027 + " target=" + app.adjTarget); 16028 } 16029 16030 return success; 16031 } 16032 16033 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16034 if (proc.thread != null && proc.baseProcessTracker != null) { 16035 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16036 } 16037 } 16038 16039 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16040 ProcessRecord TOP_APP, boolean doingAll, long now) { 16041 if (app.thread == null) { 16042 return false; 16043 } 16044 16045 final boolean wasKeeping = app.keeping; 16046 16047 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16048 16049 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16050 } 16051 16052 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16053 boolean oomAdj) { 16054 if (isForeground != proc.foregroundServices) { 16055 proc.foregroundServices = isForeground; 16056 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16057 proc.info.uid); 16058 if (isForeground) { 16059 if (curProcs == null) { 16060 curProcs = new ArrayList<ProcessRecord>(); 16061 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16062 } 16063 if (!curProcs.contains(proc)) { 16064 curProcs.add(proc); 16065 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16066 proc.info.packageName, proc.info.uid); 16067 } 16068 } else { 16069 if (curProcs != null) { 16070 if (curProcs.remove(proc)) { 16071 mBatteryStatsService.noteEvent( 16072 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16073 proc.info.packageName, proc.info.uid); 16074 if (curProcs.size() <= 0) { 16075 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16076 } 16077 } 16078 } 16079 } 16080 if (oomAdj) { 16081 updateOomAdjLocked(); 16082 } 16083 } 16084 } 16085 16086 private final ActivityRecord resumedAppLocked() { 16087 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16088 String pkg; 16089 int uid; 16090 if (act != null && !act.sleeping) { 16091 pkg = act.packageName; 16092 uid = act.info.applicationInfo.uid; 16093 } else { 16094 pkg = null; 16095 uid = -1; 16096 } 16097 // Has the UID or resumed package name changed? 16098 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16099 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16100 if (mCurResumedPackage != null) { 16101 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16102 mCurResumedPackage, mCurResumedUid); 16103 } 16104 mCurResumedPackage = pkg; 16105 mCurResumedUid = uid; 16106 if (mCurResumedPackage != null) { 16107 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16108 mCurResumedPackage, mCurResumedUid); 16109 } 16110 } 16111 return act; 16112 } 16113 16114 final boolean updateOomAdjLocked(ProcessRecord app) { 16115 final ActivityRecord TOP_ACT = resumedAppLocked(); 16116 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16117 final boolean wasCached = app.cached; 16118 16119 mAdjSeq++; 16120 16121 // This is the desired cached adjusment we want to tell it to use. 16122 // If our app is currently cached, we know it, and that is it. Otherwise, 16123 // we don't know it yet, and it needs to now be cached we will then 16124 // need to do a complete oom adj. 16125 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16126 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16127 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16128 SystemClock.uptimeMillis()); 16129 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16130 // Changed to/from cached state, so apps after it in the LRU 16131 // list may also be changed. 16132 updateOomAdjLocked(); 16133 } 16134 return success; 16135 } 16136 16137 final void updateOomAdjLocked() { 16138 final ActivityRecord TOP_ACT = resumedAppLocked(); 16139 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16140 final long now = SystemClock.uptimeMillis(); 16141 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16142 final int N = mLruProcesses.size(); 16143 16144 if (false) { 16145 RuntimeException e = new RuntimeException(); 16146 e.fillInStackTrace(); 16147 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16148 } 16149 16150 mAdjSeq++; 16151 mNewNumServiceProcs = 0; 16152 mNewNumAServiceProcs = 0; 16153 16154 final int emptyProcessLimit; 16155 final int cachedProcessLimit; 16156 if (mProcessLimit <= 0) { 16157 emptyProcessLimit = cachedProcessLimit = 0; 16158 } else if (mProcessLimit == 1) { 16159 emptyProcessLimit = 1; 16160 cachedProcessLimit = 0; 16161 } else { 16162 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16163 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16164 } 16165 16166 // Let's determine how many processes we have running vs. 16167 // how many slots we have for background processes; we may want 16168 // to put multiple processes in a slot of there are enough of 16169 // them. 16170 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16171 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16172 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16173 if (numEmptyProcs > cachedProcessLimit) { 16174 // If there are more empty processes than our limit on cached 16175 // processes, then use the cached process limit for the factor. 16176 // This ensures that the really old empty processes get pushed 16177 // down to the bottom, so if we are running low on memory we will 16178 // have a better chance at keeping around more cached processes 16179 // instead of a gazillion empty processes. 16180 numEmptyProcs = cachedProcessLimit; 16181 } 16182 int emptyFactor = numEmptyProcs/numSlots; 16183 if (emptyFactor < 1) emptyFactor = 1; 16184 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16185 if (cachedFactor < 1) cachedFactor = 1; 16186 int stepCached = 0; 16187 int stepEmpty = 0; 16188 int numCached = 0; 16189 int numEmpty = 0; 16190 int numTrimming = 0; 16191 16192 mNumNonCachedProcs = 0; 16193 mNumCachedHiddenProcs = 0; 16194 16195 // First update the OOM adjustment for each of the 16196 // application processes based on their current state. 16197 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16198 int nextCachedAdj = curCachedAdj+1; 16199 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16200 int nextEmptyAdj = curEmptyAdj+2; 16201 for (int i=N-1; i>=0; i--) { 16202 ProcessRecord app = mLruProcesses.get(i); 16203 if (!app.killedByAm && app.thread != null) { 16204 app.procStateChanged = false; 16205 final boolean wasKeeping = app.keeping; 16206 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16207 16208 // If we haven't yet assigned the final cached adj 16209 // to the process, do that now. 16210 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16211 switch (app.curProcState) { 16212 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16213 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16214 // This process is a cached process holding activities... 16215 // assign it the next cached value for that type, and then 16216 // step that cached level. 16217 app.curRawAdj = curCachedAdj; 16218 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16219 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16220 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16221 + ")"); 16222 if (curCachedAdj != nextCachedAdj) { 16223 stepCached++; 16224 if (stepCached >= cachedFactor) { 16225 stepCached = 0; 16226 curCachedAdj = nextCachedAdj; 16227 nextCachedAdj += 2; 16228 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16229 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16230 } 16231 } 16232 } 16233 break; 16234 default: 16235 // For everything else, assign next empty cached process 16236 // level and bump that up. Note that this means that 16237 // long-running services that have dropped down to the 16238 // cached level will be treated as empty (since their process 16239 // state is still as a service), which is what we want. 16240 app.curRawAdj = curEmptyAdj; 16241 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16242 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16243 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16244 + ")"); 16245 if (curEmptyAdj != nextEmptyAdj) { 16246 stepEmpty++; 16247 if (stepEmpty >= emptyFactor) { 16248 stepEmpty = 0; 16249 curEmptyAdj = nextEmptyAdj; 16250 nextEmptyAdj += 2; 16251 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16252 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16253 } 16254 } 16255 } 16256 break; 16257 } 16258 } 16259 16260 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16261 16262 // Count the number of process types. 16263 switch (app.curProcState) { 16264 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16265 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16266 mNumCachedHiddenProcs++; 16267 numCached++; 16268 if (numCached > cachedProcessLimit) { 16269 killUnneededProcessLocked(app, "cached #" + numCached); 16270 } 16271 break; 16272 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16273 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16274 && app.lastActivityTime < oldTime) { 16275 killUnneededProcessLocked(app, "empty for " 16276 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16277 / 1000) + "s"); 16278 } else { 16279 numEmpty++; 16280 if (numEmpty > emptyProcessLimit) { 16281 killUnneededProcessLocked(app, "empty #" + numEmpty); 16282 } 16283 } 16284 break; 16285 default: 16286 mNumNonCachedProcs++; 16287 break; 16288 } 16289 16290 if (app.isolated && app.services.size() <= 0) { 16291 // If this is an isolated process, and there are no 16292 // services running in it, then the process is no longer 16293 // needed. We agressively kill these because we can by 16294 // definition not re-use the same process again, and it is 16295 // good to avoid having whatever code was running in them 16296 // left sitting around after no longer needed. 16297 killUnneededProcessLocked(app, "isolated not needed"); 16298 } 16299 16300 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16301 && !app.killedByAm) { 16302 numTrimming++; 16303 } 16304 } 16305 } 16306 16307 mNumServiceProcs = mNewNumServiceProcs; 16308 16309 // Now determine the memory trimming level of background processes. 16310 // Unfortunately we need to start at the back of the list to do this 16311 // properly. We only do this if the number of background apps we 16312 // are managing to keep around is less than half the maximum we desire; 16313 // if we are keeping a good number around, we'll let them use whatever 16314 // memory they want. 16315 final int numCachedAndEmpty = numCached + numEmpty; 16316 int memFactor; 16317 if (numCached <= ProcessList.TRIM_CACHED_APPS 16318 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16319 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16320 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16321 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16322 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16323 } else { 16324 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16325 } 16326 } else { 16327 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16328 } 16329 // We always allow the memory level to go up (better). We only allow it to go 16330 // down if we are in a state where that is allowed, *and* the total number of processes 16331 // has gone down since last time. 16332 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16333 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16334 + " last=" + mLastNumProcesses); 16335 if (memFactor > mLastMemoryLevel) { 16336 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16337 memFactor = mLastMemoryLevel; 16338 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16339 } 16340 } 16341 mLastMemoryLevel = memFactor; 16342 mLastNumProcesses = mLruProcesses.size(); 16343 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16344 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16345 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16346 if (mLowRamStartTime == 0) { 16347 mLowRamStartTime = now; 16348 } 16349 int step = 0; 16350 int fgTrimLevel; 16351 switch (memFactor) { 16352 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16353 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16354 break; 16355 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16356 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16357 break; 16358 default: 16359 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16360 break; 16361 } 16362 int factor = numTrimming/3; 16363 int minFactor = 2; 16364 if (mHomeProcess != null) minFactor++; 16365 if (mPreviousProcess != null) minFactor++; 16366 if (factor < minFactor) factor = minFactor; 16367 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16368 for (int i=N-1; i>=0; i--) { 16369 ProcessRecord app = mLruProcesses.get(i); 16370 if (allChanged || app.procStateChanged) { 16371 setProcessTrackerState(app, trackerMemFactor, now); 16372 app.procStateChanged = false; 16373 } 16374 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16375 && !app.killedByAm) { 16376 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16377 try { 16378 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16379 "Trimming memory of " + app.processName 16380 + " to " + curLevel); 16381 app.thread.scheduleTrimMemory(curLevel); 16382 } catch (RemoteException e) { 16383 } 16384 if (false) { 16385 // For now we won't do this; our memory trimming seems 16386 // to be good enough at this point that destroying 16387 // activities causes more harm than good. 16388 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16389 && app != mHomeProcess && app != mPreviousProcess) { 16390 // Need to do this on its own message because the stack may not 16391 // be in a consistent state at this point. 16392 // For these apps we will also finish their activities 16393 // to help them free memory. 16394 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16395 } 16396 } 16397 } 16398 app.trimMemoryLevel = curLevel; 16399 step++; 16400 if (step >= factor) { 16401 step = 0; 16402 switch (curLevel) { 16403 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16404 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16405 break; 16406 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16407 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16408 break; 16409 } 16410 } 16411 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16412 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16413 && app.thread != null) { 16414 try { 16415 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16416 "Trimming memory of heavy-weight " + app.processName 16417 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16418 app.thread.scheduleTrimMemory( 16419 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16420 } catch (RemoteException e) { 16421 } 16422 } 16423 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16424 } else { 16425 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16426 || app.systemNoUi) && app.pendingUiClean) { 16427 // If this application is now in the background and it 16428 // had done UI, then give it the special trim level to 16429 // have it free UI resources. 16430 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16431 if (app.trimMemoryLevel < level && app.thread != null) { 16432 try { 16433 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16434 "Trimming memory of bg-ui " + app.processName 16435 + " to " + level); 16436 app.thread.scheduleTrimMemory(level); 16437 } catch (RemoteException e) { 16438 } 16439 } 16440 app.pendingUiClean = false; 16441 } 16442 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16443 try { 16444 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16445 "Trimming memory of fg " + app.processName 16446 + " to " + fgTrimLevel); 16447 app.thread.scheduleTrimMemory(fgTrimLevel); 16448 } catch (RemoteException e) { 16449 } 16450 } 16451 app.trimMemoryLevel = fgTrimLevel; 16452 } 16453 } 16454 } else { 16455 if (mLowRamStartTime != 0) { 16456 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16457 mLowRamStartTime = 0; 16458 } 16459 for (int i=N-1; i>=0; i--) { 16460 ProcessRecord app = mLruProcesses.get(i); 16461 if (allChanged || app.procStateChanged) { 16462 setProcessTrackerState(app, trackerMemFactor, now); 16463 app.procStateChanged = false; 16464 } 16465 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16466 || app.systemNoUi) && app.pendingUiClean) { 16467 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16468 && app.thread != null) { 16469 try { 16470 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16471 "Trimming memory of ui hidden " + app.processName 16472 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16473 app.thread.scheduleTrimMemory( 16474 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16475 } catch (RemoteException e) { 16476 } 16477 } 16478 app.pendingUiClean = false; 16479 } 16480 app.trimMemoryLevel = 0; 16481 } 16482 } 16483 16484 if (mAlwaysFinishActivities) { 16485 // Need to do this on its own message because the stack may not 16486 // be in a consistent state at this point. 16487 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16488 } 16489 16490 if (allChanged) { 16491 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16492 } 16493 16494 if (mProcessStats.shouldWriteNowLocked(now)) { 16495 mHandler.post(new Runnable() { 16496 @Override public void run() { 16497 synchronized (ActivityManagerService.this) { 16498 mProcessStats.writeStateAsyncLocked(); 16499 } 16500 } 16501 }); 16502 } 16503 16504 if (DEBUG_OOM_ADJ) { 16505 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16506 } 16507 } 16508 16509 final void trimApplications() { 16510 synchronized (this) { 16511 int i; 16512 16513 // First remove any unused application processes whose package 16514 // has been removed. 16515 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16516 final ProcessRecord app = mRemovedProcesses.get(i); 16517 if (app.activities.size() == 0 16518 && app.curReceiver == null && app.services.size() == 0) { 16519 Slog.i( 16520 TAG, "Exiting empty application process " 16521 + app.processName + " (" 16522 + (app.thread != null ? app.thread.asBinder() : null) 16523 + ")\n"); 16524 if (app.pid > 0 && app.pid != MY_PID) { 16525 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16526 app.processName, app.setAdj, "empty"); 16527 app.killedByAm = true; 16528 Process.killProcessQuiet(app.pid); 16529 } else { 16530 try { 16531 app.thread.scheduleExit(); 16532 } catch (Exception e) { 16533 // Ignore exceptions. 16534 } 16535 } 16536 cleanUpApplicationRecordLocked(app, false, true, -1); 16537 mRemovedProcesses.remove(i); 16538 16539 if (app.persistent) { 16540 if (app.persistent) { 16541 addAppLocked(app.info, false, null /* ABI override */); 16542 } 16543 } 16544 } 16545 } 16546 16547 // Now update the oom adj for all processes. 16548 updateOomAdjLocked(); 16549 } 16550 } 16551 16552 /** This method sends the specified signal to each of the persistent apps */ 16553 public void signalPersistentProcesses(int sig) throws RemoteException { 16554 if (sig != Process.SIGNAL_USR1) { 16555 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16556 } 16557 16558 synchronized (this) { 16559 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16560 != PackageManager.PERMISSION_GRANTED) { 16561 throw new SecurityException("Requires permission " 16562 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16563 } 16564 16565 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16566 ProcessRecord r = mLruProcesses.get(i); 16567 if (r.thread != null && r.persistent) { 16568 Process.sendSignal(r.pid, sig); 16569 } 16570 } 16571 } 16572 } 16573 16574 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16575 if (proc == null || proc == mProfileProc) { 16576 proc = mProfileProc; 16577 path = mProfileFile; 16578 profileType = mProfileType; 16579 clearProfilerLocked(); 16580 } 16581 if (proc == null) { 16582 return; 16583 } 16584 try { 16585 proc.thread.profilerControl(false, path, null, profileType); 16586 } catch (RemoteException e) { 16587 throw new IllegalStateException("Process disappeared"); 16588 } 16589 } 16590 16591 private void clearProfilerLocked() { 16592 if (mProfileFd != null) { 16593 try { 16594 mProfileFd.close(); 16595 } catch (IOException e) { 16596 } 16597 } 16598 mProfileApp = null; 16599 mProfileProc = null; 16600 mProfileFile = null; 16601 mProfileType = 0; 16602 mAutoStopProfiler = false; 16603 } 16604 16605 public boolean profileControl(String process, int userId, boolean start, 16606 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16607 16608 try { 16609 synchronized (this) { 16610 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16611 // its own permission. 16612 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16613 != PackageManager.PERMISSION_GRANTED) { 16614 throw new SecurityException("Requires permission " 16615 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16616 } 16617 16618 if (start && fd == null) { 16619 throw new IllegalArgumentException("null fd"); 16620 } 16621 16622 ProcessRecord proc = null; 16623 if (process != null) { 16624 proc = findProcessLocked(process, userId, "profileControl"); 16625 } 16626 16627 if (start && (proc == null || proc.thread == null)) { 16628 throw new IllegalArgumentException("Unknown process: " + process); 16629 } 16630 16631 if (start) { 16632 stopProfilerLocked(null, null, 0); 16633 setProfileApp(proc.info, proc.processName, path, fd, false); 16634 mProfileProc = proc; 16635 mProfileType = profileType; 16636 try { 16637 fd = fd.dup(); 16638 } catch (IOException e) { 16639 fd = null; 16640 } 16641 proc.thread.profilerControl(start, path, fd, profileType); 16642 fd = null; 16643 mProfileFd = null; 16644 } else { 16645 stopProfilerLocked(proc, path, profileType); 16646 if (fd != null) { 16647 try { 16648 fd.close(); 16649 } catch (IOException e) { 16650 } 16651 } 16652 } 16653 16654 return true; 16655 } 16656 } catch (RemoteException e) { 16657 throw new IllegalStateException("Process disappeared"); 16658 } finally { 16659 if (fd != null) { 16660 try { 16661 fd.close(); 16662 } catch (IOException e) { 16663 } 16664 } 16665 } 16666 } 16667 16668 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16669 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16670 userId, true, true, callName, null); 16671 ProcessRecord proc = null; 16672 try { 16673 int pid = Integer.parseInt(process); 16674 synchronized (mPidsSelfLocked) { 16675 proc = mPidsSelfLocked.get(pid); 16676 } 16677 } catch (NumberFormatException e) { 16678 } 16679 16680 if (proc == null) { 16681 ArrayMap<String, SparseArray<ProcessRecord>> all 16682 = mProcessNames.getMap(); 16683 SparseArray<ProcessRecord> procs = all.get(process); 16684 if (procs != null && procs.size() > 0) { 16685 proc = procs.valueAt(0); 16686 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16687 for (int i=1; i<procs.size(); i++) { 16688 ProcessRecord thisProc = procs.valueAt(i); 16689 if (thisProc.userId == userId) { 16690 proc = thisProc; 16691 break; 16692 } 16693 } 16694 } 16695 } 16696 } 16697 16698 return proc; 16699 } 16700 16701 public boolean dumpHeap(String process, int userId, boolean managed, 16702 String path, ParcelFileDescriptor fd) throws RemoteException { 16703 16704 try { 16705 synchronized (this) { 16706 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16707 // its own permission (same as profileControl). 16708 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16709 != PackageManager.PERMISSION_GRANTED) { 16710 throw new SecurityException("Requires permission " 16711 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16712 } 16713 16714 if (fd == null) { 16715 throw new IllegalArgumentException("null fd"); 16716 } 16717 16718 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16719 if (proc == null || proc.thread == null) { 16720 throw new IllegalArgumentException("Unknown process: " + process); 16721 } 16722 16723 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16724 if (!isDebuggable) { 16725 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16726 throw new SecurityException("Process not debuggable: " + proc); 16727 } 16728 } 16729 16730 proc.thread.dumpHeap(managed, path, fd); 16731 fd = null; 16732 return true; 16733 } 16734 } catch (RemoteException e) { 16735 throw new IllegalStateException("Process disappeared"); 16736 } finally { 16737 if (fd != null) { 16738 try { 16739 fd.close(); 16740 } catch (IOException e) { 16741 } 16742 } 16743 } 16744 } 16745 16746 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16747 public void monitor() { 16748 synchronized (this) { } 16749 } 16750 16751 void onCoreSettingsChange(Bundle settings) { 16752 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16753 ProcessRecord processRecord = mLruProcesses.get(i); 16754 try { 16755 if (processRecord.thread != null) { 16756 processRecord.thread.setCoreSettings(settings); 16757 } 16758 } catch (RemoteException re) { 16759 /* ignore */ 16760 } 16761 } 16762 } 16763 16764 // Multi-user methods 16765 16766 /** 16767 * Start user, if its not already running, but don't bring it to foreground. 16768 */ 16769 @Override 16770 public boolean startUserInBackground(final int userId) { 16771 return startUser(userId, /* foreground */ false); 16772 } 16773 16774 /** 16775 * Refreshes the list of users related to the current user when either a 16776 * user switch happens or when a new related user is started in the 16777 * background. 16778 */ 16779 private void updateCurrentProfileIdsLocked() { 16780 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16781 mCurrentUserId, false /* enabledOnly */); 16782 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16783 for (int i = 0; i < currentProfileIds.length; i++) { 16784 currentProfileIds[i] = profiles.get(i).id; 16785 } 16786 mCurrentProfileIds = currentProfileIds; 16787 } 16788 16789 private Set getProfileIdsLocked(int userId) { 16790 Set userIds = new HashSet<Integer>(); 16791 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16792 userId, false /* enabledOnly */); 16793 for (UserInfo user : profiles) { 16794 userIds.add(Integer.valueOf(user.id)); 16795 } 16796 return userIds; 16797 } 16798 16799 @Override 16800 public boolean switchUser(final int userId) { 16801 return startUser(userId, /* foregound */ true); 16802 } 16803 16804 private boolean startUser(final int userId, boolean foreground) { 16805 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16806 != PackageManager.PERMISSION_GRANTED) { 16807 String msg = "Permission Denial: switchUser() from pid=" 16808 + Binder.getCallingPid() 16809 + ", uid=" + Binder.getCallingUid() 16810 + " requires " + INTERACT_ACROSS_USERS_FULL; 16811 Slog.w(TAG, msg); 16812 throw new SecurityException(msg); 16813 } 16814 16815 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16816 16817 final long ident = Binder.clearCallingIdentity(); 16818 try { 16819 synchronized (this) { 16820 final int oldUserId = mCurrentUserId; 16821 if (oldUserId == userId) { 16822 return true; 16823 } 16824 16825 mStackSupervisor.setLockTaskModeLocked(null, false); 16826 16827 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16828 if (userInfo == null) { 16829 Slog.w(TAG, "No user info for user #" + userId); 16830 return false; 16831 } 16832 16833 if (foreground) { 16834 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16835 R.anim.screen_user_enter); 16836 } 16837 16838 boolean needStart = false; 16839 16840 // If the user we are switching to is not currently started, then 16841 // we need to start it now. 16842 if (mStartedUsers.get(userId) == null) { 16843 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16844 updateStartedUserArrayLocked(); 16845 needStart = true; 16846 } 16847 16848 final Integer userIdInt = Integer.valueOf(userId); 16849 mUserLru.remove(userIdInt); 16850 mUserLru.add(userIdInt); 16851 16852 if (foreground) { 16853 mCurrentUserId = userId; 16854 updateCurrentProfileIdsLocked(); 16855 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16856 // Once the internal notion of the active user has switched, we lock the device 16857 // with the option to show the user switcher on the keyguard. 16858 mWindowManager.lockNow(null); 16859 } else { 16860 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16861 updateCurrentProfileIdsLocked(); 16862 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16863 mUserLru.remove(currentUserIdInt); 16864 mUserLru.add(currentUserIdInt); 16865 } 16866 16867 final UserStartedState uss = mStartedUsers.get(userId); 16868 16869 // Make sure user is in the started state. If it is currently 16870 // stopping, we need to knock that off. 16871 if (uss.mState == UserStartedState.STATE_STOPPING) { 16872 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16873 // so we can just fairly silently bring the user back from 16874 // the almost-dead. 16875 uss.mState = UserStartedState.STATE_RUNNING; 16876 updateStartedUserArrayLocked(); 16877 needStart = true; 16878 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16879 // This means ACTION_SHUTDOWN has been sent, so we will 16880 // need to treat this as a new boot of the user. 16881 uss.mState = UserStartedState.STATE_BOOTING; 16882 updateStartedUserArrayLocked(); 16883 needStart = true; 16884 } 16885 16886 if (uss.mState == UserStartedState.STATE_BOOTING) { 16887 // Booting up a new user, need to tell system services about it. 16888 // Note that this is on the same handler as scheduling of broadcasts, 16889 // which is important because it needs to go first. 16890 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16891 } 16892 16893 if (foreground) { 16894 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16895 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16896 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16897 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16898 oldUserId, userId, uss)); 16899 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16900 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16901 } 16902 16903 if (needStart) { 16904 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16905 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16906 | Intent.FLAG_RECEIVER_FOREGROUND); 16907 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16908 broadcastIntentLocked(null, null, intent, 16909 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16910 false, false, MY_PID, Process.SYSTEM_UID, userId); 16911 } 16912 16913 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16914 if (userId != UserHandle.USER_OWNER) { 16915 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16916 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16917 broadcastIntentLocked(null, null, intent, null, 16918 new IIntentReceiver.Stub() { 16919 public void performReceive(Intent intent, int resultCode, 16920 String data, Bundle extras, boolean ordered, 16921 boolean sticky, int sendingUser) { 16922 userInitialized(uss, userId); 16923 } 16924 }, 0, null, null, null, AppOpsManager.OP_NONE, 16925 true, false, MY_PID, Process.SYSTEM_UID, 16926 userId); 16927 uss.initializing = true; 16928 } else { 16929 getUserManagerLocked().makeInitialized(userInfo.id); 16930 } 16931 } 16932 16933 if (foreground) { 16934 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16935 if (homeInFront) { 16936 startHomeActivityLocked(userId); 16937 } else { 16938 mStackSupervisor.resumeTopActivitiesLocked(); 16939 } 16940 EventLogTags.writeAmSwitchUser(userId); 16941 getUserManagerLocked().userForeground(userId); 16942 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16943 } else { 16944 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16945 } 16946 16947 if (needStart) { 16948 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16949 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16950 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16951 broadcastIntentLocked(null, null, intent, 16952 null, new IIntentReceiver.Stub() { 16953 @Override 16954 public void performReceive(Intent intent, int resultCode, String data, 16955 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16956 throws RemoteException { 16957 } 16958 }, 0, null, null, 16959 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16960 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16961 } 16962 } 16963 } finally { 16964 Binder.restoreCallingIdentity(ident); 16965 } 16966 16967 return true; 16968 } 16969 16970 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16971 long ident = Binder.clearCallingIdentity(); 16972 try { 16973 Intent intent; 16974 if (oldUserId >= 0) { 16975 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16976 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16977 | Intent.FLAG_RECEIVER_FOREGROUND); 16978 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16979 broadcastIntentLocked(null, null, intent, 16980 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16981 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16982 } 16983 if (newUserId >= 0) { 16984 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16985 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16986 | Intent.FLAG_RECEIVER_FOREGROUND); 16987 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16988 broadcastIntentLocked(null, null, intent, 16989 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16990 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16991 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16992 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16993 | Intent.FLAG_RECEIVER_FOREGROUND); 16994 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16995 broadcastIntentLocked(null, null, intent, 16996 null, null, 0, null, null, 16997 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16998 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16999 } 17000 } finally { 17001 Binder.restoreCallingIdentity(ident); 17002 } 17003 } 17004 17005 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17006 final int newUserId) { 17007 final int N = mUserSwitchObservers.beginBroadcast(); 17008 if (N > 0) { 17009 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17010 int mCount = 0; 17011 @Override 17012 public void sendResult(Bundle data) throws RemoteException { 17013 synchronized (ActivityManagerService.this) { 17014 if (mCurUserSwitchCallback == this) { 17015 mCount++; 17016 if (mCount == N) { 17017 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17018 } 17019 } 17020 } 17021 } 17022 }; 17023 synchronized (this) { 17024 uss.switching = true; 17025 mCurUserSwitchCallback = callback; 17026 } 17027 for (int i=0; i<N; i++) { 17028 try { 17029 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17030 newUserId, callback); 17031 } catch (RemoteException e) { 17032 } 17033 } 17034 } else { 17035 synchronized (this) { 17036 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17037 } 17038 } 17039 mUserSwitchObservers.finishBroadcast(); 17040 } 17041 17042 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17043 synchronized (this) { 17044 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17045 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17046 } 17047 } 17048 17049 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17050 mCurUserSwitchCallback = null; 17051 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17052 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17053 oldUserId, newUserId, uss)); 17054 } 17055 17056 void userInitialized(UserStartedState uss, int newUserId) { 17057 completeSwitchAndInitalize(uss, newUserId, true, false); 17058 } 17059 17060 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17061 completeSwitchAndInitalize(uss, newUserId, false, true); 17062 } 17063 17064 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17065 boolean clearInitializing, boolean clearSwitching) { 17066 boolean unfrozen = false; 17067 synchronized (this) { 17068 if (clearInitializing) { 17069 uss.initializing = false; 17070 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17071 } 17072 if (clearSwitching) { 17073 uss.switching = false; 17074 } 17075 if (!uss.switching && !uss.initializing) { 17076 mWindowManager.stopFreezingScreen(); 17077 unfrozen = true; 17078 } 17079 } 17080 if (unfrozen) { 17081 final int N = mUserSwitchObservers.beginBroadcast(); 17082 for (int i=0; i<N; i++) { 17083 try { 17084 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17085 } catch (RemoteException e) { 17086 } 17087 } 17088 mUserSwitchObservers.finishBroadcast(); 17089 } 17090 } 17091 17092 void scheduleStartProfilesLocked() { 17093 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17094 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17095 DateUtils.SECOND_IN_MILLIS); 17096 } 17097 } 17098 17099 void startProfilesLocked() { 17100 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17101 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17102 mCurrentUserId, false /* enabledOnly */); 17103 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17104 for (UserInfo user : profiles) { 17105 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17106 && user.id != mCurrentUserId) { 17107 toStart.add(user); 17108 } 17109 } 17110 final int n = toStart.size(); 17111 int i = 0; 17112 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17113 startUserInBackground(toStart.get(i).id); 17114 } 17115 if (i < n) { 17116 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17117 } 17118 } 17119 17120 void finishUserBoot(UserStartedState uss) { 17121 synchronized (this) { 17122 if (uss.mState == UserStartedState.STATE_BOOTING 17123 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17124 uss.mState = UserStartedState.STATE_RUNNING; 17125 final int userId = uss.mHandle.getIdentifier(); 17126 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17127 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17128 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17129 broadcastIntentLocked(null, null, intent, 17130 null, null, 0, null, null, 17131 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17132 true, false, MY_PID, Process.SYSTEM_UID, userId); 17133 } 17134 } 17135 } 17136 17137 void finishUserSwitch(UserStartedState uss) { 17138 synchronized (this) { 17139 finishUserBoot(uss); 17140 17141 startProfilesLocked(); 17142 17143 int num = mUserLru.size(); 17144 int i = 0; 17145 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17146 Integer oldUserId = mUserLru.get(i); 17147 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17148 if (oldUss == null) { 17149 // Shouldn't happen, but be sane if it does. 17150 mUserLru.remove(i); 17151 num--; 17152 continue; 17153 } 17154 if (oldUss.mState == UserStartedState.STATE_STOPPING 17155 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17156 // This user is already stopping, doesn't count. 17157 num--; 17158 i++; 17159 continue; 17160 } 17161 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17162 // Owner and current can't be stopped, but count as running. 17163 i++; 17164 continue; 17165 } 17166 // This is a user to be stopped. 17167 stopUserLocked(oldUserId, null); 17168 num--; 17169 i++; 17170 } 17171 } 17172 } 17173 17174 @Override 17175 public int stopUser(final int userId, final IStopUserCallback callback) { 17176 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17177 != PackageManager.PERMISSION_GRANTED) { 17178 String msg = "Permission Denial: switchUser() from pid=" 17179 + Binder.getCallingPid() 17180 + ", uid=" + Binder.getCallingUid() 17181 + " requires " + INTERACT_ACROSS_USERS_FULL; 17182 Slog.w(TAG, msg); 17183 throw new SecurityException(msg); 17184 } 17185 if (userId <= 0) { 17186 throw new IllegalArgumentException("Can't stop primary user " + userId); 17187 } 17188 synchronized (this) { 17189 return stopUserLocked(userId, callback); 17190 } 17191 } 17192 17193 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17194 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17195 if (mCurrentUserId == userId) { 17196 return ActivityManager.USER_OP_IS_CURRENT; 17197 } 17198 17199 final UserStartedState uss = mStartedUsers.get(userId); 17200 if (uss == null) { 17201 // User is not started, nothing to do... but we do need to 17202 // callback if requested. 17203 if (callback != null) { 17204 mHandler.post(new Runnable() { 17205 @Override 17206 public void run() { 17207 try { 17208 callback.userStopped(userId); 17209 } catch (RemoteException e) { 17210 } 17211 } 17212 }); 17213 } 17214 return ActivityManager.USER_OP_SUCCESS; 17215 } 17216 17217 if (callback != null) { 17218 uss.mStopCallbacks.add(callback); 17219 } 17220 17221 if (uss.mState != UserStartedState.STATE_STOPPING 17222 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17223 uss.mState = UserStartedState.STATE_STOPPING; 17224 updateStartedUserArrayLocked(); 17225 17226 long ident = Binder.clearCallingIdentity(); 17227 try { 17228 // We are going to broadcast ACTION_USER_STOPPING and then 17229 // once that is done send a final ACTION_SHUTDOWN and then 17230 // stop the user. 17231 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17232 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17233 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17234 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17235 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17236 // This is the result receiver for the final shutdown broadcast. 17237 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17238 @Override 17239 public void performReceive(Intent intent, int resultCode, String data, 17240 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17241 finishUserStop(uss); 17242 } 17243 }; 17244 // This is the result receiver for the initial stopping broadcast. 17245 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17246 @Override 17247 public void performReceive(Intent intent, int resultCode, String data, 17248 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17249 // On to the next. 17250 synchronized (ActivityManagerService.this) { 17251 if (uss.mState != UserStartedState.STATE_STOPPING) { 17252 // Whoops, we are being started back up. Abort, abort! 17253 return; 17254 } 17255 uss.mState = UserStartedState.STATE_SHUTDOWN; 17256 } 17257 mSystemServiceManager.stopUser(userId); 17258 broadcastIntentLocked(null, null, shutdownIntent, 17259 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17260 true, false, MY_PID, Process.SYSTEM_UID, userId); 17261 } 17262 }; 17263 // Kick things off. 17264 broadcastIntentLocked(null, null, stoppingIntent, 17265 null, stoppingReceiver, 0, null, null, 17266 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17267 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17268 } finally { 17269 Binder.restoreCallingIdentity(ident); 17270 } 17271 } 17272 17273 return ActivityManager.USER_OP_SUCCESS; 17274 } 17275 17276 void finishUserStop(UserStartedState uss) { 17277 final int userId = uss.mHandle.getIdentifier(); 17278 boolean stopped; 17279 ArrayList<IStopUserCallback> callbacks; 17280 synchronized (this) { 17281 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17282 if (mStartedUsers.get(userId) != uss) { 17283 stopped = false; 17284 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17285 stopped = false; 17286 } else { 17287 stopped = true; 17288 // User can no longer run. 17289 mStartedUsers.remove(userId); 17290 mUserLru.remove(Integer.valueOf(userId)); 17291 updateStartedUserArrayLocked(); 17292 17293 // Clean up all state and processes associated with the user. 17294 // Kill all the processes for the user. 17295 forceStopUserLocked(userId, "finish user"); 17296 } 17297 } 17298 17299 for (int i=0; i<callbacks.size(); i++) { 17300 try { 17301 if (stopped) callbacks.get(i).userStopped(userId); 17302 else callbacks.get(i).userStopAborted(userId); 17303 } catch (RemoteException e) { 17304 } 17305 } 17306 17307 if (stopped) { 17308 mSystemServiceManager.cleanupUser(userId); 17309 synchronized (this) { 17310 mStackSupervisor.removeUserLocked(userId); 17311 } 17312 } 17313 } 17314 17315 @Override 17316 public UserInfo getCurrentUser() { 17317 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17318 != PackageManager.PERMISSION_GRANTED) && ( 17319 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17320 != PackageManager.PERMISSION_GRANTED)) { 17321 String msg = "Permission Denial: getCurrentUser() from pid=" 17322 + Binder.getCallingPid() 17323 + ", uid=" + Binder.getCallingUid() 17324 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17325 Slog.w(TAG, msg); 17326 throw new SecurityException(msg); 17327 } 17328 synchronized (this) { 17329 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17330 } 17331 } 17332 17333 int getCurrentUserIdLocked() { 17334 return mCurrentUserId; 17335 } 17336 17337 @Override 17338 public boolean isUserRunning(int userId, boolean orStopped) { 17339 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17340 != PackageManager.PERMISSION_GRANTED) { 17341 String msg = "Permission Denial: isUserRunning() from pid=" 17342 + Binder.getCallingPid() 17343 + ", uid=" + Binder.getCallingUid() 17344 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17345 Slog.w(TAG, msg); 17346 throw new SecurityException(msg); 17347 } 17348 synchronized (this) { 17349 return isUserRunningLocked(userId, orStopped); 17350 } 17351 } 17352 17353 boolean isUserRunningLocked(int userId, boolean orStopped) { 17354 UserStartedState state = mStartedUsers.get(userId); 17355 if (state == null) { 17356 return false; 17357 } 17358 if (orStopped) { 17359 return true; 17360 } 17361 return state.mState != UserStartedState.STATE_STOPPING 17362 && state.mState != UserStartedState.STATE_SHUTDOWN; 17363 } 17364 17365 @Override 17366 public int[] getRunningUserIds() { 17367 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17368 != PackageManager.PERMISSION_GRANTED) { 17369 String msg = "Permission Denial: isUserRunning() from pid=" 17370 + Binder.getCallingPid() 17371 + ", uid=" + Binder.getCallingUid() 17372 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17373 Slog.w(TAG, msg); 17374 throw new SecurityException(msg); 17375 } 17376 synchronized (this) { 17377 return mStartedUserArray; 17378 } 17379 } 17380 17381 private void updateStartedUserArrayLocked() { 17382 int num = 0; 17383 for (int i=0; i<mStartedUsers.size(); i++) { 17384 UserStartedState uss = mStartedUsers.valueAt(i); 17385 // This list does not include stopping users. 17386 if (uss.mState != UserStartedState.STATE_STOPPING 17387 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17388 num++; 17389 } 17390 } 17391 mStartedUserArray = new int[num]; 17392 num = 0; 17393 for (int i=0; i<mStartedUsers.size(); i++) { 17394 UserStartedState uss = mStartedUsers.valueAt(i); 17395 if (uss.mState != UserStartedState.STATE_STOPPING 17396 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17397 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17398 num++; 17399 } 17400 } 17401 } 17402 17403 @Override 17404 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17405 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17406 != PackageManager.PERMISSION_GRANTED) { 17407 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17408 + Binder.getCallingPid() 17409 + ", uid=" + Binder.getCallingUid() 17410 + " requires " + INTERACT_ACROSS_USERS_FULL; 17411 Slog.w(TAG, msg); 17412 throw new SecurityException(msg); 17413 } 17414 17415 mUserSwitchObservers.register(observer); 17416 } 17417 17418 @Override 17419 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17420 mUserSwitchObservers.unregister(observer); 17421 } 17422 17423 private boolean userExists(int userId) { 17424 if (userId == 0) { 17425 return true; 17426 } 17427 UserManagerService ums = getUserManagerLocked(); 17428 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17429 } 17430 17431 int[] getUsersLocked() { 17432 UserManagerService ums = getUserManagerLocked(); 17433 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17434 } 17435 17436 UserManagerService getUserManagerLocked() { 17437 if (mUserManager == null) { 17438 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17439 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17440 } 17441 return mUserManager; 17442 } 17443 17444 private int applyUserId(int uid, int userId) { 17445 return UserHandle.getUid(userId, uid); 17446 } 17447 17448 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17449 if (info == null) return null; 17450 ApplicationInfo newInfo = new ApplicationInfo(info); 17451 newInfo.uid = applyUserId(info.uid, userId); 17452 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17453 + info.packageName; 17454 return newInfo; 17455 } 17456 17457 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17458 if (aInfo == null 17459 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17460 return aInfo; 17461 } 17462 17463 ActivityInfo info = new ActivityInfo(aInfo); 17464 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17465 return info; 17466 } 17467 17468 private final class LocalService extends ActivityManagerInternal { 17469 @Override 17470 public void goingToSleep() { 17471 ActivityManagerService.this.goingToSleep(); 17472 } 17473 17474 @Override 17475 public void wakingUp() { 17476 ActivityManagerService.this.wakingUp(); 17477 } 17478 } 17479 17480 /** 17481 * An implementation of IAppTask, that allows an app to manage its own tasks via 17482 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17483 * only the process that calls getAppTasks() can call the AppTask methods. 17484 */ 17485 class AppTaskImpl extends IAppTask.Stub { 17486 private int mTaskId; 17487 private int mCallingUid; 17488 17489 public AppTaskImpl(int taskId, int callingUid) { 17490 mTaskId = taskId; 17491 mCallingUid = callingUid; 17492 } 17493 17494 @Override 17495 public void finishAndRemoveTask() { 17496 // Ensure that we are called from the same process that created this AppTask 17497 if (mCallingUid != Binder.getCallingUid()) { 17498 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17499 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17500 return; 17501 } 17502 17503 synchronized (ActivityManagerService.this) { 17504 long origId = Binder.clearCallingIdentity(); 17505 try { 17506 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17507 if (tr != null) { 17508 // Only kill the process if we are not a new document 17509 int flags = tr.getBaseIntent().getFlags(); 17510 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17511 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17512 removeTaskByIdLocked(mTaskId, 17513 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17514 } 17515 } finally { 17516 Binder.restoreCallingIdentity(origId); 17517 } 17518 } 17519 } 17520 17521 @Override 17522 public ActivityManager.RecentTaskInfo getTaskInfo() { 17523 // Ensure that we are called from the same process that created this AppTask 17524 if (mCallingUid != Binder.getCallingUid()) { 17525 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17526 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17527 return null; 17528 } 17529 17530 synchronized (ActivityManagerService.this) { 17531 long origId = Binder.clearCallingIdentity(); 17532 try { 17533 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17534 if (tr != null) { 17535 return createRecentTaskInfoFromTaskRecord(tr); 17536 } 17537 } finally { 17538 Binder.restoreCallingIdentity(origId); 17539 } 17540 return null; 17541 } 17542 } 17543 } 17544} 17545