ActivityManagerService.java revision 6ea0d0a2592395b8980c24304733daec628e947e
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.lastActiveTime = tr.lastActiveTime; 7262 return rti; 7263 } 7264 7265 @Override 7266 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7267 int flags, int userId) { 7268 final int callingUid = Binder.getCallingUid(); 7269 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7270 false, true, "getRecentTasks", null); 7271 7272 synchronized (this) { 7273 final boolean allowed = checkCallingPermission( 7274 android.Manifest.permission.GET_TASKS) 7275 == PackageManager.PERMISSION_GRANTED; 7276 if (!allowed) { 7277 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7278 + " does not hold GET_TASKS; limiting output"); 7279 } 7280 final boolean detailed = checkCallingPermission( 7281 android.Manifest.permission.GET_DETAILED_TASKS) 7282 == PackageManager.PERMISSION_GRANTED; 7283 7284 IPackageManager pm = AppGlobals.getPackageManager(); 7285 7286 final int N = mRecentTasks.size(); 7287 ArrayList<ActivityManager.RecentTaskInfo> res 7288 = new ArrayList<ActivityManager.RecentTaskInfo>( 7289 maxNum < N ? maxNum : N); 7290 7291 final Set<Integer> includedUsers; 7292 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7293 includedUsers = getProfileIdsLocked(userId); 7294 } else { 7295 includedUsers = new HashSet<Integer>(); 7296 } 7297 includedUsers.add(Integer.valueOf(userId)); 7298 for (int i=0; i<N && maxNum > 0; i++) { 7299 TaskRecord tr = mRecentTasks.get(i); 7300 // Only add calling user or related users recent tasks 7301 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7302 7303 // Return the entry if desired by the caller. We always return 7304 // the first entry, because callers always expect this to be the 7305 // foreground app. We may filter others if the caller has 7306 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7307 // we should exclude the entry. 7308 7309 if (i == 0 7310 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7311 || (tr.intent == null) 7312 || ((tr.intent.getFlags() 7313 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7314 if (!allowed) { 7315 // If the caller doesn't have the GET_TASKS permission, then only 7316 // allow them to see a small subset of tasks -- their own and home. 7317 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7318 continue; 7319 } 7320 } 7321 if (tr.intent != null && 7322 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7323 != 0 && tr.getTopActivity() == null) { 7324 // Don't include auto remove tasks that are finished or finishing. 7325 continue; 7326 } 7327 7328 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7329 if (!detailed) { 7330 rti.baseIntent.replaceExtras((Bundle)null); 7331 } 7332 7333 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7334 // Check whether this activity is currently available. 7335 try { 7336 if (rti.origActivity != null) { 7337 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7338 == null) { 7339 continue; 7340 } 7341 } else if (rti.baseIntent != null) { 7342 if (pm.queryIntentActivities(rti.baseIntent, 7343 null, 0, userId) == null) { 7344 continue; 7345 } 7346 } 7347 } catch (RemoteException e) { 7348 // Will never happen. 7349 } 7350 } 7351 7352 res.add(rti); 7353 maxNum--; 7354 } 7355 } 7356 return res; 7357 } 7358 } 7359 7360 private TaskRecord recentTaskForIdLocked(int id) { 7361 final int N = mRecentTasks.size(); 7362 for (int i=0; i<N; i++) { 7363 TaskRecord tr = mRecentTasks.get(i); 7364 if (tr.taskId == id) { 7365 return tr; 7366 } 7367 } 7368 return null; 7369 } 7370 7371 @Override 7372 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7373 synchronized (this) { 7374 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7375 "getTaskThumbnail()"); 7376 TaskRecord tr = recentTaskForIdLocked(id); 7377 if (tr != null) { 7378 return tr.getTaskThumbnailLocked(); 7379 } 7380 } 7381 return null; 7382 } 7383 7384 @Override 7385 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7386 synchronized (this) { 7387 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7388 if (r != null) { 7389 r.taskDescription = td; 7390 r.task.updateTaskDescription(); 7391 } 7392 } 7393 } 7394 7395 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7396 if (!pr.killedByAm) { 7397 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7398 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7399 pr.processName, pr.setAdj, reason); 7400 pr.killedByAm = true; 7401 Process.killProcessQuiet(pr.pid); 7402 } 7403 } 7404 7405 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7406 tr.disposeThumbnail(); 7407 mRecentTasks.remove(tr); 7408 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7409 Intent baseIntent = new Intent( 7410 tr.intent != null ? tr.intent : tr.affinityIntent); 7411 ComponentName component = baseIntent.getComponent(); 7412 if (component == null) { 7413 Slog.w(TAG, "Now component for base intent of task: " + tr); 7414 return; 7415 } 7416 7417 // Find any running services associated with this app. 7418 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7419 7420 if (killProcesses) { 7421 // Find any running processes associated with this app. 7422 final String pkg = component.getPackageName(); 7423 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7424 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7425 for (int i=0; i<pmap.size(); i++) { 7426 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7427 for (int j=0; j<uids.size(); j++) { 7428 ProcessRecord proc = uids.valueAt(j); 7429 if (proc.userId != tr.userId) { 7430 continue; 7431 } 7432 if (!proc.pkgList.containsKey(pkg)) { 7433 continue; 7434 } 7435 procs.add(proc); 7436 } 7437 } 7438 7439 // Kill the running processes. 7440 for (int i=0; i<procs.size(); i++) { 7441 ProcessRecord pr = procs.get(i); 7442 if (pr == mHomeProcess) { 7443 // Don't kill the home process along with tasks from the same package. 7444 continue; 7445 } 7446 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7447 killUnneededProcessLocked(pr, "remove task"); 7448 } else { 7449 pr.waitingToKill = "remove task"; 7450 } 7451 } 7452 } 7453 } 7454 7455 /** 7456 * Removes the task with the specified task id. 7457 * 7458 * @param taskId Identifier of the task to be removed. 7459 * @param flags Additional operational flags. May be 0 or 7460 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7461 * @return Returns true if the given task was found and removed. 7462 */ 7463 private boolean removeTaskByIdLocked(int taskId, int flags) { 7464 TaskRecord tr = recentTaskForIdLocked(taskId); 7465 if (tr != null) { 7466 tr.removeTaskActivitiesLocked(); 7467 cleanUpRemovedTaskLocked(tr, flags); 7468 if (tr.isPersistable) { 7469 notifyTaskPersisterLocked(tr, true); 7470 } 7471 return true; 7472 } 7473 return false; 7474 } 7475 7476 @Override 7477 public boolean removeTask(int taskId, int flags) { 7478 synchronized (this) { 7479 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7480 "removeTask()"); 7481 long ident = Binder.clearCallingIdentity(); 7482 try { 7483 return removeTaskByIdLocked(taskId, flags); 7484 } finally { 7485 Binder.restoreCallingIdentity(ident); 7486 } 7487 } 7488 } 7489 7490 /** 7491 * TODO: Add mController hook 7492 */ 7493 @Override 7494 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7495 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7496 "moveTaskToFront()"); 7497 7498 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7499 synchronized(this) { 7500 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7501 Binder.getCallingUid(), "Task to front")) { 7502 ActivityOptions.abort(options); 7503 return; 7504 } 7505 final long origId = Binder.clearCallingIdentity(); 7506 try { 7507 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7508 if (task == null) { 7509 return; 7510 } 7511 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7512 mStackSupervisor.showLockTaskToast(); 7513 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7514 return; 7515 } 7516 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7517 if (prev != null && prev.isRecentsActivity()) { 7518 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7519 } 7520 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7521 } finally { 7522 Binder.restoreCallingIdentity(origId); 7523 } 7524 ActivityOptions.abort(options); 7525 } 7526 } 7527 7528 @Override 7529 public void moveTaskToBack(int taskId) { 7530 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7531 "moveTaskToBack()"); 7532 7533 synchronized(this) { 7534 TaskRecord tr = recentTaskForIdLocked(taskId); 7535 if (tr != null) { 7536 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7537 ActivityStack stack = tr.stack; 7538 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7539 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7540 Binder.getCallingUid(), "Task to back")) { 7541 return; 7542 } 7543 } 7544 final long origId = Binder.clearCallingIdentity(); 7545 try { 7546 stack.moveTaskToBackLocked(taskId, null); 7547 } finally { 7548 Binder.restoreCallingIdentity(origId); 7549 } 7550 } 7551 } 7552 } 7553 7554 /** 7555 * Moves an activity, and all of the other activities within the same task, to the bottom 7556 * of the history stack. The activity's order within the task is unchanged. 7557 * 7558 * @param token A reference to the activity we wish to move 7559 * @param nonRoot If false then this only works if the activity is the root 7560 * of a task; if true it will work for any activity in a task. 7561 * @return Returns true if the move completed, false if not. 7562 */ 7563 @Override 7564 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7565 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7566 synchronized(this) { 7567 final long origId = Binder.clearCallingIdentity(); 7568 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7569 if (taskId >= 0) { 7570 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7571 } 7572 Binder.restoreCallingIdentity(origId); 7573 } 7574 return false; 7575 } 7576 7577 @Override 7578 public void moveTaskBackwards(int task) { 7579 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7580 "moveTaskBackwards()"); 7581 7582 synchronized(this) { 7583 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7584 Binder.getCallingUid(), "Task backwards")) { 7585 return; 7586 } 7587 final long origId = Binder.clearCallingIdentity(); 7588 moveTaskBackwardsLocked(task); 7589 Binder.restoreCallingIdentity(origId); 7590 } 7591 } 7592 7593 private final void moveTaskBackwardsLocked(int task) { 7594 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7595 } 7596 7597 @Override 7598 public IBinder getHomeActivityToken() throws RemoteException { 7599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7600 "getHomeActivityToken()"); 7601 synchronized (this) { 7602 return mStackSupervisor.getHomeActivityToken(); 7603 } 7604 } 7605 7606 @Override 7607 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7608 IActivityContainerCallback callback) throws RemoteException { 7609 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7610 "createActivityContainer()"); 7611 synchronized (this) { 7612 if (parentActivityToken == null) { 7613 throw new IllegalArgumentException("parent token must not be null"); 7614 } 7615 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7616 if (r == null) { 7617 return null; 7618 } 7619 if (callback == null) { 7620 throw new IllegalArgumentException("callback must not be null"); 7621 } 7622 return mStackSupervisor.createActivityContainer(r, callback); 7623 } 7624 } 7625 7626 @Override 7627 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7628 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7629 "deleteActivityContainer()"); 7630 synchronized (this) { 7631 mStackSupervisor.deleteActivityContainer(container); 7632 } 7633 } 7634 7635 @Override 7636 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7637 throws RemoteException { 7638 synchronized (this) { 7639 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7640 if (stack != null) { 7641 return stack.mActivityContainer; 7642 } 7643 return null; 7644 } 7645 } 7646 7647 @Override 7648 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7649 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7650 "moveTaskToStack()"); 7651 if (stackId == HOME_STACK_ID) { 7652 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7653 new RuntimeException("here").fillInStackTrace()); 7654 } 7655 synchronized (this) { 7656 long ident = Binder.clearCallingIdentity(); 7657 try { 7658 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7659 + stackId + " toTop=" + toTop); 7660 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7661 } finally { 7662 Binder.restoreCallingIdentity(ident); 7663 } 7664 } 7665 } 7666 7667 @Override 7668 public void resizeStack(int stackBoxId, Rect bounds) { 7669 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7670 "resizeStackBox()"); 7671 long ident = Binder.clearCallingIdentity(); 7672 try { 7673 mWindowManager.resizeStack(stackBoxId, bounds); 7674 } finally { 7675 Binder.restoreCallingIdentity(ident); 7676 } 7677 } 7678 7679 @Override 7680 public List<StackInfo> getAllStackInfos() { 7681 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7682 "getAllStackInfos()"); 7683 long ident = Binder.clearCallingIdentity(); 7684 try { 7685 synchronized (this) { 7686 return mStackSupervisor.getAllStackInfosLocked(); 7687 } 7688 } finally { 7689 Binder.restoreCallingIdentity(ident); 7690 } 7691 } 7692 7693 @Override 7694 public StackInfo getStackInfo(int stackId) { 7695 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7696 "getStackInfo()"); 7697 long ident = Binder.clearCallingIdentity(); 7698 try { 7699 synchronized (this) { 7700 return mStackSupervisor.getStackInfoLocked(stackId); 7701 } 7702 } finally { 7703 Binder.restoreCallingIdentity(ident); 7704 } 7705 } 7706 7707 @Override 7708 public boolean isInHomeStack(int taskId) { 7709 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7710 "getStackInfo()"); 7711 long ident = Binder.clearCallingIdentity(); 7712 try { 7713 synchronized (this) { 7714 TaskRecord tr = recentTaskForIdLocked(taskId); 7715 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7716 } 7717 } finally { 7718 Binder.restoreCallingIdentity(ident); 7719 } 7720 } 7721 7722 @Override 7723 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7724 synchronized(this) { 7725 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7726 } 7727 } 7728 7729 private boolean isLockTaskAuthorized(String pkg) { 7730 final DevicePolicyManager dpm = (DevicePolicyManager) 7731 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7732 try { 7733 int uid = mContext.getPackageManager().getPackageUid(pkg, 7734 Binder.getCallingUserHandle().getIdentifier()); 7735 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7736 } catch (NameNotFoundException e) { 7737 return false; 7738 } 7739 } 7740 7741 void startLockTaskMode(TaskRecord task) { 7742 final String pkg; 7743 synchronized (this) { 7744 pkg = task.intent.getComponent().getPackageName(); 7745 } 7746 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7747 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7748 final TaskRecord taskRecord = task; 7749 mHandler.post(new Runnable() { 7750 @Override 7751 public void run() { 7752 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7753 } 7754 }); 7755 return; 7756 } 7757 long ident = Binder.clearCallingIdentity(); 7758 try { 7759 synchronized (this) { 7760 // Since we lost lock on task, make sure it is still there. 7761 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7762 if (task != null) { 7763 if (!isSystemInitiated 7764 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7765 throw new IllegalArgumentException("Invalid task, not in foreground"); 7766 } 7767 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7768 } 7769 } 7770 } finally { 7771 Binder.restoreCallingIdentity(ident); 7772 } 7773 } 7774 7775 @Override 7776 public void startLockTaskMode(int taskId) { 7777 final TaskRecord task; 7778 long ident = Binder.clearCallingIdentity(); 7779 try { 7780 synchronized (this) { 7781 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7782 } 7783 } finally { 7784 Binder.restoreCallingIdentity(ident); 7785 } 7786 if (task != null) { 7787 startLockTaskMode(task); 7788 } 7789 } 7790 7791 @Override 7792 public void startLockTaskMode(IBinder token) { 7793 final TaskRecord task; 7794 long ident = Binder.clearCallingIdentity(); 7795 try { 7796 synchronized (this) { 7797 final ActivityRecord r = ActivityRecord.forToken(token); 7798 if (r == null) { 7799 return; 7800 } 7801 task = r.task; 7802 } 7803 } finally { 7804 Binder.restoreCallingIdentity(ident); 7805 } 7806 if (task != null) { 7807 startLockTaskMode(task); 7808 } 7809 } 7810 7811 @Override 7812 public void startLockTaskModeOnCurrent() throws RemoteException { 7813 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7814 ActivityRecord r = null; 7815 synchronized (this) { 7816 r = mStackSupervisor.topRunningActivityLocked(); 7817 } 7818 startLockTaskMode(r.task); 7819 } 7820 7821 @Override 7822 public void stopLockTaskMode() { 7823 // Verify that the user matches the package of the intent for the TaskRecord 7824 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7825 // and stopLockTaskMode. 7826 final int callingUid = Binder.getCallingUid(); 7827 if (callingUid != Process.SYSTEM_UID) { 7828 try { 7829 String pkg = 7830 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7831 int uid = mContext.getPackageManager().getPackageUid(pkg, 7832 Binder.getCallingUserHandle().getIdentifier()); 7833 if (uid != callingUid) { 7834 throw new SecurityException("Invalid uid, expected " + uid); 7835 } 7836 } catch (NameNotFoundException e) { 7837 Log.d(TAG, "stopLockTaskMode " + e); 7838 return; 7839 } 7840 } 7841 long ident = Binder.clearCallingIdentity(); 7842 try { 7843 Log.d(TAG, "stopLockTaskMode"); 7844 // Stop lock task 7845 synchronized (this) { 7846 mStackSupervisor.setLockTaskModeLocked(null, false); 7847 } 7848 } finally { 7849 Binder.restoreCallingIdentity(ident); 7850 } 7851 } 7852 7853 @Override 7854 public void stopLockTaskModeOnCurrent() throws RemoteException { 7855 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7856 long ident = Binder.clearCallingIdentity(); 7857 try { 7858 stopLockTaskMode(); 7859 } finally { 7860 Binder.restoreCallingIdentity(ident); 7861 } 7862 } 7863 7864 @Override 7865 public boolean isInLockTaskMode() { 7866 synchronized (this) { 7867 return mStackSupervisor.isInLockTaskMode(); 7868 } 7869 } 7870 7871 // ========================================================= 7872 // CONTENT PROVIDERS 7873 // ========================================================= 7874 7875 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7876 List<ProviderInfo> providers = null; 7877 try { 7878 providers = AppGlobals.getPackageManager(). 7879 queryContentProviders(app.processName, app.uid, 7880 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7881 } catch (RemoteException ex) { 7882 } 7883 if (DEBUG_MU) 7884 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7885 int userId = app.userId; 7886 if (providers != null) { 7887 int N = providers.size(); 7888 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7889 for (int i=0; i<N; i++) { 7890 ProviderInfo cpi = 7891 (ProviderInfo)providers.get(i); 7892 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7893 cpi.name, cpi.flags); 7894 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7895 // This is a singleton provider, but a user besides the 7896 // default user is asking to initialize a process it runs 7897 // in... well, no, it doesn't actually run in this process, 7898 // it runs in the process of the default user. Get rid of it. 7899 providers.remove(i); 7900 N--; 7901 i--; 7902 continue; 7903 } 7904 7905 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7906 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7907 if (cpr == null) { 7908 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7909 mProviderMap.putProviderByClass(comp, cpr); 7910 } 7911 if (DEBUG_MU) 7912 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7913 app.pubProviders.put(cpi.name, cpr); 7914 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7915 // Don't add this if it is a platform component that is marked 7916 // to run in multiple processes, because this is actually 7917 // part of the framework so doesn't make sense to track as a 7918 // separate apk in the process. 7919 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7920 mProcessStats); 7921 } 7922 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7923 } 7924 } 7925 return providers; 7926 } 7927 7928 /** 7929 * Check if {@link ProcessRecord} has a possible chance at accessing the 7930 * given {@link ProviderInfo}. Final permission checking is always done 7931 * in {@link ContentProvider}. 7932 */ 7933 private final String checkContentProviderPermissionLocked( 7934 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7935 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7936 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7937 boolean checkedGrants = false; 7938 if (checkUser) { 7939 // Looking for cross-user grants before enforcing the typical cross-users permissions 7940 if (UserHandle.getUserId(callingUid) != userId) { 7941 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7942 return null; 7943 } 7944 checkedGrants = true; 7945 } 7946 userId = handleIncomingUser(callingPid, callingUid, userId, 7947 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7948 } 7949 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7950 cpi.applicationInfo.uid, cpi.exported) 7951 == PackageManager.PERMISSION_GRANTED) { 7952 return null; 7953 } 7954 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7955 cpi.applicationInfo.uid, cpi.exported) 7956 == PackageManager.PERMISSION_GRANTED) { 7957 return null; 7958 } 7959 7960 PathPermission[] pps = cpi.pathPermissions; 7961 if (pps != null) { 7962 int i = pps.length; 7963 while (i > 0) { 7964 i--; 7965 PathPermission pp = pps[i]; 7966 String pprperm = pp.getReadPermission(); 7967 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7968 cpi.applicationInfo.uid, cpi.exported) 7969 == PackageManager.PERMISSION_GRANTED) { 7970 return null; 7971 } 7972 String ppwperm = pp.getWritePermission(); 7973 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7974 cpi.applicationInfo.uid, cpi.exported) 7975 == PackageManager.PERMISSION_GRANTED) { 7976 return null; 7977 } 7978 } 7979 } 7980 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7981 return null; 7982 } 7983 7984 String msg; 7985 if (!cpi.exported) { 7986 msg = "Permission Denial: opening provider " + cpi.name 7987 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7988 + ", uid=" + callingUid + ") that is not exported from uid " 7989 + cpi.applicationInfo.uid; 7990 } else { 7991 msg = "Permission Denial: opening provider " + cpi.name 7992 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7993 + ", uid=" + callingUid + ") requires " 7994 + cpi.readPermission + " or " + cpi.writePermission; 7995 } 7996 Slog.w(TAG, msg); 7997 return msg; 7998 } 7999 8000 /** 8001 * Returns if the ContentProvider has granted a uri to callingUid 8002 */ 8003 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8004 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8005 if (perms != null) { 8006 for (GrantUri grantUri : perms.keySet()) { 8007 if (grantUri.sourceUserId == userId || !checkUser) { 8008 if (matchesProvider(grantUri.uri, cpi)) { 8009 return true; 8010 } 8011 } 8012 } 8013 } 8014 return false; 8015 } 8016 8017 /** 8018 * Returns true if the uri authority is one of the authorities specified in the provider. 8019 */ 8020 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8021 String uriAuth = uri.getAuthority(); 8022 String cpiAuth = cpi.authority; 8023 if (cpiAuth.indexOf(';') == -1) { 8024 return cpiAuth.equals(uriAuth); 8025 } 8026 String[] cpiAuths = cpiAuth.split(";"); 8027 int length = cpiAuths.length; 8028 for (int i = 0; i < length; i++) { 8029 if (cpiAuths[i].equals(uriAuth)) return true; 8030 } 8031 return false; 8032 } 8033 8034 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8035 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8036 if (r != null) { 8037 for (int i=0; i<r.conProviders.size(); i++) { 8038 ContentProviderConnection conn = r.conProviders.get(i); 8039 if (conn.provider == cpr) { 8040 if (DEBUG_PROVIDER) Slog.v(TAG, 8041 "Adding provider requested by " 8042 + r.processName + " from process " 8043 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8044 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8045 if (stable) { 8046 conn.stableCount++; 8047 conn.numStableIncs++; 8048 } else { 8049 conn.unstableCount++; 8050 conn.numUnstableIncs++; 8051 } 8052 return conn; 8053 } 8054 } 8055 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8056 if (stable) { 8057 conn.stableCount = 1; 8058 conn.numStableIncs = 1; 8059 } else { 8060 conn.unstableCount = 1; 8061 conn.numUnstableIncs = 1; 8062 } 8063 cpr.connections.add(conn); 8064 r.conProviders.add(conn); 8065 return conn; 8066 } 8067 cpr.addExternalProcessHandleLocked(externalProcessToken); 8068 return null; 8069 } 8070 8071 boolean decProviderCountLocked(ContentProviderConnection conn, 8072 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8073 if (conn != null) { 8074 cpr = conn.provider; 8075 if (DEBUG_PROVIDER) Slog.v(TAG, 8076 "Removing provider requested by " 8077 + conn.client.processName + " from process " 8078 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8079 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8080 if (stable) { 8081 conn.stableCount--; 8082 } else { 8083 conn.unstableCount--; 8084 } 8085 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8086 cpr.connections.remove(conn); 8087 conn.client.conProviders.remove(conn); 8088 return true; 8089 } 8090 return false; 8091 } 8092 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8093 return false; 8094 } 8095 8096 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8097 String name, IBinder token, boolean stable, int userId) { 8098 ContentProviderRecord cpr; 8099 ContentProviderConnection conn = null; 8100 ProviderInfo cpi = null; 8101 8102 synchronized(this) { 8103 ProcessRecord r = null; 8104 if (caller != null) { 8105 r = getRecordForAppLocked(caller); 8106 if (r == null) { 8107 throw new SecurityException( 8108 "Unable to find app for caller " + caller 8109 + " (pid=" + Binder.getCallingPid() 8110 + ") when getting content provider " + name); 8111 } 8112 } 8113 8114 boolean checkCrossUser = true; 8115 8116 // First check if this content provider has been published... 8117 cpr = mProviderMap.getProviderByName(name, userId); 8118 // If that didn't work, check if it exists for user 0 and then 8119 // verify that it's a singleton provider before using it. 8120 if (cpr == null && userId != UserHandle.USER_OWNER) { 8121 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8122 if (cpr != null) { 8123 cpi = cpr.info; 8124 if (isSingleton(cpi.processName, cpi.applicationInfo, 8125 cpi.name, cpi.flags) 8126 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8127 userId = UserHandle.USER_OWNER; 8128 checkCrossUser = false; 8129 } else { 8130 cpr = null; 8131 cpi = null; 8132 } 8133 } 8134 } 8135 8136 boolean providerRunning = cpr != null; 8137 if (providerRunning) { 8138 cpi = cpr.info; 8139 String msg; 8140 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8141 != null) { 8142 throw new SecurityException(msg); 8143 } 8144 8145 if (r != null && cpr.canRunHere(r)) { 8146 // This provider has been published or is in the process 8147 // of being published... but it is also allowed to run 8148 // in the caller's process, so don't make a connection 8149 // and just let the caller instantiate its own instance. 8150 ContentProviderHolder holder = cpr.newHolder(null); 8151 // don't give caller the provider object, it needs 8152 // to make its own. 8153 holder.provider = null; 8154 return holder; 8155 } 8156 8157 final long origId = Binder.clearCallingIdentity(); 8158 8159 // In this case the provider instance already exists, so we can 8160 // return it right away. 8161 conn = incProviderCountLocked(r, cpr, token, stable); 8162 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8163 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8164 // If this is a perceptible app accessing the provider, 8165 // make sure to count it as being accessed and thus 8166 // back up on the LRU list. This is good because 8167 // content providers are often expensive to start. 8168 updateLruProcessLocked(cpr.proc, false, null); 8169 } 8170 } 8171 8172 if (cpr.proc != null) { 8173 if (false) { 8174 if (cpr.name.flattenToShortString().equals( 8175 "com.android.providers.calendar/.CalendarProvider2")) { 8176 Slog.v(TAG, "****************** KILLING " 8177 + cpr.name.flattenToShortString()); 8178 Process.killProcess(cpr.proc.pid); 8179 } 8180 } 8181 boolean success = updateOomAdjLocked(cpr.proc); 8182 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8183 // NOTE: there is still a race here where a signal could be 8184 // pending on the process even though we managed to update its 8185 // adj level. Not sure what to do about this, but at least 8186 // the race is now smaller. 8187 if (!success) { 8188 // Uh oh... it looks like the provider's process 8189 // has been killed on us. We need to wait for a new 8190 // process to be started, and make sure its death 8191 // doesn't kill our process. 8192 Slog.i(TAG, 8193 "Existing provider " + cpr.name.flattenToShortString() 8194 + " is crashing; detaching " + r); 8195 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8196 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8197 if (!lastRef) { 8198 // This wasn't the last ref our process had on 8199 // the provider... we have now been killed, bail. 8200 return null; 8201 } 8202 providerRunning = false; 8203 conn = null; 8204 } 8205 } 8206 8207 Binder.restoreCallingIdentity(origId); 8208 } 8209 8210 boolean singleton; 8211 if (!providerRunning) { 8212 try { 8213 cpi = AppGlobals.getPackageManager(). 8214 resolveContentProvider(name, 8215 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8216 } catch (RemoteException ex) { 8217 } 8218 if (cpi == null) { 8219 return null; 8220 } 8221 // If the provider is a singleton AND 8222 // (it's a call within the same user || the provider is a 8223 // privileged app) 8224 // Then allow connecting to the singleton provider 8225 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8226 cpi.name, cpi.flags) 8227 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8228 if (singleton) { 8229 userId = UserHandle.USER_OWNER; 8230 } 8231 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8232 8233 String msg; 8234 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8235 != null) { 8236 throw new SecurityException(msg); 8237 } 8238 8239 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8240 && !cpi.processName.equals("system")) { 8241 // If this content provider does not run in the system 8242 // process, and the system is not yet ready to run other 8243 // processes, then fail fast instead of hanging. 8244 throw new IllegalArgumentException( 8245 "Attempt to launch content provider before system ready"); 8246 } 8247 8248 // Make sure that the user who owns this provider is started. If not, 8249 // we don't want to allow it to run. 8250 if (mStartedUsers.get(userId) == null) { 8251 Slog.w(TAG, "Unable to launch app " 8252 + cpi.applicationInfo.packageName + "/" 8253 + cpi.applicationInfo.uid + " for provider " 8254 + name + ": user " + userId + " is stopped"); 8255 return null; 8256 } 8257 8258 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8259 cpr = mProviderMap.getProviderByClass(comp, userId); 8260 final boolean firstClass = cpr == null; 8261 if (firstClass) { 8262 try { 8263 ApplicationInfo ai = 8264 AppGlobals.getPackageManager(). 8265 getApplicationInfo( 8266 cpi.applicationInfo.packageName, 8267 STOCK_PM_FLAGS, userId); 8268 if (ai == null) { 8269 Slog.w(TAG, "No package info for content provider " 8270 + cpi.name); 8271 return null; 8272 } 8273 ai = getAppInfoForUser(ai, userId); 8274 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8275 } catch (RemoteException ex) { 8276 // pm is in same process, this will never happen. 8277 } 8278 } 8279 8280 if (r != null && cpr.canRunHere(r)) { 8281 // If this is a multiprocess provider, then just return its 8282 // info and allow the caller to instantiate it. Only do 8283 // this if the provider is the same user as the caller's 8284 // process, or can run as root (so can be in any process). 8285 return cpr.newHolder(null); 8286 } 8287 8288 if (DEBUG_PROVIDER) { 8289 RuntimeException e = new RuntimeException("here"); 8290 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8291 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8292 } 8293 8294 // This is single process, and our app is now connecting to it. 8295 // See if we are already in the process of launching this 8296 // provider. 8297 final int N = mLaunchingProviders.size(); 8298 int i; 8299 for (i=0; i<N; i++) { 8300 if (mLaunchingProviders.get(i) == cpr) { 8301 break; 8302 } 8303 } 8304 8305 // If the provider is not already being launched, then get it 8306 // started. 8307 if (i >= N) { 8308 final long origId = Binder.clearCallingIdentity(); 8309 8310 try { 8311 // Content provider is now in use, its package can't be stopped. 8312 try { 8313 AppGlobals.getPackageManager().setPackageStoppedState( 8314 cpr.appInfo.packageName, false, userId); 8315 } catch (RemoteException e) { 8316 } catch (IllegalArgumentException e) { 8317 Slog.w(TAG, "Failed trying to unstop package " 8318 + cpr.appInfo.packageName + ": " + e); 8319 } 8320 8321 // Use existing process if already started 8322 ProcessRecord proc = getProcessRecordLocked( 8323 cpi.processName, cpr.appInfo.uid, false); 8324 if (proc != null && proc.thread != null) { 8325 if (DEBUG_PROVIDER) { 8326 Slog.d(TAG, "Installing in existing process " + proc); 8327 } 8328 proc.pubProviders.put(cpi.name, cpr); 8329 try { 8330 proc.thread.scheduleInstallProvider(cpi); 8331 } catch (RemoteException e) { 8332 } 8333 } else { 8334 proc = startProcessLocked(cpi.processName, 8335 cpr.appInfo, false, 0, "content provider", 8336 new ComponentName(cpi.applicationInfo.packageName, 8337 cpi.name), false, false, false); 8338 if (proc == null) { 8339 Slog.w(TAG, "Unable to launch app " 8340 + cpi.applicationInfo.packageName + "/" 8341 + cpi.applicationInfo.uid + " for provider " 8342 + name + ": process is bad"); 8343 return null; 8344 } 8345 } 8346 cpr.launchingApp = proc; 8347 mLaunchingProviders.add(cpr); 8348 } finally { 8349 Binder.restoreCallingIdentity(origId); 8350 } 8351 } 8352 8353 // Make sure the provider is published (the same provider class 8354 // may be published under multiple names). 8355 if (firstClass) { 8356 mProviderMap.putProviderByClass(comp, cpr); 8357 } 8358 8359 mProviderMap.putProviderByName(name, cpr); 8360 conn = incProviderCountLocked(r, cpr, token, stable); 8361 if (conn != null) { 8362 conn.waiting = true; 8363 } 8364 } 8365 } 8366 8367 // Wait for the provider to be published... 8368 synchronized (cpr) { 8369 while (cpr.provider == null) { 8370 if (cpr.launchingApp == null) { 8371 Slog.w(TAG, "Unable to launch app " 8372 + cpi.applicationInfo.packageName + "/" 8373 + cpi.applicationInfo.uid + " for provider " 8374 + name + ": launching app became null"); 8375 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8376 UserHandle.getUserId(cpi.applicationInfo.uid), 8377 cpi.applicationInfo.packageName, 8378 cpi.applicationInfo.uid, name); 8379 return null; 8380 } 8381 try { 8382 if (DEBUG_MU) { 8383 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8384 + cpr.launchingApp); 8385 } 8386 if (conn != null) { 8387 conn.waiting = true; 8388 } 8389 cpr.wait(); 8390 } catch (InterruptedException ex) { 8391 } finally { 8392 if (conn != null) { 8393 conn.waiting = false; 8394 } 8395 } 8396 } 8397 } 8398 return cpr != null ? cpr.newHolder(conn) : null; 8399 } 8400 8401 @Override 8402 public final ContentProviderHolder getContentProvider( 8403 IApplicationThread caller, String name, int userId, boolean stable) { 8404 enforceNotIsolatedCaller("getContentProvider"); 8405 if (caller == null) { 8406 String msg = "null IApplicationThread when getting content provider " 8407 + name; 8408 Slog.w(TAG, msg); 8409 throw new SecurityException(msg); 8410 } 8411 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8412 // with cross-user grant. 8413 return getContentProviderImpl(caller, name, null, stable, userId); 8414 } 8415 8416 public ContentProviderHolder getContentProviderExternal( 8417 String name, int userId, IBinder token) { 8418 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8419 "Do not have permission in call getContentProviderExternal()"); 8420 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8421 false, true, "getContentProvider", null); 8422 return getContentProviderExternalUnchecked(name, token, userId); 8423 } 8424 8425 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8426 IBinder token, int userId) { 8427 return getContentProviderImpl(null, name, token, true, userId); 8428 } 8429 8430 /** 8431 * Drop a content provider from a ProcessRecord's bookkeeping 8432 */ 8433 public void removeContentProvider(IBinder connection, boolean stable) { 8434 enforceNotIsolatedCaller("removeContentProvider"); 8435 long ident = Binder.clearCallingIdentity(); 8436 try { 8437 synchronized (this) { 8438 ContentProviderConnection conn; 8439 try { 8440 conn = (ContentProviderConnection)connection; 8441 } catch (ClassCastException e) { 8442 String msg ="removeContentProvider: " + connection 8443 + " not a ContentProviderConnection"; 8444 Slog.w(TAG, msg); 8445 throw new IllegalArgumentException(msg); 8446 } 8447 if (conn == null) { 8448 throw new NullPointerException("connection is null"); 8449 } 8450 if (decProviderCountLocked(conn, null, null, stable)) { 8451 updateOomAdjLocked(); 8452 } 8453 } 8454 } finally { 8455 Binder.restoreCallingIdentity(ident); 8456 } 8457 } 8458 8459 public void removeContentProviderExternal(String name, IBinder token) { 8460 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8461 "Do not have permission in call removeContentProviderExternal()"); 8462 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8463 } 8464 8465 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8466 synchronized (this) { 8467 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8468 if(cpr == null) { 8469 //remove from mProvidersByClass 8470 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8471 return; 8472 } 8473 8474 //update content provider record entry info 8475 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8476 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8477 if (localCpr.hasExternalProcessHandles()) { 8478 if (localCpr.removeExternalProcessHandleLocked(token)) { 8479 updateOomAdjLocked(); 8480 } else { 8481 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8482 + " with no external reference for token: " 8483 + token + "."); 8484 } 8485 } else { 8486 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8487 + " with no external references."); 8488 } 8489 } 8490 } 8491 8492 public final void publishContentProviders(IApplicationThread caller, 8493 List<ContentProviderHolder> providers) { 8494 if (providers == null) { 8495 return; 8496 } 8497 8498 enforceNotIsolatedCaller("publishContentProviders"); 8499 synchronized (this) { 8500 final ProcessRecord r = getRecordForAppLocked(caller); 8501 if (DEBUG_MU) 8502 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8503 if (r == null) { 8504 throw new SecurityException( 8505 "Unable to find app for caller " + caller 8506 + " (pid=" + Binder.getCallingPid() 8507 + ") when publishing content providers"); 8508 } 8509 8510 final long origId = Binder.clearCallingIdentity(); 8511 8512 final int N = providers.size(); 8513 for (int i=0; i<N; i++) { 8514 ContentProviderHolder src = providers.get(i); 8515 if (src == null || src.info == null || src.provider == null) { 8516 continue; 8517 } 8518 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8519 if (DEBUG_MU) 8520 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8521 if (dst != null) { 8522 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8523 mProviderMap.putProviderByClass(comp, dst); 8524 String names[] = dst.info.authority.split(";"); 8525 for (int j = 0; j < names.length; j++) { 8526 mProviderMap.putProviderByName(names[j], dst); 8527 } 8528 8529 int NL = mLaunchingProviders.size(); 8530 int j; 8531 for (j=0; j<NL; j++) { 8532 if (mLaunchingProviders.get(j) == dst) { 8533 mLaunchingProviders.remove(j); 8534 j--; 8535 NL--; 8536 } 8537 } 8538 synchronized (dst) { 8539 dst.provider = src.provider; 8540 dst.proc = r; 8541 dst.notifyAll(); 8542 } 8543 updateOomAdjLocked(r); 8544 } 8545 } 8546 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 8551 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8552 ContentProviderConnection conn; 8553 try { 8554 conn = (ContentProviderConnection)connection; 8555 } catch (ClassCastException e) { 8556 String msg ="refContentProvider: " + connection 8557 + " not a ContentProviderConnection"; 8558 Slog.w(TAG, msg); 8559 throw new IllegalArgumentException(msg); 8560 } 8561 if (conn == null) { 8562 throw new NullPointerException("connection is null"); 8563 } 8564 8565 synchronized (this) { 8566 if (stable > 0) { 8567 conn.numStableIncs += stable; 8568 } 8569 stable = conn.stableCount + stable; 8570 if (stable < 0) { 8571 throw new IllegalStateException("stableCount < 0: " + stable); 8572 } 8573 8574 if (unstable > 0) { 8575 conn.numUnstableIncs += unstable; 8576 } 8577 unstable = conn.unstableCount + unstable; 8578 if (unstable < 0) { 8579 throw new IllegalStateException("unstableCount < 0: " + unstable); 8580 } 8581 8582 if ((stable+unstable) <= 0) { 8583 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8584 + stable + " unstable=" + unstable); 8585 } 8586 conn.stableCount = stable; 8587 conn.unstableCount = unstable; 8588 return !conn.dead; 8589 } 8590 } 8591 8592 public void unstableProviderDied(IBinder connection) { 8593 ContentProviderConnection conn; 8594 try { 8595 conn = (ContentProviderConnection)connection; 8596 } catch (ClassCastException e) { 8597 String msg ="refContentProvider: " + connection 8598 + " not a ContentProviderConnection"; 8599 Slog.w(TAG, msg); 8600 throw new IllegalArgumentException(msg); 8601 } 8602 if (conn == null) { 8603 throw new NullPointerException("connection is null"); 8604 } 8605 8606 // Safely retrieve the content provider associated with the connection. 8607 IContentProvider provider; 8608 synchronized (this) { 8609 provider = conn.provider.provider; 8610 } 8611 8612 if (provider == null) { 8613 // Um, yeah, we're way ahead of you. 8614 return; 8615 } 8616 8617 // Make sure the caller is being honest with us. 8618 if (provider.asBinder().pingBinder()) { 8619 // Er, no, still looks good to us. 8620 synchronized (this) { 8621 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8622 + " says " + conn + " died, but we don't agree"); 8623 return; 8624 } 8625 } 8626 8627 // Well look at that! It's dead! 8628 synchronized (this) { 8629 if (conn.provider.provider != provider) { 8630 // But something changed... good enough. 8631 return; 8632 } 8633 8634 ProcessRecord proc = conn.provider.proc; 8635 if (proc == null || proc.thread == null) { 8636 // Seems like the process is already cleaned up. 8637 return; 8638 } 8639 8640 // As far as we're concerned, this is just like receiving a 8641 // death notification... just a bit prematurely. 8642 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8643 + ") early provider death"); 8644 final long ident = Binder.clearCallingIdentity(); 8645 try { 8646 appDiedLocked(proc, proc.pid, proc.thread); 8647 } finally { 8648 Binder.restoreCallingIdentity(ident); 8649 } 8650 } 8651 } 8652 8653 @Override 8654 public void appNotRespondingViaProvider(IBinder connection) { 8655 enforceCallingPermission( 8656 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8657 8658 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8659 if (conn == null) { 8660 Slog.w(TAG, "ContentProviderConnection is null"); 8661 return; 8662 } 8663 8664 final ProcessRecord host = conn.provider.proc; 8665 if (host == null) { 8666 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8667 return; 8668 } 8669 8670 final long token = Binder.clearCallingIdentity(); 8671 try { 8672 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8673 } finally { 8674 Binder.restoreCallingIdentity(token); 8675 } 8676 } 8677 8678 public final void installSystemProviders() { 8679 List<ProviderInfo> providers; 8680 synchronized (this) { 8681 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8682 providers = generateApplicationProvidersLocked(app); 8683 if (providers != null) { 8684 for (int i=providers.size()-1; i>=0; i--) { 8685 ProviderInfo pi = (ProviderInfo)providers.get(i); 8686 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8687 Slog.w(TAG, "Not installing system proc provider " + pi.name 8688 + ": not system .apk"); 8689 providers.remove(i); 8690 } 8691 } 8692 } 8693 } 8694 if (providers != null) { 8695 mSystemThread.installSystemProviders(providers); 8696 } 8697 8698 mCoreSettingsObserver = new CoreSettingsObserver(this); 8699 8700 mUsageStatsService.monitorPackages(); 8701 } 8702 8703 /** 8704 * Allows app to retrieve the MIME type of a URI without having permission 8705 * to access its content provider. 8706 * 8707 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8708 * 8709 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8710 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8711 */ 8712 public String getProviderMimeType(Uri uri, int userId) { 8713 enforceNotIsolatedCaller("getProviderMimeType"); 8714 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8715 userId, false, true, "getProviderMimeType", null); 8716 final String name = uri.getAuthority(); 8717 final long ident = Binder.clearCallingIdentity(); 8718 ContentProviderHolder holder = null; 8719 8720 try { 8721 holder = getContentProviderExternalUnchecked(name, null, userId); 8722 if (holder != null) { 8723 return holder.provider.getType(uri); 8724 } 8725 } catch (RemoteException e) { 8726 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8727 return null; 8728 } finally { 8729 if (holder != null) { 8730 removeContentProviderExternalUnchecked(name, null, userId); 8731 } 8732 Binder.restoreCallingIdentity(ident); 8733 } 8734 8735 return null; 8736 } 8737 8738 // ========================================================= 8739 // GLOBAL MANAGEMENT 8740 // ========================================================= 8741 8742 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8743 boolean isolated) { 8744 String proc = customProcess != null ? customProcess : info.processName; 8745 BatteryStatsImpl.Uid.Proc ps = null; 8746 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8747 int uid = info.uid; 8748 if (isolated) { 8749 int userId = UserHandle.getUserId(uid); 8750 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8751 while (true) { 8752 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8753 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8754 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8755 } 8756 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8757 mNextIsolatedProcessUid++; 8758 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8759 // No process for this uid, use it. 8760 break; 8761 } 8762 stepsLeft--; 8763 if (stepsLeft <= 0) { 8764 return null; 8765 } 8766 } 8767 } 8768 return new ProcessRecord(stats, info, proc, uid); 8769 } 8770 8771 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8772 String abiOverride) { 8773 ProcessRecord app; 8774 if (!isolated) { 8775 app = getProcessRecordLocked(info.processName, info.uid, true); 8776 } else { 8777 app = null; 8778 } 8779 8780 if (app == null) { 8781 app = newProcessRecordLocked(info, null, isolated); 8782 mProcessNames.put(info.processName, app.uid, app); 8783 if (isolated) { 8784 mIsolatedProcesses.put(app.uid, app); 8785 } 8786 updateLruProcessLocked(app, false, null); 8787 updateOomAdjLocked(); 8788 } 8789 8790 // This package really, really can not be stopped. 8791 try { 8792 AppGlobals.getPackageManager().setPackageStoppedState( 8793 info.packageName, false, UserHandle.getUserId(app.uid)); 8794 } catch (RemoteException e) { 8795 } catch (IllegalArgumentException e) { 8796 Slog.w(TAG, "Failed trying to unstop package " 8797 + info.packageName + ": " + e); 8798 } 8799 8800 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8801 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8802 app.persistent = true; 8803 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8804 } 8805 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8806 mPersistentStartingProcesses.add(app); 8807 startProcessLocked(app, "added application", app.processName, 8808 abiOverride); 8809 } 8810 8811 return app; 8812 } 8813 8814 public void unhandledBack() { 8815 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8816 "unhandledBack()"); 8817 8818 synchronized(this) { 8819 final long origId = Binder.clearCallingIdentity(); 8820 try { 8821 getFocusedStack().unhandledBackLocked(); 8822 } finally { 8823 Binder.restoreCallingIdentity(origId); 8824 } 8825 } 8826 } 8827 8828 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8829 enforceNotIsolatedCaller("openContentUri"); 8830 final int userId = UserHandle.getCallingUserId(); 8831 String name = uri.getAuthority(); 8832 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8833 ParcelFileDescriptor pfd = null; 8834 if (cph != null) { 8835 // We record the binder invoker's uid in thread-local storage before 8836 // going to the content provider to open the file. Later, in the code 8837 // that handles all permissions checks, we look for this uid and use 8838 // that rather than the Activity Manager's own uid. The effect is that 8839 // we do the check against the caller's permissions even though it looks 8840 // to the content provider like the Activity Manager itself is making 8841 // the request. 8842 sCallerIdentity.set(new Identity( 8843 Binder.getCallingPid(), Binder.getCallingUid())); 8844 try { 8845 pfd = cph.provider.openFile(null, uri, "r", null); 8846 } catch (FileNotFoundException e) { 8847 // do nothing; pfd will be returned null 8848 } finally { 8849 // Ensure that whatever happens, we clean up the identity state 8850 sCallerIdentity.remove(); 8851 } 8852 8853 // We've got the fd now, so we're done with the provider. 8854 removeContentProviderExternalUnchecked(name, null, userId); 8855 } else { 8856 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8857 } 8858 return pfd; 8859 } 8860 8861 // Actually is sleeping or shutting down or whatever else in the future 8862 // is an inactive state. 8863 public boolean isSleepingOrShuttingDown() { 8864 return mSleeping || mShuttingDown; 8865 } 8866 8867 public boolean isSleeping() { 8868 return mSleeping; 8869 } 8870 8871 void goingToSleep() { 8872 synchronized(this) { 8873 mWentToSleep = true; 8874 updateEventDispatchingLocked(); 8875 goToSleepIfNeededLocked(); 8876 } 8877 } 8878 8879 void finishRunningVoiceLocked() { 8880 if (mRunningVoice) { 8881 mRunningVoice = false; 8882 goToSleepIfNeededLocked(); 8883 } 8884 } 8885 8886 void goToSleepIfNeededLocked() { 8887 if (mWentToSleep && !mRunningVoice) { 8888 if (!mSleeping) { 8889 mSleeping = true; 8890 mStackSupervisor.goingToSleepLocked(); 8891 8892 // Initialize the wake times of all processes. 8893 checkExcessivePowerUsageLocked(false); 8894 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8895 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8896 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8897 } 8898 } 8899 } 8900 8901 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8902 mTaskPersister.notify(task, flush); 8903 } 8904 8905 @Override 8906 public boolean shutdown(int timeout) { 8907 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8908 != PackageManager.PERMISSION_GRANTED) { 8909 throw new SecurityException("Requires permission " 8910 + android.Manifest.permission.SHUTDOWN); 8911 } 8912 8913 boolean timedout = false; 8914 8915 synchronized(this) { 8916 mShuttingDown = true; 8917 updateEventDispatchingLocked(); 8918 timedout = mStackSupervisor.shutdownLocked(timeout); 8919 } 8920 8921 mAppOpsService.shutdown(); 8922 mUsageStatsService.shutdown(); 8923 mBatteryStatsService.shutdown(); 8924 synchronized (this) { 8925 mProcessStats.shutdownLocked(); 8926 } 8927 notifyTaskPersisterLocked(null, true); 8928 8929 return timedout; 8930 } 8931 8932 public final void activitySlept(IBinder token) { 8933 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8934 8935 final long origId = Binder.clearCallingIdentity(); 8936 8937 synchronized (this) { 8938 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8939 if (r != null) { 8940 mStackSupervisor.activitySleptLocked(r); 8941 } 8942 } 8943 8944 Binder.restoreCallingIdentity(origId); 8945 } 8946 8947 void logLockScreen(String msg) { 8948 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8949 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8950 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8951 mStackSupervisor.mDismissKeyguardOnNextActivity); 8952 } 8953 8954 private void comeOutOfSleepIfNeededLocked() { 8955 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8956 if (mSleeping) { 8957 mSleeping = false; 8958 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8959 } 8960 } 8961 } 8962 8963 void wakingUp() { 8964 synchronized(this) { 8965 mWentToSleep = false; 8966 updateEventDispatchingLocked(); 8967 comeOutOfSleepIfNeededLocked(); 8968 } 8969 } 8970 8971 void startRunningVoiceLocked() { 8972 if (!mRunningVoice) { 8973 mRunningVoice = true; 8974 comeOutOfSleepIfNeededLocked(); 8975 } 8976 } 8977 8978 private void updateEventDispatchingLocked() { 8979 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8980 } 8981 8982 public void setLockScreenShown(boolean shown) { 8983 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8984 != PackageManager.PERMISSION_GRANTED) { 8985 throw new SecurityException("Requires permission " 8986 + android.Manifest.permission.DEVICE_POWER); 8987 } 8988 8989 synchronized(this) { 8990 long ident = Binder.clearCallingIdentity(); 8991 try { 8992 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8993 mLockScreenShown = shown; 8994 comeOutOfSleepIfNeededLocked(); 8995 } finally { 8996 Binder.restoreCallingIdentity(ident); 8997 } 8998 } 8999 } 9000 9001 public void stopAppSwitches() { 9002 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9003 != PackageManager.PERMISSION_GRANTED) { 9004 throw new SecurityException("Requires permission " 9005 + android.Manifest.permission.STOP_APP_SWITCHES); 9006 } 9007 9008 synchronized(this) { 9009 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9010 + APP_SWITCH_DELAY_TIME; 9011 mDidAppSwitch = false; 9012 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9013 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9014 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9015 } 9016 } 9017 9018 public void resumeAppSwitches() { 9019 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9020 != PackageManager.PERMISSION_GRANTED) { 9021 throw new SecurityException("Requires permission " 9022 + android.Manifest.permission.STOP_APP_SWITCHES); 9023 } 9024 9025 synchronized(this) { 9026 // Note that we don't execute any pending app switches... we will 9027 // let those wait until either the timeout, or the next start 9028 // activity request. 9029 mAppSwitchesAllowedTime = 0; 9030 } 9031 } 9032 9033 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9034 String name) { 9035 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9036 return true; 9037 } 9038 9039 final int perm = checkComponentPermission( 9040 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9041 callingUid, -1, true); 9042 if (perm == PackageManager.PERMISSION_GRANTED) { 9043 return true; 9044 } 9045 9046 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9047 return false; 9048 } 9049 9050 public void setDebugApp(String packageName, boolean waitForDebugger, 9051 boolean persistent) { 9052 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9053 "setDebugApp()"); 9054 9055 long ident = Binder.clearCallingIdentity(); 9056 try { 9057 // Note that this is not really thread safe if there are multiple 9058 // callers into it at the same time, but that's not a situation we 9059 // care about. 9060 if (persistent) { 9061 final ContentResolver resolver = mContext.getContentResolver(); 9062 Settings.Global.putString( 9063 resolver, Settings.Global.DEBUG_APP, 9064 packageName); 9065 Settings.Global.putInt( 9066 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9067 waitForDebugger ? 1 : 0); 9068 } 9069 9070 synchronized (this) { 9071 if (!persistent) { 9072 mOrigDebugApp = mDebugApp; 9073 mOrigWaitForDebugger = mWaitForDebugger; 9074 } 9075 mDebugApp = packageName; 9076 mWaitForDebugger = waitForDebugger; 9077 mDebugTransient = !persistent; 9078 if (packageName != null) { 9079 forceStopPackageLocked(packageName, -1, false, false, true, true, 9080 false, UserHandle.USER_ALL, "set debug app"); 9081 } 9082 } 9083 } finally { 9084 Binder.restoreCallingIdentity(ident); 9085 } 9086 } 9087 9088 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9089 synchronized (this) { 9090 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9091 if (!isDebuggable) { 9092 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9093 throw new SecurityException("Process not debuggable: " + app.packageName); 9094 } 9095 } 9096 9097 mOpenGlTraceApp = processName; 9098 } 9099 } 9100 9101 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9102 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9103 synchronized (this) { 9104 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9105 if (!isDebuggable) { 9106 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9107 throw new SecurityException("Process not debuggable: " + app.packageName); 9108 } 9109 } 9110 mProfileApp = processName; 9111 mProfileFile = profileFile; 9112 if (mProfileFd != null) { 9113 try { 9114 mProfileFd.close(); 9115 } catch (IOException e) { 9116 } 9117 mProfileFd = null; 9118 } 9119 mProfileFd = profileFd; 9120 mProfileType = 0; 9121 mAutoStopProfiler = autoStopProfiler; 9122 } 9123 } 9124 9125 @Override 9126 public void setAlwaysFinish(boolean enabled) { 9127 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9128 "setAlwaysFinish()"); 9129 9130 Settings.Global.putInt( 9131 mContext.getContentResolver(), 9132 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9133 9134 synchronized (this) { 9135 mAlwaysFinishActivities = enabled; 9136 } 9137 } 9138 9139 @Override 9140 public void setActivityController(IActivityController controller) { 9141 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9142 "setActivityController()"); 9143 synchronized (this) { 9144 mController = controller; 9145 Watchdog.getInstance().setActivityController(controller); 9146 } 9147 } 9148 9149 @Override 9150 public void setUserIsMonkey(boolean userIsMonkey) { 9151 synchronized (this) { 9152 synchronized (mPidsSelfLocked) { 9153 final int callingPid = Binder.getCallingPid(); 9154 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9155 if (precessRecord == null) { 9156 throw new SecurityException("Unknown process: " + callingPid); 9157 } 9158 if (precessRecord.instrumentationUiAutomationConnection == null) { 9159 throw new SecurityException("Only an instrumentation process " 9160 + "with a UiAutomation can call setUserIsMonkey"); 9161 } 9162 } 9163 mUserIsMonkey = userIsMonkey; 9164 } 9165 } 9166 9167 @Override 9168 public boolean isUserAMonkey() { 9169 synchronized (this) { 9170 // If there is a controller also implies the user is a monkey. 9171 return (mUserIsMonkey || mController != null); 9172 } 9173 } 9174 9175 public void requestBugReport() { 9176 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9177 SystemProperties.set("ctl.start", "bugreport"); 9178 } 9179 9180 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9181 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9182 } 9183 9184 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9185 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9186 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9187 } 9188 return KEY_DISPATCHING_TIMEOUT; 9189 } 9190 9191 @Override 9192 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9193 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9194 != PackageManager.PERMISSION_GRANTED) { 9195 throw new SecurityException("Requires permission " 9196 + android.Manifest.permission.FILTER_EVENTS); 9197 } 9198 ProcessRecord proc; 9199 long timeout; 9200 synchronized (this) { 9201 synchronized (mPidsSelfLocked) { 9202 proc = mPidsSelfLocked.get(pid); 9203 } 9204 timeout = getInputDispatchingTimeoutLocked(proc); 9205 } 9206 9207 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9208 return -1; 9209 } 9210 9211 return timeout; 9212 } 9213 9214 /** 9215 * Handle input dispatching timeouts. 9216 * Returns whether input dispatching should be aborted or not. 9217 */ 9218 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9219 final ActivityRecord activity, final ActivityRecord parent, 9220 final boolean aboveSystem, String reason) { 9221 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9222 != PackageManager.PERMISSION_GRANTED) { 9223 throw new SecurityException("Requires permission " 9224 + android.Manifest.permission.FILTER_EVENTS); 9225 } 9226 9227 final String annotation; 9228 if (reason == null) { 9229 annotation = "Input dispatching timed out"; 9230 } else { 9231 annotation = "Input dispatching timed out (" + reason + ")"; 9232 } 9233 9234 if (proc != null) { 9235 synchronized (this) { 9236 if (proc.debugging) { 9237 return false; 9238 } 9239 9240 if (mDidDexOpt) { 9241 // Give more time since we were dexopting. 9242 mDidDexOpt = false; 9243 return false; 9244 } 9245 9246 if (proc.instrumentationClass != null) { 9247 Bundle info = new Bundle(); 9248 info.putString("shortMsg", "keyDispatchingTimedOut"); 9249 info.putString("longMsg", annotation); 9250 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9251 return true; 9252 } 9253 } 9254 mHandler.post(new Runnable() { 9255 @Override 9256 public void run() { 9257 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9258 } 9259 }); 9260 } 9261 9262 return true; 9263 } 9264 9265 public Bundle getAssistContextExtras(int requestType) { 9266 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9267 "getAssistContextExtras()"); 9268 PendingAssistExtras pae; 9269 Bundle extras = new Bundle(); 9270 synchronized (this) { 9271 ActivityRecord activity = getFocusedStack().mResumedActivity; 9272 if (activity == null) { 9273 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9274 return null; 9275 } 9276 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9277 if (activity.app == null || activity.app.thread == null) { 9278 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9279 return extras; 9280 } 9281 if (activity.app.pid == Binder.getCallingPid()) { 9282 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9283 return extras; 9284 } 9285 pae = new PendingAssistExtras(activity); 9286 try { 9287 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9288 requestType); 9289 mPendingAssistExtras.add(pae); 9290 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9291 } catch (RemoteException e) { 9292 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9293 return extras; 9294 } 9295 } 9296 synchronized (pae) { 9297 while (!pae.haveResult) { 9298 try { 9299 pae.wait(); 9300 } catch (InterruptedException e) { 9301 } 9302 } 9303 if (pae.result != null) { 9304 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9305 } 9306 } 9307 synchronized (this) { 9308 mPendingAssistExtras.remove(pae); 9309 mHandler.removeCallbacks(pae); 9310 } 9311 return extras; 9312 } 9313 9314 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9315 PendingAssistExtras pae = (PendingAssistExtras)token; 9316 synchronized (pae) { 9317 pae.result = extras; 9318 pae.haveResult = true; 9319 pae.notifyAll(); 9320 } 9321 } 9322 9323 public void registerProcessObserver(IProcessObserver observer) { 9324 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9325 "registerProcessObserver()"); 9326 synchronized (this) { 9327 mProcessObservers.register(observer); 9328 } 9329 } 9330 9331 @Override 9332 public void unregisterProcessObserver(IProcessObserver observer) { 9333 synchronized (this) { 9334 mProcessObservers.unregister(observer); 9335 } 9336 } 9337 9338 @Override 9339 public boolean convertFromTranslucent(IBinder token) { 9340 final long origId = Binder.clearCallingIdentity(); 9341 try { 9342 synchronized (this) { 9343 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9344 if (r == null) { 9345 return false; 9346 } 9347 if (r.changeWindowTranslucency(true)) { 9348 mWindowManager.setAppFullscreen(token, true); 9349 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9350 return true; 9351 } 9352 return false; 9353 } 9354 } finally { 9355 Binder.restoreCallingIdentity(origId); 9356 } 9357 } 9358 9359 @Override 9360 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9361 final long origId = Binder.clearCallingIdentity(); 9362 try { 9363 synchronized (this) { 9364 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9365 if (r == null) { 9366 return false; 9367 } 9368 if (r.changeWindowTranslucency(false)) { 9369 r.task.stack.convertToTranslucent(r, options); 9370 mWindowManager.setAppFullscreen(token, false); 9371 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9372 return true; 9373 } 9374 return false; 9375 } 9376 } finally { 9377 Binder.restoreCallingIdentity(origId); 9378 } 9379 } 9380 9381 @Override 9382 public ActivityOptions getActivityOptions(IBinder token) { 9383 final long origId = Binder.clearCallingIdentity(); 9384 try { 9385 synchronized (this) { 9386 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9387 if (r != null) { 9388 final ActivityOptions activityOptions = r.pendingOptions; 9389 r.pendingOptions = null; 9390 return activityOptions; 9391 } 9392 return null; 9393 } 9394 } finally { 9395 Binder.restoreCallingIdentity(origId); 9396 } 9397 } 9398 9399 @Override 9400 public void setImmersive(IBinder token, boolean immersive) { 9401 synchronized(this) { 9402 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9403 if (r == null) { 9404 throw new IllegalArgumentException(); 9405 } 9406 r.immersive = immersive; 9407 9408 // update associated state if we're frontmost 9409 if (r == mFocusedActivity) { 9410 if (DEBUG_IMMERSIVE) { 9411 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9412 } 9413 applyUpdateLockStateLocked(r); 9414 } 9415 } 9416 } 9417 9418 @Override 9419 public boolean isImmersive(IBinder token) { 9420 synchronized (this) { 9421 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9422 if (r == null) { 9423 throw new IllegalArgumentException(); 9424 } 9425 return r.immersive; 9426 } 9427 } 9428 9429 public boolean isTopActivityImmersive() { 9430 enforceNotIsolatedCaller("startActivity"); 9431 synchronized (this) { 9432 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9433 return (r != null) ? r.immersive : false; 9434 } 9435 } 9436 9437 public final void enterSafeMode() { 9438 synchronized(this) { 9439 // It only makes sense to do this before the system is ready 9440 // and started launching other packages. 9441 if (!mSystemReady) { 9442 try { 9443 AppGlobals.getPackageManager().enterSafeMode(); 9444 } catch (RemoteException e) { 9445 } 9446 } 9447 9448 mSafeMode = true; 9449 } 9450 } 9451 9452 public final void showSafeModeOverlay() { 9453 View v = LayoutInflater.from(mContext).inflate( 9454 com.android.internal.R.layout.safe_mode, null); 9455 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9456 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9457 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9458 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9459 lp.gravity = Gravity.BOTTOM | Gravity.START; 9460 lp.format = v.getBackground().getOpacity(); 9461 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9462 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9463 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9464 ((WindowManager)mContext.getSystemService( 9465 Context.WINDOW_SERVICE)).addView(v, lp); 9466 } 9467 9468 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9469 if (!(sender instanceof PendingIntentRecord)) { 9470 return; 9471 } 9472 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9473 synchronized (stats) { 9474 if (mBatteryStatsService.isOnBattery()) { 9475 mBatteryStatsService.enforceCallingPermission(); 9476 PendingIntentRecord rec = (PendingIntentRecord)sender; 9477 int MY_UID = Binder.getCallingUid(); 9478 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9479 BatteryStatsImpl.Uid.Pkg pkg = 9480 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9481 sourcePkg != null ? sourcePkg : rec.key.packageName); 9482 pkg.incWakeupsLocked(); 9483 } 9484 } 9485 } 9486 9487 public boolean killPids(int[] pids, String pReason, boolean secure) { 9488 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9489 throw new SecurityException("killPids only available to the system"); 9490 } 9491 String reason = (pReason == null) ? "Unknown" : pReason; 9492 // XXX Note: don't acquire main activity lock here, because the window 9493 // manager calls in with its locks held. 9494 9495 boolean killed = false; 9496 synchronized (mPidsSelfLocked) { 9497 int[] types = new int[pids.length]; 9498 int worstType = 0; 9499 for (int i=0; i<pids.length; i++) { 9500 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9501 if (proc != null) { 9502 int type = proc.setAdj; 9503 types[i] = type; 9504 if (type > worstType) { 9505 worstType = type; 9506 } 9507 } 9508 } 9509 9510 // If the worst oom_adj is somewhere in the cached proc LRU range, 9511 // then constrain it so we will kill all cached procs. 9512 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9513 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9514 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9515 } 9516 9517 // If this is not a secure call, don't let it kill processes that 9518 // are important. 9519 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9520 worstType = ProcessList.SERVICE_ADJ; 9521 } 9522 9523 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9524 for (int i=0; i<pids.length; i++) { 9525 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9526 if (proc == null) { 9527 continue; 9528 } 9529 int adj = proc.setAdj; 9530 if (adj >= worstType && !proc.killedByAm) { 9531 killUnneededProcessLocked(proc, reason); 9532 killed = true; 9533 } 9534 } 9535 } 9536 return killed; 9537 } 9538 9539 @Override 9540 public void killUid(int uid, String reason) { 9541 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9542 throw new SecurityException("killUid only available to the system"); 9543 } 9544 synchronized (this) { 9545 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9546 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9547 reason != null ? reason : "kill uid"); 9548 } 9549 } 9550 9551 @Override 9552 public boolean killProcessesBelowForeground(String reason) { 9553 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9554 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9555 } 9556 9557 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9558 } 9559 9560 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9561 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9562 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9563 } 9564 9565 boolean killed = false; 9566 synchronized (mPidsSelfLocked) { 9567 final int size = mPidsSelfLocked.size(); 9568 for (int i = 0; i < size; i++) { 9569 final int pid = mPidsSelfLocked.keyAt(i); 9570 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9571 if (proc == null) continue; 9572 9573 final int adj = proc.setAdj; 9574 if (adj > belowAdj && !proc.killedByAm) { 9575 killUnneededProcessLocked(proc, reason); 9576 killed = true; 9577 } 9578 } 9579 } 9580 return killed; 9581 } 9582 9583 @Override 9584 public void hang(final IBinder who, boolean allowRestart) { 9585 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9586 != PackageManager.PERMISSION_GRANTED) { 9587 throw new SecurityException("Requires permission " 9588 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9589 } 9590 9591 final IBinder.DeathRecipient death = new DeathRecipient() { 9592 @Override 9593 public void binderDied() { 9594 synchronized (this) { 9595 notifyAll(); 9596 } 9597 } 9598 }; 9599 9600 try { 9601 who.linkToDeath(death, 0); 9602 } catch (RemoteException e) { 9603 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9604 return; 9605 } 9606 9607 synchronized (this) { 9608 Watchdog.getInstance().setAllowRestart(allowRestart); 9609 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9610 synchronized (death) { 9611 while (who.isBinderAlive()) { 9612 try { 9613 death.wait(); 9614 } catch (InterruptedException e) { 9615 } 9616 } 9617 } 9618 Watchdog.getInstance().setAllowRestart(true); 9619 } 9620 } 9621 9622 @Override 9623 public void restart() { 9624 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9625 != PackageManager.PERMISSION_GRANTED) { 9626 throw new SecurityException("Requires permission " 9627 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9628 } 9629 9630 Log.i(TAG, "Sending shutdown broadcast..."); 9631 9632 BroadcastReceiver br = new BroadcastReceiver() { 9633 @Override public void onReceive(Context context, Intent intent) { 9634 // Now the broadcast is done, finish up the low-level shutdown. 9635 Log.i(TAG, "Shutting down activity manager..."); 9636 shutdown(10000); 9637 Log.i(TAG, "Shutdown complete, restarting!"); 9638 Process.killProcess(Process.myPid()); 9639 System.exit(10); 9640 } 9641 }; 9642 9643 // First send the high-level shut down broadcast. 9644 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9645 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9646 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9647 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9648 mContext.sendOrderedBroadcastAsUser(intent, 9649 UserHandle.ALL, null, br, mHandler, 0, null, null); 9650 */ 9651 br.onReceive(mContext, intent); 9652 } 9653 9654 private long getLowRamTimeSinceIdle(long now) { 9655 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9656 } 9657 9658 @Override 9659 public void performIdleMaintenance() { 9660 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9661 != PackageManager.PERMISSION_GRANTED) { 9662 throw new SecurityException("Requires permission " 9663 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9664 } 9665 9666 synchronized (this) { 9667 final long now = SystemClock.uptimeMillis(); 9668 final long timeSinceLastIdle = now - mLastIdleTime; 9669 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9670 mLastIdleTime = now; 9671 mLowRamTimeSinceLastIdle = 0; 9672 if (mLowRamStartTime != 0) { 9673 mLowRamStartTime = now; 9674 } 9675 9676 StringBuilder sb = new StringBuilder(128); 9677 sb.append("Idle maintenance over "); 9678 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9679 sb.append(" low RAM for "); 9680 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9681 Slog.i(TAG, sb.toString()); 9682 9683 // If at least 1/3 of our time since the last idle period has been spent 9684 // with RAM low, then we want to kill processes. 9685 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9686 9687 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9688 ProcessRecord proc = mLruProcesses.get(i); 9689 if (proc.notCachedSinceIdle) { 9690 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9691 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9692 if (doKilling && proc.initialIdlePss != 0 9693 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9694 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9695 + " from " + proc.initialIdlePss + ")"); 9696 } 9697 } 9698 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9699 proc.notCachedSinceIdle = true; 9700 proc.initialIdlePss = 0; 9701 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9702 isSleeping(), now); 9703 } 9704 } 9705 9706 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9707 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9708 } 9709 } 9710 9711 private void retrieveSettings() { 9712 final ContentResolver resolver = mContext.getContentResolver(); 9713 String debugApp = Settings.Global.getString( 9714 resolver, Settings.Global.DEBUG_APP); 9715 boolean waitForDebugger = Settings.Global.getInt( 9716 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9717 boolean alwaysFinishActivities = Settings.Global.getInt( 9718 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9719 boolean forceRtl = Settings.Global.getInt( 9720 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9721 // Transfer any global setting for forcing RTL layout, into a System Property 9722 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9723 9724 Configuration configuration = new Configuration(); 9725 Settings.System.getConfiguration(resolver, configuration); 9726 if (forceRtl) { 9727 // This will take care of setting the correct layout direction flags 9728 configuration.setLayoutDirection(configuration.locale); 9729 } 9730 9731 synchronized (this) { 9732 mDebugApp = mOrigDebugApp = debugApp; 9733 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9734 mAlwaysFinishActivities = alwaysFinishActivities; 9735 // This happens before any activities are started, so we can 9736 // change mConfiguration in-place. 9737 updateConfigurationLocked(configuration, null, false, true); 9738 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9739 } 9740 } 9741 9742 public boolean testIsSystemReady() { 9743 // no need to synchronize(this) just to read & return the value 9744 return mSystemReady; 9745 } 9746 9747 private static File getCalledPreBootReceiversFile() { 9748 File dataDir = Environment.getDataDirectory(); 9749 File systemDir = new File(dataDir, "system"); 9750 File fname = new File(systemDir, "called_pre_boots.dat"); 9751 return fname; 9752 } 9753 9754 static final int LAST_DONE_VERSION = 10000; 9755 9756 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9757 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9758 File file = getCalledPreBootReceiversFile(); 9759 FileInputStream fis = null; 9760 try { 9761 fis = new FileInputStream(file); 9762 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9763 int fvers = dis.readInt(); 9764 if (fvers == LAST_DONE_VERSION) { 9765 String vers = dis.readUTF(); 9766 String codename = dis.readUTF(); 9767 String build = dis.readUTF(); 9768 if (android.os.Build.VERSION.RELEASE.equals(vers) 9769 && android.os.Build.VERSION.CODENAME.equals(codename) 9770 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9771 int num = dis.readInt(); 9772 while (num > 0) { 9773 num--; 9774 String pkg = dis.readUTF(); 9775 String cls = dis.readUTF(); 9776 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9777 } 9778 } 9779 } 9780 } catch (FileNotFoundException e) { 9781 } catch (IOException e) { 9782 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9783 } finally { 9784 if (fis != null) { 9785 try { 9786 fis.close(); 9787 } catch (IOException e) { 9788 } 9789 } 9790 } 9791 return lastDoneReceivers; 9792 } 9793 9794 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9795 File file = getCalledPreBootReceiversFile(); 9796 FileOutputStream fos = null; 9797 DataOutputStream dos = null; 9798 try { 9799 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9800 fos = new FileOutputStream(file); 9801 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9802 dos.writeInt(LAST_DONE_VERSION); 9803 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9804 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9805 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9806 dos.writeInt(list.size()); 9807 for (int i=0; i<list.size(); i++) { 9808 dos.writeUTF(list.get(i).getPackageName()); 9809 dos.writeUTF(list.get(i).getClassName()); 9810 } 9811 } catch (IOException e) { 9812 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9813 file.delete(); 9814 } finally { 9815 FileUtils.sync(fos); 9816 if (dos != null) { 9817 try { 9818 dos.close(); 9819 } catch (IOException e) { 9820 // TODO Auto-generated catch block 9821 e.printStackTrace(); 9822 } 9823 } 9824 } 9825 } 9826 9827 public void systemReady(final Runnable goingCallback) { 9828 synchronized(this) { 9829 if (mSystemReady) { 9830 if (goingCallback != null) goingCallback.run(); 9831 return; 9832 } 9833 9834 if (mRecentTasks == null) { 9835 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9836 if (!mRecentTasks.isEmpty()) { 9837 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9838 } 9839 mTaskPersister.startPersisting(); 9840 } 9841 9842 // Check to see if there are any update receivers to run. 9843 if (!mDidUpdate) { 9844 if (mWaitingUpdate) { 9845 return; 9846 } 9847 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9848 List<ResolveInfo> ris = null; 9849 try { 9850 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9851 intent, null, 0, 0); 9852 } catch (RemoteException e) { 9853 } 9854 if (ris != null) { 9855 for (int i=ris.size()-1; i>=0; i--) { 9856 if ((ris.get(i).activityInfo.applicationInfo.flags 9857 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9858 ris.remove(i); 9859 } 9860 } 9861 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9862 9863 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9864 9865 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9866 for (int i=0; i<ris.size(); i++) { 9867 ActivityInfo ai = ris.get(i).activityInfo; 9868 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9869 if (lastDoneReceivers.contains(comp)) { 9870 // We already did the pre boot receiver for this app with the current 9871 // platform version, so don't do it again... 9872 ris.remove(i); 9873 i--; 9874 // ...however, do keep it as one that has been done, so we don't 9875 // forget about it when rewriting the file of last done receivers. 9876 doneReceivers.add(comp); 9877 } 9878 } 9879 9880 final int[] users = getUsersLocked(); 9881 for (int i=0; i<ris.size(); i++) { 9882 ActivityInfo ai = ris.get(i).activityInfo; 9883 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9884 doneReceivers.add(comp); 9885 intent.setComponent(comp); 9886 for (int j=0; j<users.length; j++) { 9887 IIntentReceiver finisher = null; 9888 if (i == ris.size()-1 && j == users.length-1) { 9889 finisher = new IIntentReceiver.Stub() { 9890 public void performReceive(Intent intent, int resultCode, 9891 String data, Bundle extras, boolean ordered, 9892 boolean sticky, int sendingUser) { 9893 // The raw IIntentReceiver interface is called 9894 // with the AM lock held, so redispatch to 9895 // execute our code without the lock. 9896 mHandler.post(new Runnable() { 9897 public void run() { 9898 synchronized (ActivityManagerService.this) { 9899 mDidUpdate = true; 9900 } 9901 writeLastDonePreBootReceivers(doneReceivers); 9902 showBootMessage(mContext.getText( 9903 R.string.android_upgrading_complete), 9904 false); 9905 systemReady(goingCallback); 9906 } 9907 }); 9908 } 9909 }; 9910 } 9911 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9912 + " for user " + users[j]); 9913 broadcastIntentLocked(null, null, intent, null, finisher, 9914 0, null, null, null, AppOpsManager.OP_NONE, 9915 true, false, MY_PID, Process.SYSTEM_UID, 9916 users[j]); 9917 if (finisher != null) { 9918 mWaitingUpdate = true; 9919 } 9920 } 9921 } 9922 } 9923 if (mWaitingUpdate) { 9924 return; 9925 } 9926 mDidUpdate = true; 9927 } 9928 9929 mAppOpsService.systemReady(); 9930 mUsageStatsService.systemReady(); 9931 mSystemReady = true; 9932 } 9933 9934 ArrayList<ProcessRecord> procsToKill = null; 9935 synchronized(mPidsSelfLocked) { 9936 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9937 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9938 if (!isAllowedWhileBooting(proc.info)){ 9939 if (procsToKill == null) { 9940 procsToKill = new ArrayList<ProcessRecord>(); 9941 } 9942 procsToKill.add(proc); 9943 } 9944 } 9945 } 9946 9947 synchronized(this) { 9948 if (procsToKill != null) { 9949 for (int i=procsToKill.size()-1; i>=0; i--) { 9950 ProcessRecord proc = procsToKill.get(i); 9951 Slog.i(TAG, "Removing system update proc: " + proc); 9952 removeProcessLocked(proc, true, false, "system update done"); 9953 } 9954 } 9955 9956 // Now that we have cleaned up any update processes, we 9957 // are ready to start launching real processes and know that 9958 // we won't trample on them any more. 9959 mProcessesReady = true; 9960 } 9961 9962 Slog.i(TAG, "System now ready"); 9963 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9964 SystemClock.uptimeMillis()); 9965 9966 synchronized(this) { 9967 // Make sure we have no pre-ready processes sitting around. 9968 9969 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9970 ResolveInfo ri = mContext.getPackageManager() 9971 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9972 STOCK_PM_FLAGS); 9973 CharSequence errorMsg = null; 9974 if (ri != null) { 9975 ActivityInfo ai = ri.activityInfo; 9976 ApplicationInfo app = ai.applicationInfo; 9977 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9978 mTopAction = Intent.ACTION_FACTORY_TEST; 9979 mTopData = null; 9980 mTopComponent = new ComponentName(app.packageName, 9981 ai.name); 9982 } else { 9983 errorMsg = mContext.getResources().getText( 9984 com.android.internal.R.string.factorytest_not_system); 9985 } 9986 } else { 9987 errorMsg = mContext.getResources().getText( 9988 com.android.internal.R.string.factorytest_no_action); 9989 } 9990 if (errorMsg != null) { 9991 mTopAction = null; 9992 mTopData = null; 9993 mTopComponent = null; 9994 Message msg = Message.obtain(); 9995 msg.what = SHOW_FACTORY_ERROR_MSG; 9996 msg.getData().putCharSequence("msg", errorMsg); 9997 mHandler.sendMessage(msg); 9998 } 9999 } 10000 } 10001 10002 retrieveSettings(); 10003 10004 synchronized (this) { 10005 readGrantedUriPermissionsLocked(); 10006 } 10007 10008 if (goingCallback != null) goingCallback.run(); 10009 10010 mSystemServiceManager.startUser(mCurrentUserId); 10011 10012 synchronized (this) { 10013 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10014 try { 10015 List apps = AppGlobals.getPackageManager(). 10016 getPersistentApplications(STOCK_PM_FLAGS); 10017 if (apps != null) { 10018 int N = apps.size(); 10019 int i; 10020 for (i=0; i<N; i++) { 10021 ApplicationInfo info 10022 = (ApplicationInfo)apps.get(i); 10023 if (info != null && 10024 !info.packageName.equals("android")) { 10025 addAppLocked(info, false, null /* ABI override */); 10026 } 10027 } 10028 } 10029 } catch (RemoteException ex) { 10030 // pm is in same process, this will never happen. 10031 } 10032 } 10033 10034 // Start up initial activity. 10035 mBooting = true; 10036 10037 try { 10038 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10039 Message msg = Message.obtain(); 10040 msg.what = SHOW_UID_ERROR_MSG; 10041 mHandler.sendMessage(msg); 10042 } 10043 } catch (RemoteException e) { 10044 } 10045 10046 long ident = Binder.clearCallingIdentity(); 10047 try { 10048 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10049 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10050 | Intent.FLAG_RECEIVER_FOREGROUND); 10051 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10052 broadcastIntentLocked(null, null, intent, 10053 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10054 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10055 intent = new Intent(Intent.ACTION_USER_STARTING); 10056 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10057 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10058 broadcastIntentLocked(null, null, intent, 10059 null, new IIntentReceiver.Stub() { 10060 @Override 10061 public void performReceive(Intent intent, int resultCode, String data, 10062 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10063 throws RemoteException { 10064 } 10065 }, 0, null, null, 10066 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10067 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10068 } catch (Throwable t) { 10069 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10070 } finally { 10071 Binder.restoreCallingIdentity(ident); 10072 } 10073 mStackSupervisor.resumeTopActivitiesLocked(); 10074 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10075 } 10076 } 10077 10078 private boolean makeAppCrashingLocked(ProcessRecord app, 10079 String shortMsg, String longMsg, String stackTrace) { 10080 app.crashing = true; 10081 app.crashingReport = generateProcessError(app, 10082 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10083 startAppProblemLocked(app); 10084 app.stopFreezingAllLocked(); 10085 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10086 } 10087 10088 private void makeAppNotRespondingLocked(ProcessRecord app, 10089 String activity, String shortMsg, String longMsg) { 10090 app.notResponding = true; 10091 app.notRespondingReport = generateProcessError(app, 10092 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10093 activity, shortMsg, longMsg, null); 10094 startAppProblemLocked(app); 10095 app.stopFreezingAllLocked(); 10096 } 10097 10098 /** 10099 * Generate a process error record, suitable for attachment to a ProcessRecord. 10100 * 10101 * @param app The ProcessRecord in which the error occurred. 10102 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10103 * ActivityManager.AppErrorStateInfo 10104 * @param activity The activity associated with the crash, if known. 10105 * @param shortMsg Short message describing the crash. 10106 * @param longMsg Long message describing the crash. 10107 * @param stackTrace Full crash stack trace, may be null. 10108 * 10109 * @return Returns a fully-formed AppErrorStateInfo record. 10110 */ 10111 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10112 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10113 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10114 10115 report.condition = condition; 10116 report.processName = app.processName; 10117 report.pid = app.pid; 10118 report.uid = app.info.uid; 10119 report.tag = activity; 10120 report.shortMsg = shortMsg; 10121 report.longMsg = longMsg; 10122 report.stackTrace = stackTrace; 10123 10124 return report; 10125 } 10126 10127 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10128 synchronized (this) { 10129 app.crashing = false; 10130 app.crashingReport = null; 10131 app.notResponding = false; 10132 app.notRespondingReport = null; 10133 if (app.anrDialog == fromDialog) { 10134 app.anrDialog = null; 10135 } 10136 if (app.waitDialog == fromDialog) { 10137 app.waitDialog = null; 10138 } 10139 if (app.pid > 0 && app.pid != MY_PID) { 10140 handleAppCrashLocked(app, null, null, null); 10141 killUnneededProcessLocked(app, "user request after error"); 10142 } 10143 } 10144 } 10145 10146 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10147 String stackTrace) { 10148 long now = SystemClock.uptimeMillis(); 10149 10150 Long crashTime; 10151 if (!app.isolated) { 10152 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10153 } else { 10154 crashTime = null; 10155 } 10156 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10157 // This process loses! 10158 Slog.w(TAG, "Process " + app.info.processName 10159 + " has crashed too many times: killing!"); 10160 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10161 app.userId, app.info.processName, app.uid); 10162 mStackSupervisor.handleAppCrashLocked(app); 10163 if (!app.persistent) { 10164 // We don't want to start this process again until the user 10165 // explicitly does so... but for persistent process, we really 10166 // need to keep it running. If a persistent process is actually 10167 // repeatedly crashing, then badness for everyone. 10168 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10169 app.info.processName); 10170 if (!app.isolated) { 10171 // XXX We don't have a way to mark isolated processes 10172 // as bad, since they don't have a peristent identity. 10173 mBadProcesses.put(app.info.processName, app.uid, 10174 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10175 mProcessCrashTimes.remove(app.info.processName, app.uid); 10176 } 10177 app.bad = true; 10178 app.removed = true; 10179 // Don't let services in this process be restarted and potentially 10180 // annoy the user repeatedly. Unless it is persistent, since those 10181 // processes run critical code. 10182 removeProcessLocked(app, false, false, "crash"); 10183 mStackSupervisor.resumeTopActivitiesLocked(); 10184 return false; 10185 } 10186 mStackSupervisor.resumeTopActivitiesLocked(); 10187 } else { 10188 mStackSupervisor.finishTopRunningActivityLocked(app); 10189 } 10190 10191 // Bump up the crash count of any services currently running in the proc. 10192 for (int i=app.services.size()-1; i>=0; i--) { 10193 // Any services running in the application need to be placed 10194 // back in the pending list. 10195 ServiceRecord sr = app.services.valueAt(i); 10196 sr.crashCount++; 10197 } 10198 10199 // If the crashing process is what we consider to be the "home process" and it has been 10200 // replaced by a third-party app, clear the package preferred activities from packages 10201 // with a home activity running in the process to prevent a repeatedly crashing app 10202 // from blocking the user to manually clear the list. 10203 final ArrayList<ActivityRecord> activities = app.activities; 10204 if (app == mHomeProcess && activities.size() > 0 10205 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10206 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10207 final ActivityRecord r = activities.get(activityNdx); 10208 if (r.isHomeActivity()) { 10209 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10210 try { 10211 ActivityThread.getPackageManager() 10212 .clearPackagePreferredActivities(r.packageName); 10213 } catch (RemoteException c) { 10214 // pm is in same process, this will never happen. 10215 } 10216 } 10217 } 10218 } 10219 10220 if (!app.isolated) { 10221 // XXX Can't keep track of crash times for isolated processes, 10222 // because they don't have a perisistent identity. 10223 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10224 } 10225 10226 return true; 10227 } 10228 10229 void startAppProblemLocked(ProcessRecord app) { 10230 if (app.userId == mCurrentUserId) { 10231 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10232 mContext, app.info.packageName, app.info.flags); 10233 } else { 10234 // If this app is not running under the current user, then we 10235 // can't give it a report button because that would require 10236 // launching the report UI under a different user. 10237 app.errorReportReceiver = null; 10238 } 10239 skipCurrentReceiverLocked(app); 10240 } 10241 10242 void skipCurrentReceiverLocked(ProcessRecord app) { 10243 for (BroadcastQueue queue : mBroadcastQueues) { 10244 queue.skipCurrentReceiverLocked(app); 10245 } 10246 } 10247 10248 /** 10249 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10250 * The application process will exit immediately after this call returns. 10251 * @param app object of the crashing app, null for the system server 10252 * @param crashInfo describing the exception 10253 */ 10254 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10255 ProcessRecord r = findAppProcess(app, "Crash"); 10256 final String processName = app == null ? "system_server" 10257 : (r == null ? "unknown" : r.processName); 10258 10259 handleApplicationCrashInner("crash", r, processName, crashInfo); 10260 } 10261 10262 /* Native crash reporting uses this inner version because it needs to be somewhat 10263 * decoupled from the AM-managed cleanup lifecycle 10264 */ 10265 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10266 ApplicationErrorReport.CrashInfo crashInfo) { 10267 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10268 UserHandle.getUserId(Binder.getCallingUid()), processName, 10269 r == null ? -1 : r.info.flags, 10270 crashInfo.exceptionClassName, 10271 crashInfo.exceptionMessage, 10272 crashInfo.throwFileName, 10273 crashInfo.throwLineNumber); 10274 10275 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10276 10277 crashApplication(r, crashInfo); 10278 } 10279 10280 public void handleApplicationStrictModeViolation( 10281 IBinder app, 10282 int violationMask, 10283 StrictMode.ViolationInfo info) { 10284 ProcessRecord r = findAppProcess(app, "StrictMode"); 10285 if (r == null) { 10286 return; 10287 } 10288 10289 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10290 Integer stackFingerprint = info.hashCode(); 10291 boolean logIt = true; 10292 synchronized (mAlreadyLoggedViolatedStacks) { 10293 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10294 logIt = false; 10295 // TODO: sub-sample into EventLog for these, with 10296 // the info.durationMillis? Then we'd get 10297 // the relative pain numbers, without logging all 10298 // the stack traces repeatedly. We'd want to do 10299 // likewise in the client code, which also does 10300 // dup suppression, before the Binder call. 10301 } else { 10302 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10303 mAlreadyLoggedViolatedStacks.clear(); 10304 } 10305 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10306 } 10307 } 10308 if (logIt) { 10309 logStrictModeViolationToDropBox(r, info); 10310 } 10311 } 10312 10313 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10314 AppErrorResult result = new AppErrorResult(); 10315 synchronized (this) { 10316 final long origId = Binder.clearCallingIdentity(); 10317 10318 Message msg = Message.obtain(); 10319 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10320 HashMap<String, Object> data = new HashMap<String, Object>(); 10321 data.put("result", result); 10322 data.put("app", r); 10323 data.put("violationMask", violationMask); 10324 data.put("info", info); 10325 msg.obj = data; 10326 mHandler.sendMessage(msg); 10327 10328 Binder.restoreCallingIdentity(origId); 10329 } 10330 int res = result.get(); 10331 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10332 } 10333 } 10334 10335 // Depending on the policy in effect, there could be a bunch of 10336 // these in quick succession so we try to batch these together to 10337 // minimize disk writes, number of dropbox entries, and maximize 10338 // compression, by having more fewer, larger records. 10339 private void logStrictModeViolationToDropBox( 10340 ProcessRecord process, 10341 StrictMode.ViolationInfo info) { 10342 if (info == null) { 10343 return; 10344 } 10345 final boolean isSystemApp = process == null || 10346 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10347 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10348 final String processName = process == null ? "unknown" : process.processName; 10349 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10350 final DropBoxManager dbox = (DropBoxManager) 10351 mContext.getSystemService(Context.DROPBOX_SERVICE); 10352 10353 // Exit early if the dropbox isn't configured to accept this report type. 10354 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10355 10356 boolean bufferWasEmpty; 10357 boolean needsFlush; 10358 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10359 synchronized (sb) { 10360 bufferWasEmpty = sb.length() == 0; 10361 appendDropBoxProcessHeaders(process, processName, sb); 10362 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10363 sb.append("System-App: ").append(isSystemApp).append("\n"); 10364 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10365 if (info.violationNumThisLoop != 0) { 10366 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10367 } 10368 if (info.numAnimationsRunning != 0) { 10369 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10370 } 10371 if (info.broadcastIntentAction != null) { 10372 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10373 } 10374 if (info.durationMillis != -1) { 10375 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10376 } 10377 if (info.numInstances != -1) { 10378 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10379 } 10380 if (info.tags != null) { 10381 for (String tag : info.tags) { 10382 sb.append("Span-Tag: ").append(tag).append("\n"); 10383 } 10384 } 10385 sb.append("\n"); 10386 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10387 sb.append(info.crashInfo.stackTrace); 10388 } 10389 sb.append("\n"); 10390 10391 // Only buffer up to ~64k. Various logging bits truncate 10392 // things at 128k. 10393 needsFlush = (sb.length() > 64 * 1024); 10394 } 10395 10396 // Flush immediately if the buffer's grown too large, or this 10397 // is a non-system app. Non-system apps are isolated with a 10398 // different tag & policy and not batched. 10399 // 10400 // Batching is useful during internal testing with 10401 // StrictMode settings turned up high. Without batching, 10402 // thousands of separate files could be created on boot. 10403 if (!isSystemApp || needsFlush) { 10404 new Thread("Error dump: " + dropboxTag) { 10405 @Override 10406 public void run() { 10407 String report; 10408 synchronized (sb) { 10409 report = sb.toString(); 10410 sb.delete(0, sb.length()); 10411 sb.trimToSize(); 10412 } 10413 if (report.length() != 0) { 10414 dbox.addText(dropboxTag, report); 10415 } 10416 } 10417 }.start(); 10418 return; 10419 } 10420 10421 // System app batching: 10422 if (!bufferWasEmpty) { 10423 // An existing dropbox-writing thread is outstanding, so 10424 // we don't need to start it up. The existing thread will 10425 // catch the buffer appends we just did. 10426 return; 10427 } 10428 10429 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10430 // (After this point, we shouldn't access AMS internal data structures.) 10431 new Thread("Error dump: " + dropboxTag) { 10432 @Override 10433 public void run() { 10434 // 5 second sleep to let stacks arrive and be batched together 10435 try { 10436 Thread.sleep(5000); // 5 seconds 10437 } catch (InterruptedException e) {} 10438 10439 String errorReport; 10440 synchronized (mStrictModeBuffer) { 10441 errorReport = mStrictModeBuffer.toString(); 10442 if (errorReport.length() == 0) { 10443 return; 10444 } 10445 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10446 mStrictModeBuffer.trimToSize(); 10447 } 10448 dbox.addText(dropboxTag, errorReport); 10449 } 10450 }.start(); 10451 } 10452 10453 /** 10454 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10455 * @param app object of the crashing app, null for the system server 10456 * @param tag reported by the caller 10457 * @param crashInfo describing the context of the error 10458 * @return true if the process should exit immediately (WTF is fatal) 10459 */ 10460 public boolean handleApplicationWtf(IBinder app, String tag, 10461 ApplicationErrorReport.CrashInfo crashInfo) { 10462 ProcessRecord r = findAppProcess(app, "WTF"); 10463 final String processName = app == null ? "system_server" 10464 : (r == null ? "unknown" : r.processName); 10465 10466 EventLog.writeEvent(EventLogTags.AM_WTF, 10467 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10468 processName, 10469 r == null ? -1 : r.info.flags, 10470 tag, crashInfo.exceptionMessage); 10471 10472 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10473 10474 if (r != null && r.pid != Process.myPid() && 10475 Settings.Global.getInt(mContext.getContentResolver(), 10476 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10477 crashApplication(r, crashInfo); 10478 return true; 10479 } else { 10480 return false; 10481 } 10482 } 10483 10484 /** 10485 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10486 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10487 */ 10488 private ProcessRecord findAppProcess(IBinder app, String reason) { 10489 if (app == null) { 10490 return null; 10491 } 10492 10493 synchronized (this) { 10494 final int NP = mProcessNames.getMap().size(); 10495 for (int ip=0; ip<NP; ip++) { 10496 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10497 final int NA = apps.size(); 10498 for (int ia=0; ia<NA; ia++) { 10499 ProcessRecord p = apps.valueAt(ia); 10500 if (p.thread != null && p.thread.asBinder() == app) { 10501 return p; 10502 } 10503 } 10504 } 10505 10506 Slog.w(TAG, "Can't find mystery application for " + reason 10507 + " from pid=" + Binder.getCallingPid() 10508 + " uid=" + Binder.getCallingUid() + ": " + app); 10509 return null; 10510 } 10511 } 10512 10513 /** 10514 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10515 * to append various headers to the dropbox log text. 10516 */ 10517 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10518 StringBuilder sb) { 10519 // Watchdog thread ends up invoking this function (with 10520 // a null ProcessRecord) to add the stack file to dropbox. 10521 // Do not acquire a lock on this (am) in such cases, as it 10522 // could cause a potential deadlock, if and when watchdog 10523 // is invoked due to unavailability of lock on am and it 10524 // would prevent watchdog from killing system_server. 10525 if (process == null) { 10526 sb.append("Process: ").append(processName).append("\n"); 10527 return; 10528 } 10529 // Note: ProcessRecord 'process' is guarded by the service 10530 // instance. (notably process.pkgList, which could otherwise change 10531 // concurrently during execution of this method) 10532 synchronized (this) { 10533 sb.append("Process: ").append(processName).append("\n"); 10534 int flags = process.info.flags; 10535 IPackageManager pm = AppGlobals.getPackageManager(); 10536 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10537 for (int ip=0; ip<process.pkgList.size(); ip++) { 10538 String pkg = process.pkgList.keyAt(ip); 10539 sb.append("Package: ").append(pkg); 10540 try { 10541 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10542 if (pi != null) { 10543 sb.append(" v").append(pi.versionCode); 10544 if (pi.versionName != null) { 10545 sb.append(" (").append(pi.versionName).append(")"); 10546 } 10547 } 10548 } catch (RemoteException e) { 10549 Slog.e(TAG, "Error getting package info: " + pkg, e); 10550 } 10551 sb.append("\n"); 10552 } 10553 } 10554 } 10555 10556 private static String processClass(ProcessRecord process) { 10557 if (process == null || process.pid == MY_PID) { 10558 return "system_server"; 10559 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10560 return "system_app"; 10561 } else { 10562 return "data_app"; 10563 } 10564 } 10565 10566 /** 10567 * Write a description of an error (crash, WTF, ANR) to the drop box. 10568 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10569 * @param process which caused the error, null means the system server 10570 * @param activity which triggered the error, null if unknown 10571 * @param parent activity related to the error, null if unknown 10572 * @param subject line related to the error, null if absent 10573 * @param report in long form describing the error, null if absent 10574 * @param logFile to include in the report, null if none 10575 * @param crashInfo giving an application stack trace, null if absent 10576 */ 10577 public void addErrorToDropBox(String eventType, 10578 ProcessRecord process, String processName, ActivityRecord activity, 10579 ActivityRecord parent, String subject, 10580 final String report, final File logFile, 10581 final ApplicationErrorReport.CrashInfo crashInfo) { 10582 // NOTE -- this must never acquire the ActivityManagerService lock, 10583 // otherwise the watchdog may be prevented from resetting the system. 10584 10585 final String dropboxTag = processClass(process) + "_" + eventType; 10586 final DropBoxManager dbox = (DropBoxManager) 10587 mContext.getSystemService(Context.DROPBOX_SERVICE); 10588 10589 // Exit early if the dropbox isn't configured to accept this report type. 10590 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10591 10592 final StringBuilder sb = new StringBuilder(1024); 10593 appendDropBoxProcessHeaders(process, processName, sb); 10594 if (activity != null) { 10595 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10596 } 10597 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10598 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10599 } 10600 if (parent != null && parent != activity) { 10601 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10602 } 10603 if (subject != null) { 10604 sb.append("Subject: ").append(subject).append("\n"); 10605 } 10606 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10607 if (Debug.isDebuggerConnected()) { 10608 sb.append("Debugger: Connected\n"); 10609 } 10610 sb.append("\n"); 10611 10612 // Do the rest in a worker thread to avoid blocking the caller on I/O 10613 // (After this point, we shouldn't access AMS internal data structures.) 10614 Thread worker = new Thread("Error dump: " + dropboxTag) { 10615 @Override 10616 public void run() { 10617 if (report != null) { 10618 sb.append(report); 10619 } 10620 if (logFile != null) { 10621 try { 10622 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10623 "\n\n[[TRUNCATED]]")); 10624 } catch (IOException e) { 10625 Slog.e(TAG, "Error reading " + logFile, e); 10626 } 10627 } 10628 if (crashInfo != null && crashInfo.stackTrace != null) { 10629 sb.append(crashInfo.stackTrace); 10630 } 10631 10632 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10633 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10634 if (lines > 0) { 10635 sb.append("\n"); 10636 10637 // Merge several logcat streams, and take the last N lines 10638 InputStreamReader input = null; 10639 try { 10640 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10641 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10642 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10643 10644 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10645 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10646 input = new InputStreamReader(logcat.getInputStream()); 10647 10648 int num; 10649 char[] buf = new char[8192]; 10650 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10651 } catch (IOException e) { 10652 Slog.e(TAG, "Error running logcat", e); 10653 } finally { 10654 if (input != null) try { input.close(); } catch (IOException e) {} 10655 } 10656 } 10657 10658 dbox.addText(dropboxTag, sb.toString()); 10659 } 10660 }; 10661 10662 if (process == null) { 10663 // If process is null, we are being called from some internal code 10664 // and may be about to die -- run this synchronously. 10665 worker.run(); 10666 } else { 10667 worker.start(); 10668 } 10669 } 10670 10671 /** 10672 * Bring up the "unexpected error" dialog box for a crashing app. 10673 * Deal with edge cases (intercepts from instrumented applications, 10674 * ActivityController, error intent receivers, that sort of thing). 10675 * @param r the application crashing 10676 * @param crashInfo describing the failure 10677 */ 10678 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10679 long timeMillis = System.currentTimeMillis(); 10680 String shortMsg = crashInfo.exceptionClassName; 10681 String longMsg = crashInfo.exceptionMessage; 10682 String stackTrace = crashInfo.stackTrace; 10683 if (shortMsg != null && longMsg != null) { 10684 longMsg = shortMsg + ": " + longMsg; 10685 } else if (shortMsg != null) { 10686 longMsg = shortMsg; 10687 } 10688 10689 AppErrorResult result = new AppErrorResult(); 10690 synchronized (this) { 10691 if (mController != null) { 10692 try { 10693 String name = r != null ? r.processName : null; 10694 int pid = r != null ? r.pid : Binder.getCallingPid(); 10695 if (!mController.appCrashed(name, pid, 10696 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10697 Slog.w(TAG, "Force-killing crashed app " + name 10698 + " at watcher's request"); 10699 Process.killProcess(pid); 10700 return; 10701 } 10702 } catch (RemoteException e) { 10703 mController = null; 10704 Watchdog.getInstance().setActivityController(null); 10705 } 10706 } 10707 10708 final long origId = Binder.clearCallingIdentity(); 10709 10710 // If this process is running instrumentation, finish it. 10711 if (r != null && r.instrumentationClass != null) { 10712 Slog.w(TAG, "Error in app " + r.processName 10713 + " running instrumentation " + r.instrumentationClass + ":"); 10714 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10715 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10716 Bundle info = new Bundle(); 10717 info.putString("shortMsg", shortMsg); 10718 info.putString("longMsg", longMsg); 10719 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10720 Binder.restoreCallingIdentity(origId); 10721 return; 10722 } 10723 10724 // If we can't identify the process or it's already exceeded its crash quota, 10725 // quit right away without showing a crash dialog. 10726 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10727 Binder.restoreCallingIdentity(origId); 10728 return; 10729 } 10730 10731 Message msg = Message.obtain(); 10732 msg.what = SHOW_ERROR_MSG; 10733 HashMap data = new HashMap(); 10734 data.put("result", result); 10735 data.put("app", r); 10736 msg.obj = data; 10737 mHandler.sendMessage(msg); 10738 10739 Binder.restoreCallingIdentity(origId); 10740 } 10741 10742 int res = result.get(); 10743 10744 Intent appErrorIntent = null; 10745 synchronized (this) { 10746 if (r != null && !r.isolated) { 10747 // XXX Can't keep track of crash time for isolated processes, 10748 // since they don't have a persistent identity. 10749 mProcessCrashTimes.put(r.info.processName, r.uid, 10750 SystemClock.uptimeMillis()); 10751 } 10752 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10753 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10754 } 10755 } 10756 10757 if (appErrorIntent != null) { 10758 try { 10759 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10760 } catch (ActivityNotFoundException e) { 10761 Slog.w(TAG, "bug report receiver dissappeared", e); 10762 } 10763 } 10764 } 10765 10766 Intent createAppErrorIntentLocked(ProcessRecord r, 10767 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10768 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10769 if (report == null) { 10770 return null; 10771 } 10772 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10773 result.setComponent(r.errorReportReceiver); 10774 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10775 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10776 return result; 10777 } 10778 10779 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10780 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10781 if (r.errorReportReceiver == null) { 10782 return null; 10783 } 10784 10785 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10786 return null; 10787 } 10788 10789 ApplicationErrorReport report = new ApplicationErrorReport(); 10790 report.packageName = r.info.packageName; 10791 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10792 report.processName = r.processName; 10793 report.time = timeMillis; 10794 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10795 10796 if (r.crashing || r.forceCrashReport) { 10797 report.type = ApplicationErrorReport.TYPE_CRASH; 10798 report.crashInfo = crashInfo; 10799 } else if (r.notResponding) { 10800 report.type = ApplicationErrorReport.TYPE_ANR; 10801 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10802 10803 report.anrInfo.activity = r.notRespondingReport.tag; 10804 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10805 report.anrInfo.info = r.notRespondingReport.longMsg; 10806 } 10807 10808 return report; 10809 } 10810 10811 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10812 enforceNotIsolatedCaller("getProcessesInErrorState"); 10813 // assume our apps are happy - lazy create the list 10814 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10815 10816 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10817 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10818 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10819 10820 synchronized (this) { 10821 10822 // iterate across all processes 10823 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10824 ProcessRecord app = mLruProcesses.get(i); 10825 if (!allUsers && app.userId != userId) { 10826 continue; 10827 } 10828 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10829 // This one's in trouble, so we'll generate a report for it 10830 // crashes are higher priority (in case there's a crash *and* an anr) 10831 ActivityManager.ProcessErrorStateInfo report = null; 10832 if (app.crashing) { 10833 report = app.crashingReport; 10834 } else if (app.notResponding) { 10835 report = app.notRespondingReport; 10836 } 10837 10838 if (report != null) { 10839 if (errList == null) { 10840 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10841 } 10842 errList.add(report); 10843 } else { 10844 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10845 " crashing = " + app.crashing + 10846 " notResponding = " + app.notResponding); 10847 } 10848 } 10849 } 10850 } 10851 10852 return errList; 10853 } 10854 10855 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10856 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10857 if (currApp != null) { 10858 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10859 } 10860 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10861 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10862 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10863 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10864 if (currApp != null) { 10865 currApp.lru = 0; 10866 } 10867 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10868 } else if (adj >= ProcessList.SERVICE_ADJ) { 10869 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10870 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10871 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10872 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10873 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10874 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10875 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10876 } else { 10877 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10878 } 10879 } 10880 10881 private void fillInProcMemInfo(ProcessRecord app, 10882 ActivityManager.RunningAppProcessInfo outInfo) { 10883 outInfo.pid = app.pid; 10884 outInfo.uid = app.info.uid; 10885 if (mHeavyWeightProcess == app) { 10886 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10887 } 10888 if (app.persistent) { 10889 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10890 } 10891 if (app.activities.size() > 0) { 10892 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10893 } 10894 outInfo.lastTrimLevel = app.trimMemoryLevel; 10895 int adj = app.curAdj; 10896 outInfo.importance = oomAdjToImportance(adj, outInfo); 10897 outInfo.importanceReasonCode = app.adjTypeCode; 10898 outInfo.processState = app.curProcState; 10899 } 10900 10901 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10902 enforceNotIsolatedCaller("getRunningAppProcesses"); 10903 // Lazy instantiation of list 10904 List<ActivityManager.RunningAppProcessInfo> runList = null; 10905 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10906 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10907 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10908 synchronized (this) { 10909 // Iterate across all processes 10910 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10911 ProcessRecord app = mLruProcesses.get(i); 10912 if (!allUsers && app.userId != userId) { 10913 continue; 10914 } 10915 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10916 // Generate process state info for running application 10917 ActivityManager.RunningAppProcessInfo currApp = 10918 new ActivityManager.RunningAppProcessInfo(app.processName, 10919 app.pid, app.getPackageList()); 10920 fillInProcMemInfo(app, currApp); 10921 if (app.adjSource instanceof ProcessRecord) { 10922 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10923 currApp.importanceReasonImportance = oomAdjToImportance( 10924 app.adjSourceOom, null); 10925 } else if (app.adjSource instanceof ActivityRecord) { 10926 ActivityRecord r = (ActivityRecord)app.adjSource; 10927 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10928 } 10929 if (app.adjTarget instanceof ComponentName) { 10930 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10931 } 10932 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10933 // + " lru=" + currApp.lru); 10934 if (runList == null) { 10935 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10936 } 10937 runList.add(currApp); 10938 } 10939 } 10940 } 10941 return runList; 10942 } 10943 10944 public List<ApplicationInfo> getRunningExternalApplications() { 10945 enforceNotIsolatedCaller("getRunningExternalApplications"); 10946 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10947 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10948 if (runningApps != null && runningApps.size() > 0) { 10949 Set<String> extList = new HashSet<String>(); 10950 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10951 if (app.pkgList != null) { 10952 for (String pkg : app.pkgList) { 10953 extList.add(pkg); 10954 } 10955 } 10956 } 10957 IPackageManager pm = AppGlobals.getPackageManager(); 10958 for (String pkg : extList) { 10959 try { 10960 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10961 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10962 retList.add(info); 10963 } 10964 } catch (RemoteException e) { 10965 } 10966 } 10967 } 10968 return retList; 10969 } 10970 10971 @Override 10972 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10973 enforceNotIsolatedCaller("getMyMemoryState"); 10974 synchronized (this) { 10975 ProcessRecord proc; 10976 synchronized (mPidsSelfLocked) { 10977 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10978 } 10979 fillInProcMemInfo(proc, outInfo); 10980 } 10981 } 10982 10983 @Override 10984 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10985 if (checkCallingPermission(android.Manifest.permission.DUMP) 10986 != PackageManager.PERMISSION_GRANTED) { 10987 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10988 + Binder.getCallingPid() 10989 + ", uid=" + Binder.getCallingUid() 10990 + " without permission " 10991 + android.Manifest.permission.DUMP); 10992 return; 10993 } 10994 10995 boolean dumpAll = false; 10996 boolean dumpClient = false; 10997 String dumpPackage = null; 10998 10999 int opti = 0; 11000 while (opti < args.length) { 11001 String opt = args[opti]; 11002 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11003 break; 11004 } 11005 opti++; 11006 if ("-a".equals(opt)) { 11007 dumpAll = true; 11008 } else if ("-c".equals(opt)) { 11009 dumpClient = true; 11010 } else if ("-h".equals(opt)) { 11011 pw.println("Activity manager dump options:"); 11012 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11013 pw.println(" cmd may be one of:"); 11014 pw.println(" a[ctivities]: activity stack state"); 11015 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11016 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11017 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11018 pw.println(" o[om]: out of memory management"); 11019 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11020 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11021 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11022 pw.println(" service [COMP_SPEC]: service client-side state"); 11023 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11024 pw.println(" all: dump all activities"); 11025 pw.println(" top: dump the top activity"); 11026 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11027 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11028 pw.println(" a partial substring in a component name, a"); 11029 pw.println(" hex object identifier."); 11030 pw.println(" -a: include all available server state."); 11031 pw.println(" -c: include client state."); 11032 return; 11033 } else { 11034 pw.println("Unknown argument: " + opt + "; use -h for help"); 11035 } 11036 } 11037 11038 long origId = Binder.clearCallingIdentity(); 11039 boolean more = false; 11040 // Is the caller requesting to dump a particular piece of data? 11041 if (opti < args.length) { 11042 String cmd = args[opti]; 11043 opti++; 11044 if ("activities".equals(cmd) || "a".equals(cmd)) { 11045 synchronized (this) { 11046 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11047 } 11048 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11049 String[] newArgs; 11050 String name; 11051 if (opti >= args.length) { 11052 name = null; 11053 newArgs = EMPTY_STRING_ARRAY; 11054 } else { 11055 name = args[opti]; 11056 opti++; 11057 newArgs = new String[args.length - opti]; 11058 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11059 args.length - opti); 11060 } 11061 synchronized (this) { 11062 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11063 } 11064 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11065 String[] newArgs; 11066 String name; 11067 if (opti >= args.length) { 11068 name = null; 11069 newArgs = EMPTY_STRING_ARRAY; 11070 } else { 11071 name = args[opti]; 11072 opti++; 11073 newArgs = new String[args.length - opti]; 11074 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11075 args.length - opti); 11076 } 11077 synchronized (this) { 11078 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11079 } 11080 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11081 String[] newArgs; 11082 String name; 11083 if (opti >= args.length) { 11084 name = null; 11085 newArgs = EMPTY_STRING_ARRAY; 11086 } else { 11087 name = args[opti]; 11088 opti++; 11089 newArgs = new String[args.length - opti]; 11090 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11091 args.length - opti); 11092 } 11093 synchronized (this) { 11094 dumpProcessesLocked(fd, pw, args, opti, true, name); 11095 } 11096 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11097 synchronized (this) { 11098 dumpOomLocked(fd, pw, args, opti, true); 11099 } 11100 } else if ("provider".equals(cmd)) { 11101 String[] newArgs; 11102 String name; 11103 if (opti >= args.length) { 11104 name = null; 11105 newArgs = EMPTY_STRING_ARRAY; 11106 } else { 11107 name = args[opti]; 11108 opti++; 11109 newArgs = new String[args.length - opti]; 11110 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11111 } 11112 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11113 pw.println("No providers match: " + name); 11114 pw.println("Use -h for help."); 11115 } 11116 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11117 synchronized (this) { 11118 dumpProvidersLocked(fd, pw, args, opti, true, null); 11119 } 11120 } else if ("service".equals(cmd)) { 11121 String[] newArgs; 11122 String name; 11123 if (opti >= args.length) { 11124 name = null; 11125 newArgs = EMPTY_STRING_ARRAY; 11126 } else { 11127 name = args[opti]; 11128 opti++; 11129 newArgs = new String[args.length - opti]; 11130 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11131 args.length - opti); 11132 } 11133 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11134 pw.println("No services match: " + name); 11135 pw.println("Use -h for help."); 11136 } 11137 } else if ("package".equals(cmd)) { 11138 String[] newArgs; 11139 if (opti >= args.length) { 11140 pw.println("package: no package name specified"); 11141 pw.println("Use -h for help."); 11142 } else { 11143 dumpPackage = args[opti]; 11144 opti++; 11145 newArgs = new String[args.length - opti]; 11146 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11147 args.length - opti); 11148 args = newArgs; 11149 opti = 0; 11150 more = true; 11151 } 11152 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11153 synchronized (this) { 11154 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11155 } 11156 } else { 11157 // Dumping a single activity? 11158 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11159 pw.println("Bad activity command, or no activities match: " + cmd); 11160 pw.println("Use -h for help."); 11161 } 11162 } 11163 if (!more) { 11164 Binder.restoreCallingIdentity(origId); 11165 return; 11166 } 11167 } 11168 11169 // No piece of data specified, dump everything. 11170 synchronized (this) { 11171 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11172 pw.println(); 11173 if (dumpAll) { 11174 pw.println("-------------------------------------------------------------------------------"); 11175 } 11176 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11177 pw.println(); 11178 if (dumpAll) { 11179 pw.println("-------------------------------------------------------------------------------"); 11180 } 11181 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11182 pw.println(); 11183 if (dumpAll) { 11184 pw.println("-------------------------------------------------------------------------------"); 11185 } 11186 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11187 pw.println(); 11188 if (dumpAll) { 11189 pw.println("-------------------------------------------------------------------------------"); 11190 } 11191 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11192 pw.println(); 11193 if (dumpAll) { 11194 pw.println("-------------------------------------------------------------------------------"); 11195 } 11196 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11197 } 11198 Binder.restoreCallingIdentity(origId); 11199 } 11200 11201 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11202 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11203 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11204 11205 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11206 dumpPackage); 11207 boolean needSep = printedAnything; 11208 11209 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11210 dumpPackage, needSep, " mFocusedActivity: "); 11211 if (printed) { 11212 printedAnything = true; 11213 needSep = false; 11214 } 11215 11216 if (dumpPackage == null) { 11217 if (needSep) { 11218 pw.println(); 11219 } 11220 needSep = true; 11221 printedAnything = true; 11222 mStackSupervisor.dump(pw, " "); 11223 } 11224 11225 if (mRecentTasks.size() > 0) { 11226 boolean printedHeader = false; 11227 11228 final int N = mRecentTasks.size(); 11229 for (int i=0; i<N; i++) { 11230 TaskRecord tr = mRecentTasks.get(i); 11231 if (dumpPackage != null) { 11232 if (tr.realActivity == null || 11233 !dumpPackage.equals(tr.realActivity)) { 11234 continue; 11235 } 11236 } 11237 if (!printedHeader) { 11238 if (needSep) { 11239 pw.println(); 11240 } 11241 pw.println(" Recent tasks:"); 11242 printedHeader = true; 11243 printedAnything = true; 11244 } 11245 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11246 pw.println(tr); 11247 if (dumpAll) { 11248 mRecentTasks.get(i).dump(pw, " "); 11249 } 11250 } 11251 } 11252 11253 if (!printedAnything) { 11254 pw.println(" (nothing)"); 11255 } 11256 } 11257 11258 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11259 int opti, boolean dumpAll, String dumpPackage) { 11260 boolean needSep = false; 11261 boolean printedAnything = false; 11262 int numPers = 0; 11263 11264 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11265 11266 if (dumpAll) { 11267 final int NP = mProcessNames.getMap().size(); 11268 for (int ip=0; ip<NP; ip++) { 11269 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11270 final int NA = procs.size(); 11271 for (int ia=0; ia<NA; ia++) { 11272 ProcessRecord r = procs.valueAt(ia); 11273 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11274 continue; 11275 } 11276 if (!needSep) { 11277 pw.println(" All known processes:"); 11278 needSep = true; 11279 printedAnything = true; 11280 } 11281 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11282 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11283 pw.print(" "); pw.println(r); 11284 r.dump(pw, " "); 11285 if (r.persistent) { 11286 numPers++; 11287 } 11288 } 11289 } 11290 } 11291 11292 if (mIsolatedProcesses.size() > 0) { 11293 boolean printed = false; 11294 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11295 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11296 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11297 continue; 11298 } 11299 if (!printed) { 11300 if (needSep) { 11301 pw.println(); 11302 } 11303 pw.println(" Isolated process list (sorted by uid):"); 11304 printedAnything = true; 11305 printed = true; 11306 needSep = true; 11307 } 11308 pw.println(String.format("%sIsolated #%2d: %s", 11309 " ", i, r.toString())); 11310 } 11311 } 11312 11313 if (mLruProcesses.size() > 0) { 11314 if (needSep) { 11315 pw.println(); 11316 } 11317 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11318 pw.print(" total, non-act at "); 11319 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11320 pw.print(", non-svc at "); 11321 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11322 pw.println("):"); 11323 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11324 needSep = true; 11325 printedAnything = true; 11326 } 11327 11328 if (dumpAll || dumpPackage != null) { 11329 synchronized (mPidsSelfLocked) { 11330 boolean printed = false; 11331 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11332 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11333 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11334 continue; 11335 } 11336 if (!printed) { 11337 if (needSep) pw.println(); 11338 needSep = true; 11339 pw.println(" PID mappings:"); 11340 printed = true; 11341 printedAnything = true; 11342 } 11343 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11344 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11345 } 11346 } 11347 } 11348 11349 if (mForegroundProcesses.size() > 0) { 11350 synchronized (mPidsSelfLocked) { 11351 boolean printed = false; 11352 for (int i=0; i<mForegroundProcesses.size(); i++) { 11353 ProcessRecord r = mPidsSelfLocked.get( 11354 mForegroundProcesses.valueAt(i).pid); 11355 if (dumpPackage != null && (r == null 11356 || !r.pkgList.containsKey(dumpPackage))) { 11357 continue; 11358 } 11359 if (!printed) { 11360 if (needSep) pw.println(); 11361 needSep = true; 11362 pw.println(" Foreground Processes:"); 11363 printed = true; 11364 printedAnything = true; 11365 } 11366 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11367 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11368 } 11369 } 11370 } 11371 11372 if (mPersistentStartingProcesses.size() > 0) { 11373 if (needSep) pw.println(); 11374 needSep = true; 11375 printedAnything = true; 11376 pw.println(" Persisent processes that are starting:"); 11377 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11378 "Starting Norm", "Restarting PERS", dumpPackage); 11379 } 11380 11381 if (mRemovedProcesses.size() > 0) { 11382 if (needSep) pw.println(); 11383 needSep = true; 11384 printedAnything = true; 11385 pw.println(" Processes that are being removed:"); 11386 dumpProcessList(pw, this, mRemovedProcesses, " ", 11387 "Removed Norm", "Removed PERS", dumpPackage); 11388 } 11389 11390 if (mProcessesOnHold.size() > 0) { 11391 if (needSep) pw.println(); 11392 needSep = true; 11393 printedAnything = true; 11394 pw.println(" Processes that are on old until the system is ready:"); 11395 dumpProcessList(pw, this, mProcessesOnHold, " ", 11396 "OnHold Norm", "OnHold PERS", dumpPackage); 11397 } 11398 11399 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11400 11401 if (mProcessCrashTimes.getMap().size() > 0) { 11402 boolean printed = false; 11403 long now = SystemClock.uptimeMillis(); 11404 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11405 final int NP = pmap.size(); 11406 for (int ip=0; ip<NP; ip++) { 11407 String pname = pmap.keyAt(ip); 11408 SparseArray<Long> uids = pmap.valueAt(ip); 11409 final int N = uids.size(); 11410 for (int i=0; i<N; i++) { 11411 int puid = uids.keyAt(i); 11412 ProcessRecord r = mProcessNames.get(pname, puid); 11413 if (dumpPackage != null && (r == null 11414 || !r.pkgList.containsKey(dumpPackage))) { 11415 continue; 11416 } 11417 if (!printed) { 11418 if (needSep) pw.println(); 11419 needSep = true; 11420 pw.println(" Time since processes crashed:"); 11421 printed = true; 11422 printedAnything = true; 11423 } 11424 pw.print(" Process "); pw.print(pname); 11425 pw.print(" uid "); pw.print(puid); 11426 pw.print(": last crashed "); 11427 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11428 pw.println(" ago"); 11429 } 11430 } 11431 } 11432 11433 if (mBadProcesses.getMap().size() > 0) { 11434 boolean printed = false; 11435 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11436 final int NP = pmap.size(); 11437 for (int ip=0; ip<NP; ip++) { 11438 String pname = pmap.keyAt(ip); 11439 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11440 final int N = uids.size(); 11441 for (int i=0; i<N; i++) { 11442 int puid = uids.keyAt(i); 11443 ProcessRecord r = mProcessNames.get(pname, puid); 11444 if (dumpPackage != null && (r == null 11445 || !r.pkgList.containsKey(dumpPackage))) { 11446 continue; 11447 } 11448 if (!printed) { 11449 if (needSep) pw.println(); 11450 needSep = true; 11451 pw.println(" Bad processes:"); 11452 printedAnything = true; 11453 } 11454 BadProcessInfo info = uids.valueAt(i); 11455 pw.print(" Bad process "); pw.print(pname); 11456 pw.print(" uid "); pw.print(puid); 11457 pw.print(": crashed at time "); pw.println(info.time); 11458 if (info.shortMsg != null) { 11459 pw.print(" Short msg: "); pw.println(info.shortMsg); 11460 } 11461 if (info.longMsg != null) { 11462 pw.print(" Long msg: "); pw.println(info.longMsg); 11463 } 11464 if (info.stack != null) { 11465 pw.println(" Stack:"); 11466 int lastPos = 0; 11467 for (int pos=0; pos<info.stack.length(); pos++) { 11468 if (info.stack.charAt(pos) == '\n') { 11469 pw.print(" "); 11470 pw.write(info.stack, lastPos, pos-lastPos); 11471 pw.println(); 11472 lastPos = pos+1; 11473 } 11474 } 11475 if (lastPos < info.stack.length()) { 11476 pw.print(" "); 11477 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11478 pw.println(); 11479 } 11480 } 11481 } 11482 } 11483 } 11484 11485 if (dumpPackage == null) { 11486 pw.println(); 11487 needSep = false; 11488 pw.println(" mStartedUsers:"); 11489 for (int i=0; i<mStartedUsers.size(); i++) { 11490 UserStartedState uss = mStartedUsers.valueAt(i); 11491 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11492 pw.print(": "); uss.dump("", pw); 11493 } 11494 pw.print(" mStartedUserArray: ["); 11495 for (int i=0; i<mStartedUserArray.length; i++) { 11496 if (i > 0) pw.print(", "); 11497 pw.print(mStartedUserArray[i]); 11498 } 11499 pw.println("]"); 11500 pw.print(" mUserLru: ["); 11501 for (int i=0; i<mUserLru.size(); i++) { 11502 if (i > 0) pw.print(", "); 11503 pw.print(mUserLru.get(i)); 11504 } 11505 pw.println("]"); 11506 if (dumpAll) { 11507 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11508 } 11509 } 11510 if (mHomeProcess != null && (dumpPackage == null 11511 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11512 if (needSep) { 11513 pw.println(); 11514 needSep = false; 11515 } 11516 pw.println(" mHomeProcess: " + mHomeProcess); 11517 } 11518 if (mPreviousProcess != null && (dumpPackage == null 11519 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11520 if (needSep) { 11521 pw.println(); 11522 needSep = false; 11523 } 11524 pw.println(" mPreviousProcess: " + mPreviousProcess); 11525 } 11526 if (dumpAll) { 11527 StringBuilder sb = new StringBuilder(128); 11528 sb.append(" mPreviousProcessVisibleTime: "); 11529 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11530 pw.println(sb); 11531 } 11532 if (mHeavyWeightProcess != null && (dumpPackage == null 11533 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11534 if (needSep) { 11535 pw.println(); 11536 needSep = false; 11537 } 11538 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11539 } 11540 if (dumpPackage == null) { 11541 pw.println(" mConfiguration: " + mConfiguration); 11542 } 11543 if (dumpAll) { 11544 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11545 if (mCompatModePackages.getPackages().size() > 0) { 11546 boolean printed = false; 11547 for (Map.Entry<String, Integer> entry 11548 : mCompatModePackages.getPackages().entrySet()) { 11549 String pkg = entry.getKey(); 11550 int mode = entry.getValue(); 11551 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11552 continue; 11553 } 11554 if (!printed) { 11555 pw.println(" mScreenCompatPackages:"); 11556 printed = true; 11557 } 11558 pw.print(" "); pw.print(pkg); pw.print(": "); 11559 pw.print(mode); pw.println(); 11560 } 11561 } 11562 } 11563 if (dumpPackage == null) { 11564 if (mSleeping || mWentToSleep || mLockScreenShown) { 11565 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11566 + " mLockScreenShown " + mLockScreenShown); 11567 } 11568 if (mShuttingDown || mRunningVoice) { 11569 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11570 } 11571 } 11572 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11573 || mOrigWaitForDebugger) { 11574 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11575 || dumpPackage.equals(mOrigDebugApp)) { 11576 if (needSep) { 11577 pw.println(); 11578 needSep = false; 11579 } 11580 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11581 + " mDebugTransient=" + mDebugTransient 11582 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11583 } 11584 } 11585 if (mOpenGlTraceApp != null) { 11586 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11587 if (needSep) { 11588 pw.println(); 11589 needSep = false; 11590 } 11591 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11592 } 11593 } 11594 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11595 || mProfileFd != null) { 11596 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11597 if (needSep) { 11598 pw.println(); 11599 needSep = false; 11600 } 11601 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11602 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11603 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11604 + mAutoStopProfiler); 11605 } 11606 } 11607 if (dumpPackage == null) { 11608 if (mAlwaysFinishActivities || mController != null) { 11609 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11610 + " mController=" + mController); 11611 } 11612 if (dumpAll) { 11613 pw.println(" Total persistent processes: " + numPers); 11614 pw.println(" mProcessesReady=" + mProcessesReady 11615 + " mSystemReady=" + mSystemReady); 11616 pw.println(" mBooting=" + mBooting 11617 + " mBooted=" + mBooted 11618 + " mFactoryTest=" + mFactoryTest); 11619 pw.print(" mLastPowerCheckRealtime="); 11620 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11621 pw.println(""); 11622 pw.print(" mLastPowerCheckUptime="); 11623 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11624 pw.println(""); 11625 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11626 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11627 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11628 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11629 + " (" + mLruProcesses.size() + " total)" 11630 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11631 + " mNumServiceProcs=" + mNumServiceProcs 11632 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11633 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11634 + " mLastMemoryLevel" + mLastMemoryLevel 11635 + " mLastNumProcesses" + mLastNumProcesses); 11636 long now = SystemClock.uptimeMillis(); 11637 pw.print(" mLastIdleTime="); 11638 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11639 pw.print(" mLowRamSinceLastIdle="); 11640 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11641 pw.println(); 11642 } 11643 } 11644 11645 if (!printedAnything) { 11646 pw.println(" (nothing)"); 11647 } 11648 } 11649 11650 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11651 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11652 if (mProcessesToGc.size() > 0) { 11653 boolean printed = false; 11654 long now = SystemClock.uptimeMillis(); 11655 for (int i=0; i<mProcessesToGc.size(); i++) { 11656 ProcessRecord proc = mProcessesToGc.get(i); 11657 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11658 continue; 11659 } 11660 if (!printed) { 11661 if (needSep) pw.println(); 11662 needSep = true; 11663 pw.println(" Processes that are waiting to GC:"); 11664 printed = true; 11665 } 11666 pw.print(" Process "); pw.println(proc); 11667 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11668 pw.print(", last gced="); 11669 pw.print(now-proc.lastRequestedGc); 11670 pw.print(" ms ago, last lowMem="); 11671 pw.print(now-proc.lastLowMemory); 11672 pw.println(" ms ago"); 11673 11674 } 11675 } 11676 return needSep; 11677 } 11678 11679 void printOomLevel(PrintWriter pw, String name, int adj) { 11680 pw.print(" "); 11681 if (adj >= 0) { 11682 pw.print(' '); 11683 if (adj < 10) pw.print(' '); 11684 } else { 11685 if (adj > -10) pw.print(' '); 11686 } 11687 pw.print(adj); 11688 pw.print(": "); 11689 pw.print(name); 11690 pw.print(" ("); 11691 pw.print(mProcessList.getMemLevel(adj)/1024); 11692 pw.println(" kB)"); 11693 } 11694 11695 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11696 int opti, boolean dumpAll) { 11697 boolean needSep = false; 11698 11699 if (mLruProcesses.size() > 0) { 11700 if (needSep) pw.println(); 11701 needSep = true; 11702 pw.println(" OOM levels:"); 11703 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11704 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11705 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11706 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11707 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11708 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11709 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11710 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11711 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11712 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11713 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11714 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11715 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11716 11717 if (needSep) pw.println(); 11718 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11719 pw.print(" total, non-act at "); 11720 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11721 pw.print(", non-svc at "); 11722 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11723 pw.println("):"); 11724 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11725 needSep = true; 11726 } 11727 11728 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11729 11730 pw.println(); 11731 pw.println(" mHomeProcess: " + mHomeProcess); 11732 pw.println(" mPreviousProcess: " + mPreviousProcess); 11733 if (mHeavyWeightProcess != null) { 11734 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11735 } 11736 11737 return true; 11738 } 11739 11740 /** 11741 * There are three ways to call this: 11742 * - no provider specified: dump all the providers 11743 * - a flattened component name that matched an existing provider was specified as the 11744 * first arg: dump that one provider 11745 * - the first arg isn't the flattened component name of an existing provider: 11746 * dump all providers whose component contains the first arg as a substring 11747 */ 11748 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11749 int opti, boolean dumpAll) { 11750 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11751 } 11752 11753 static class ItemMatcher { 11754 ArrayList<ComponentName> components; 11755 ArrayList<String> strings; 11756 ArrayList<Integer> objects; 11757 boolean all; 11758 11759 ItemMatcher() { 11760 all = true; 11761 } 11762 11763 void build(String name) { 11764 ComponentName componentName = ComponentName.unflattenFromString(name); 11765 if (componentName != null) { 11766 if (components == null) { 11767 components = new ArrayList<ComponentName>(); 11768 } 11769 components.add(componentName); 11770 all = false; 11771 } else { 11772 int objectId = 0; 11773 // Not a '/' separated full component name; maybe an object ID? 11774 try { 11775 objectId = Integer.parseInt(name, 16); 11776 if (objects == null) { 11777 objects = new ArrayList<Integer>(); 11778 } 11779 objects.add(objectId); 11780 all = false; 11781 } catch (RuntimeException e) { 11782 // Not an integer; just do string match. 11783 if (strings == null) { 11784 strings = new ArrayList<String>(); 11785 } 11786 strings.add(name); 11787 all = false; 11788 } 11789 } 11790 } 11791 11792 int build(String[] args, int opti) { 11793 for (; opti<args.length; opti++) { 11794 String name = args[opti]; 11795 if ("--".equals(name)) { 11796 return opti+1; 11797 } 11798 build(name); 11799 } 11800 return opti; 11801 } 11802 11803 boolean match(Object object, ComponentName comp) { 11804 if (all) { 11805 return true; 11806 } 11807 if (components != null) { 11808 for (int i=0; i<components.size(); i++) { 11809 if (components.get(i).equals(comp)) { 11810 return true; 11811 } 11812 } 11813 } 11814 if (objects != null) { 11815 for (int i=0; i<objects.size(); i++) { 11816 if (System.identityHashCode(object) == objects.get(i)) { 11817 return true; 11818 } 11819 } 11820 } 11821 if (strings != null) { 11822 String flat = comp.flattenToString(); 11823 for (int i=0; i<strings.size(); i++) { 11824 if (flat.contains(strings.get(i))) { 11825 return true; 11826 } 11827 } 11828 } 11829 return false; 11830 } 11831 } 11832 11833 /** 11834 * There are three things that cmd can be: 11835 * - a flattened component name that matches an existing activity 11836 * - the cmd arg isn't the flattened component name of an existing activity: 11837 * dump all activity whose component contains the cmd as a substring 11838 * - A hex number of the ActivityRecord object instance. 11839 */ 11840 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11841 int opti, boolean dumpAll) { 11842 ArrayList<ActivityRecord> activities; 11843 11844 synchronized (this) { 11845 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11846 } 11847 11848 if (activities.size() <= 0) { 11849 return false; 11850 } 11851 11852 String[] newArgs = new String[args.length - opti]; 11853 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11854 11855 TaskRecord lastTask = null; 11856 boolean needSep = false; 11857 for (int i=activities.size()-1; i>=0; i--) { 11858 ActivityRecord r = activities.get(i); 11859 if (needSep) { 11860 pw.println(); 11861 } 11862 needSep = true; 11863 synchronized (this) { 11864 if (lastTask != r.task) { 11865 lastTask = r.task; 11866 pw.print("TASK "); pw.print(lastTask.affinity); 11867 pw.print(" id="); pw.println(lastTask.taskId); 11868 if (dumpAll) { 11869 lastTask.dump(pw, " "); 11870 } 11871 } 11872 } 11873 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11874 } 11875 return true; 11876 } 11877 11878 /** 11879 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11880 * there is a thread associated with the activity. 11881 */ 11882 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11883 final ActivityRecord r, String[] args, boolean dumpAll) { 11884 String innerPrefix = prefix + " "; 11885 synchronized (this) { 11886 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11887 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11888 pw.print(" pid="); 11889 if (r.app != null) pw.println(r.app.pid); 11890 else pw.println("(not running)"); 11891 if (dumpAll) { 11892 r.dump(pw, innerPrefix); 11893 } 11894 } 11895 if (r.app != null && r.app.thread != null) { 11896 // flush anything that is already in the PrintWriter since the thread is going 11897 // to write to the file descriptor directly 11898 pw.flush(); 11899 try { 11900 TransferPipe tp = new TransferPipe(); 11901 try { 11902 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11903 r.appToken, innerPrefix, args); 11904 tp.go(fd); 11905 } finally { 11906 tp.kill(); 11907 } 11908 } catch (IOException e) { 11909 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11910 } catch (RemoteException e) { 11911 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11912 } 11913 } 11914 } 11915 11916 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11917 int opti, boolean dumpAll, String dumpPackage) { 11918 boolean needSep = false; 11919 boolean onlyHistory = false; 11920 boolean printedAnything = false; 11921 11922 if ("history".equals(dumpPackage)) { 11923 if (opti < args.length && "-s".equals(args[opti])) { 11924 dumpAll = false; 11925 } 11926 onlyHistory = true; 11927 dumpPackage = null; 11928 } 11929 11930 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11931 if (!onlyHistory && dumpAll) { 11932 if (mRegisteredReceivers.size() > 0) { 11933 boolean printed = false; 11934 Iterator it = mRegisteredReceivers.values().iterator(); 11935 while (it.hasNext()) { 11936 ReceiverList r = (ReceiverList)it.next(); 11937 if (dumpPackage != null && (r.app == null || 11938 !dumpPackage.equals(r.app.info.packageName))) { 11939 continue; 11940 } 11941 if (!printed) { 11942 pw.println(" Registered Receivers:"); 11943 needSep = true; 11944 printed = true; 11945 printedAnything = true; 11946 } 11947 pw.print(" * "); pw.println(r); 11948 r.dump(pw, " "); 11949 } 11950 } 11951 11952 if (mReceiverResolver.dump(pw, needSep ? 11953 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11954 " ", dumpPackage, false)) { 11955 needSep = true; 11956 printedAnything = true; 11957 } 11958 } 11959 11960 for (BroadcastQueue q : mBroadcastQueues) { 11961 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11962 printedAnything |= needSep; 11963 } 11964 11965 needSep = true; 11966 11967 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11968 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11969 if (needSep) { 11970 pw.println(); 11971 } 11972 needSep = true; 11973 printedAnything = true; 11974 pw.print(" Sticky broadcasts for user "); 11975 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11976 StringBuilder sb = new StringBuilder(128); 11977 for (Map.Entry<String, ArrayList<Intent>> ent 11978 : mStickyBroadcasts.valueAt(user).entrySet()) { 11979 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11980 if (dumpAll) { 11981 pw.println(":"); 11982 ArrayList<Intent> intents = ent.getValue(); 11983 final int N = intents.size(); 11984 for (int i=0; i<N; i++) { 11985 sb.setLength(0); 11986 sb.append(" Intent: "); 11987 intents.get(i).toShortString(sb, false, true, false, false); 11988 pw.println(sb.toString()); 11989 Bundle bundle = intents.get(i).getExtras(); 11990 if (bundle != null) { 11991 pw.print(" "); 11992 pw.println(bundle.toString()); 11993 } 11994 } 11995 } else { 11996 pw.println(""); 11997 } 11998 } 11999 } 12000 } 12001 12002 if (!onlyHistory && dumpAll) { 12003 pw.println(); 12004 for (BroadcastQueue queue : mBroadcastQueues) { 12005 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12006 + queue.mBroadcastsScheduled); 12007 } 12008 pw.println(" mHandler:"); 12009 mHandler.dump(new PrintWriterPrinter(pw), " "); 12010 needSep = true; 12011 printedAnything = true; 12012 } 12013 12014 if (!printedAnything) { 12015 pw.println(" (nothing)"); 12016 } 12017 } 12018 12019 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12020 int opti, boolean dumpAll, String dumpPackage) { 12021 boolean needSep; 12022 boolean printedAnything = false; 12023 12024 ItemMatcher matcher = new ItemMatcher(); 12025 matcher.build(args, opti); 12026 12027 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12028 12029 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12030 printedAnything |= needSep; 12031 12032 if (mLaunchingProviders.size() > 0) { 12033 boolean printed = false; 12034 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12035 ContentProviderRecord r = mLaunchingProviders.get(i); 12036 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12037 continue; 12038 } 12039 if (!printed) { 12040 if (needSep) pw.println(); 12041 needSep = true; 12042 pw.println(" Launching content providers:"); 12043 printed = true; 12044 printedAnything = true; 12045 } 12046 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12047 pw.println(r); 12048 } 12049 } 12050 12051 if (mGrantedUriPermissions.size() > 0) { 12052 boolean printed = false; 12053 int dumpUid = -2; 12054 if (dumpPackage != null) { 12055 try { 12056 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12057 } catch (NameNotFoundException e) { 12058 dumpUid = -1; 12059 } 12060 } 12061 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12062 int uid = mGrantedUriPermissions.keyAt(i); 12063 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12064 continue; 12065 } 12066 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12067 if (!printed) { 12068 if (needSep) pw.println(); 12069 needSep = true; 12070 pw.println(" Granted Uri Permissions:"); 12071 printed = true; 12072 printedAnything = true; 12073 } 12074 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12075 for (UriPermission perm : perms.values()) { 12076 pw.print(" "); pw.println(perm); 12077 if (dumpAll) { 12078 perm.dump(pw, " "); 12079 } 12080 } 12081 } 12082 } 12083 12084 if (!printedAnything) { 12085 pw.println(" (nothing)"); 12086 } 12087 } 12088 12089 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12090 int opti, boolean dumpAll, String dumpPackage) { 12091 boolean printed = false; 12092 12093 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12094 12095 if (mIntentSenderRecords.size() > 0) { 12096 Iterator<WeakReference<PendingIntentRecord>> it 12097 = mIntentSenderRecords.values().iterator(); 12098 while (it.hasNext()) { 12099 WeakReference<PendingIntentRecord> ref = it.next(); 12100 PendingIntentRecord rec = ref != null ? ref.get(): null; 12101 if (dumpPackage != null && (rec == null 12102 || !dumpPackage.equals(rec.key.packageName))) { 12103 continue; 12104 } 12105 printed = true; 12106 if (rec != null) { 12107 pw.print(" * "); pw.println(rec); 12108 if (dumpAll) { 12109 rec.dump(pw, " "); 12110 } 12111 } else { 12112 pw.print(" * "); pw.println(ref); 12113 } 12114 } 12115 } 12116 12117 if (!printed) { 12118 pw.println(" (nothing)"); 12119 } 12120 } 12121 12122 private static final int dumpProcessList(PrintWriter pw, 12123 ActivityManagerService service, List list, 12124 String prefix, String normalLabel, String persistentLabel, 12125 String dumpPackage) { 12126 int numPers = 0; 12127 final int N = list.size()-1; 12128 for (int i=N; i>=0; i--) { 12129 ProcessRecord r = (ProcessRecord)list.get(i); 12130 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12131 continue; 12132 } 12133 pw.println(String.format("%s%s #%2d: %s", 12134 prefix, (r.persistent ? persistentLabel : normalLabel), 12135 i, r.toString())); 12136 if (r.persistent) { 12137 numPers++; 12138 } 12139 } 12140 return numPers; 12141 } 12142 12143 private static final boolean dumpProcessOomList(PrintWriter pw, 12144 ActivityManagerService service, List<ProcessRecord> origList, 12145 String prefix, String normalLabel, String persistentLabel, 12146 boolean inclDetails, String dumpPackage) { 12147 12148 ArrayList<Pair<ProcessRecord, Integer>> list 12149 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12150 for (int i=0; i<origList.size(); i++) { 12151 ProcessRecord r = origList.get(i); 12152 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12153 continue; 12154 } 12155 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12156 } 12157 12158 if (list.size() <= 0) { 12159 return false; 12160 } 12161 12162 Comparator<Pair<ProcessRecord, Integer>> comparator 12163 = new Comparator<Pair<ProcessRecord, Integer>>() { 12164 @Override 12165 public int compare(Pair<ProcessRecord, Integer> object1, 12166 Pair<ProcessRecord, Integer> object2) { 12167 if (object1.first.setAdj != object2.first.setAdj) { 12168 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12169 } 12170 if (object1.second.intValue() != object2.second.intValue()) { 12171 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12172 } 12173 return 0; 12174 } 12175 }; 12176 12177 Collections.sort(list, comparator); 12178 12179 final long curRealtime = SystemClock.elapsedRealtime(); 12180 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12181 final long curUptime = SystemClock.uptimeMillis(); 12182 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12183 12184 for (int i=list.size()-1; i>=0; i--) { 12185 ProcessRecord r = list.get(i).first; 12186 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12187 char schedGroup; 12188 switch (r.setSchedGroup) { 12189 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12190 schedGroup = 'B'; 12191 break; 12192 case Process.THREAD_GROUP_DEFAULT: 12193 schedGroup = 'F'; 12194 break; 12195 default: 12196 schedGroup = '?'; 12197 break; 12198 } 12199 char foreground; 12200 if (r.foregroundActivities) { 12201 foreground = 'A'; 12202 } else if (r.foregroundServices) { 12203 foreground = 'S'; 12204 } else { 12205 foreground = ' '; 12206 } 12207 String procState = ProcessList.makeProcStateString(r.curProcState); 12208 pw.print(prefix); 12209 pw.print(r.persistent ? persistentLabel : normalLabel); 12210 pw.print(" #"); 12211 int num = (origList.size()-1)-list.get(i).second; 12212 if (num < 10) pw.print(' '); 12213 pw.print(num); 12214 pw.print(": "); 12215 pw.print(oomAdj); 12216 pw.print(' '); 12217 pw.print(schedGroup); 12218 pw.print('/'); 12219 pw.print(foreground); 12220 pw.print('/'); 12221 pw.print(procState); 12222 pw.print(" trm:"); 12223 if (r.trimMemoryLevel < 10) pw.print(' '); 12224 pw.print(r.trimMemoryLevel); 12225 pw.print(' '); 12226 pw.print(r.toShortString()); 12227 pw.print(" ("); 12228 pw.print(r.adjType); 12229 pw.println(')'); 12230 if (r.adjSource != null || r.adjTarget != null) { 12231 pw.print(prefix); 12232 pw.print(" "); 12233 if (r.adjTarget instanceof ComponentName) { 12234 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12235 } else if (r.adjTarget != null) { 12236 pw.print(r.adjTarget.toString()); 12237 } else { 12238 pw.print("{null}"); 12239 } 12240 pw.print("<="); 12241 if (r.adjSource instanceof ProcessRecord) { 12242 pw.print("Proc{"); 12243 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12244 pw.println("}"); 12245 } else if (r.adjSource != null) { 12246 pw.println(r.adjSource.toString()); 12247 } else { 12248 pw.println("{null}"); 12249 } 12250 } 12251 if (inclDetails) { 12252 pw.print(prefix); 12253 pw.print(" "); 12254 pw.print("oom: max="); pw.print(r.maxAdj); 12255 pw.print(" curRaw="); pw.print(r.curRawAdj); 12256 pw.print(" setRaw="); pw.print(r.setRawAdj); 12257 pw.print(" cur="); pw.print(r.curAdj); 12258 pw.print(" set="); pw.println(r.setAdj); 12259 pw.print(prefix); 12260 pw.print(" "); 12261 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12262 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12263 pw.print(" lastPss="); pw.print(r.lastPss); 12264 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12265 pw.print(prefix); 12266 pw.print(" "); 12267 pw.print("keeping="); pw.print(r.keeping); 12268 pw.print(" cached="); pw.print(r.cached); 12269 pw.print(" empty="); pw.print(r.empty); 12270 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12271 12272 if (!r.keeping) { 12273 if (r.lastWakeTime != 0) { 12274 long wtime; 12275 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12276 synchronized (stats) { 12277 wtime = stats.getProcessWakeTime(r.info.uid, 12278 r.pid, curRealtime); 12279 } 12280 long timeUsed = wtime - r.lastWakeTime; 12281 pw.print(prefix); 12282 pw.print(" "); 12283 pw.print("keep awake over "); 12284 TimeUtils.formatDuration(realtimeSince, pw); 12285 pw.print(" used "); 12286 TimeUtils.formatDuration(timeUsed, pw); 12287 pw.print(" ("); 12288 pw.print((timeUsed*100)/realtimeSince); 12289 pw.println("%)"); 12290 } 12291 if (r.lastCpuTime != 0) { 12292 long timeUsed = r.curCpuTime - r.lastCpuTime; 12293 pw.print(prefix); 12294 pw.print(" "); 12295 pw.print("run cpu over "); 12296 TimeUtils.formatDuration(uptimeSince, pw); 12297 pw.print(" used "); 12298 TimeUtils.formatDuration(timeUsed, pw); 12299 pw.print(" ("); 12300 pw.print((timeUsed*100)/uptimeSince); 12301 pw.println("%)"); 12302 } 12303 } 12304 } 12305 } 12306 return true; 12307 } 12308 12309 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12310 ArrayList<ProcessRecord> procs; 12311 synchronized (this) { 12312 if (args != null && args.length > start 12313 && args[start].charAt(0) != '-') { 12314 procs = new ArrayList<ProcessRecord>(); 12315 int pid = -1; 12316 try { 12317 pid = Integer.parseInt(args[start]); 12318 } catch (NumberFormatException e) { 12319 } 12320 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12321 ProcessRecord proc = mLruProcesses.get(i); 12322 if (proc.pid == pid) { 12323 procs.add(proc); 12324 } else if (proc.processName.equals(args[start])) { 12325 procs.add(proc); 12326 } 12327 } 12328 if (procs.size() <= 0) { 12329 return null; 12330 } 12331 } else { 12332 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12333 } 12334 } 12335 return procs; 12336 } 12337 12338 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12339 PrintWriter pw, String[] args) { 12340 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12341 if (procs == null) { 12342 pw.println("No process found for: " + args[0]); 12343 return; 12344 } 12345 12346 long uptime = SystemClock.uptimeMillis(); 12347 long realtime = SystemClock.elapsedRealtime(); 12348 pw.println("Applications Graphics Acceleration Info:"); 12349 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12350 12351 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12352 ProcessRecord r = procs.get(i); 12353 if (r.thread != null) { 12354 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12355 pw.flush(); 12356 try { 12357 TransferPipe tp = new TransferPipe(); 12358 try { 12359 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12360 tp.go(fd); 12361 } finally { 12362 tp.kill(); 12363 } 12364 } catch (IOException e) { 12365 pw.println("Failure while dumping the app: " + r); 12366 pw.flush(); 12367 } catch (RemoteException e) { 12368 pw.println("Got a RemoteException while dumping the app " + r); 12369 pw.flush(); 12370 } 12371 } 12372 } 12373 } 12374 12375 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12376 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12377 if (procs == null) { 12378 pw.println("No process found for: " + args[0]); 12379 return; 12380 } 12381 12382 pw.println("Applications Database Info:"); 12383 12384 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12385 ProcessRecord r = procs.get(i); 12386 if (r.thread != null) { 12387 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12388 pw.flush(); 12389 try { 12390 TransferPipe tp = new TransferPipe(); 12391 try { 12392 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12393 tp.go(fd); 12394 } finally { 12395 tp.kill(); 12396 } 12397 } catch (IOException e) { 12398 pw.println("Failure while dumping the app: " + r); 12399 pw.flush(); 12400 } catch (RemoteException e) { 12401 pw.println("Got a RemoteException while dumping the app " + r); 12402 pw.flush(); 12403 } 12404 } 12405 } 12406 } 12407 12408 final static class MemItem { 12409 final boolean isProc; 12410 final String label; 12411 final String shortLabel; 12412 final long pss; 12413 final int id; 12414 final boolean hasActivities; 12415 ArrayList<MemItem> subitems; 12416 12417 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12418 boolean _hasActivities) { 12419 isProc = true; 12420 label = _label; 12421 shortLabel = _shortLabel; 12422 pss = _pss; 12423 id = _id; 12424 hasActivities = _hasActivities; 12425 } 12426 12427 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12428 isProc = false; 12429 label = _label; 12430 shortLabel = _shortLabel; 12431 pss = _pss; 12432 id = _id; 12433 hasActivities = false; 12434 } 12435 } 12436 12437 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12438 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12439 if (sort && !isCompact) { 12440 Collections.sort(items, new Comparator<MemItem>() { 12441 @Override 12442 public int compare(MemItem lhs, MemItem rhs) { 12443 if (lhs.pss < rhs.pss) { 12444 return 1; 12445 } else if (lhs.pss > rhs.pss) { 12446 return -1; 12447 } 12448 return 0; 12449 } 12450 }); 12451 } 12452 12453 for (int i=0; i<items.size(); i++) { 12454 MemItem mi = items.get(i); 12455 if (!isCompact) { 12456 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12457 } else if (mi.isProc) { 12458 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12459 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12460 pw.println(mi.hasActivities ? ",a" : ",e"); 12461 } else { 12462 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12463 pw.println(mi.pss); 12464 } 12465 if (mi.subitems != null) { 12466 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12467 true, isCompact); 12468 } 12469 } 12470 } 12471 12472 // These are in KB. 12473 static final long[] DUMP_MEM_BUCKETS = new long[] { 12474 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12475 120*1024, 160*1024, 200*1024, 12476 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12477 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12478 }; 12479 12480 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12481 boolean stackLike) { 12482 int start = label.lastIndexOf('.'); 12483 if (start >= 0) start++; 12484 else start = 0; 12485 int end = label.length(); 12486 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12487 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12488 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12489 out.append(bucket); 12490 out.append(stackLike ? "MB." : "MB "); 12491 out.append(label, start, end); 12492 return; 12493 } 12494 } 12495 out.append(memKB/1024); 12496 out.append(stackLike ? "MB." : "MB "); 12497 out.append(label, start, end); 12498 } 12499 12500 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12501 ProcessList.NATIVE_ADJ, 12502 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12503 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12504 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12505 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12506 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12507 }; 12508 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12509 "Native", 12510 "System", "Persistent", "Foreground", 12511 "Visible", "Perceptible", 12512 "Heavy Weight", "Backup", 12513 "A Services", "Home", 12514 "Previous", "B Services", "Cached" 12515 }; 12516 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12517 "native", 12518 "sys", "pers", "fore", 12519 "vis", "percept", 12520 "heavy", "backup", 12521 "servicea", "home", 12522 "prev", "serviceb", "cached" 12523 }; 12524 12525 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12526 long realtime, boolean isCheckinRequest, boolean isCompact) { 12527 if (isCheckinRequest || isCompact) { 12528 // short checkin version 12529 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12530 } else { 12531 pw.println("Applications Memory Usage (kB):"); 12532 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12533 } 12534 } 12535 12536 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12537 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12538 boolean dumpDetails = false; 12539 boolean dumpFullDetails = false; 12540 boolean dumpDalvik = false; 12541 boolean oomOnly = false; 12542 boolean isCompact = false; 12543 boolean localOnly = false; 12544 12545 int opti = 0; 12546 while (opti < args.length) { 12547 String opt = args[opti]; 12548 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12549 break; 12550 } 12551 opti++; 12552 if ("-a".equals(opt)) { 12553 dumpDetails = true; 12554 dumpFullDetails = true; 12555 dumpDalvik = true; 12556 } else if ("-d".equals(opt)) { 12557 dumpDalvik = true; 12558 } else if ("-c".equals(opt)) { 12559 isCompact = true; 12560 } else if ("--oom".equals(opt)) { 12561 oomOnly = true; 12562 } else if ("--local".equals(opt)) { 12563 localOnly = true; 12564 } else if ("-h".equals(opt)) { 12565 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12566 pw.println(" -a: include all available information for each process."); 12567 pw.println(" -d: include dalvik details when dumping process details."); 12568 pw.println(" -c: dump in a compact machine-parseable representation."); 12569 pw.println(" --oom: only show processes organized by oom adj."); 12570 pw.println(" --local: only collect details locally, don't call process."); 12571 pw.println("If [process] is specified it can be the name or "); 12572 pw.println("pid of a specific process to dump."); 12573 return; 12574 } else { 12575 pw.println("Unknown argument: " + opt + "; use -h for help"); 12576 } 12577 } 12578 12579 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12580 long uptime = SystemClock.uptimeMillis(); 12581 long realtime = SystemClock.elapsedRealtime(); 12582 final long[] tmpLong = new long[1]; 12583 12584 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12585 if (procs == null) { 12586 // No Java processes. Maybe they want to print a native process. 12587 if (args != null && args.length > opti 12588 && args[opti].charAt(0) != '-') { 12589 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12590 = new ArrayList<ProcessCpuTracker.Stats>(); 12591 updateCpuStatsNow(); 12592 int findPid = -1; 12593 try { 12594 findPid = Integer.parseInt(args[opti]); 12595 } catch (NumberFormatException e) { 12596 } 12597 synchronized (mProcessCpuThread) { 12598 final int N = mProcessCpuTracker.countStats(); 12599 for (int i=0; i<N; i++) { 12600 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12601 if (st.pid == findPid || (st.baseName != null 12602 && st.baseName.equals(args[opti]))) { 12603 nativeProcs.add(st); 12604 } 12605 } 12606 } 12607 if (nativeProcs.size() > 0) { 12608 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12609 isCompact); 12610 Debug.MemoryInfo mi = null; 12611 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12612 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12613 final int pid = r.pid; 12614 if (!isCheckinRequest && dumpDetails) { 12615 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12616 } 12617 if (mi == null) { 12618 mi = new Debug.MemoryInfo(); 12619 } 12620 if (dumpDetails || (!brief && !oomOnly)) { 12621 Debug.getMemoryInfo(pid, mi); 12622 } else { 12623 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12624 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12625 } 12626 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12627 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12628 if (isCheckinRequest) { 12629 pw.println(); 12630 } 12631 } 12632 return; 12633 } 12634 } 12635 pw.println("No process found for: " + args[opti]); 12636 return; 12637 } 12638 12639 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12640 dumpDetails = true; 12641 } 12642 12643 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12644 12645 String[] innerArgs = new String[args.length-opti]; 12646 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12647 12648 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12649 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12650 long nativePss=0, dalvikPss=0, otherPss=0; 12651 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12652 12653 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12654 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12655 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12656 12657 long totalPss = 0; 12658 long cachedPss = 0; 12659 12660 Debug.MemoryInfo mi = null; 12661 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12662 final ProcessRecord r = procs.get(i); 12663 final IApplicationThread thread; 12664 final int pid; 12665 final int oomAdj; 12666 final boolean hasActivities; 12667 synchronized (this) { 12668 thread = r.thread; 12669 pid = r.pid; 12670 oomAdj = r.getSetAdjWithServices(); 12671 hasActivities = r.activities.size() > 0; 12672 } 12673 if (thread != null) { 12674 if (!isCheckinRequest && dumpDetails) { 12675 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12676 } 12677 if (mi == null) { 12678 mi = new Debug.MemoryInfo(); 12679 } 12680 if (dumpDetails || (!brief && !oomOnly)) { 12681 Debug.getMemoryInfo(pid, mi); 12682 } else { 12683 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12684 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12685 } 12686 if (dumpDetails) { 12687 if (localOnly) { 12688 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12689 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12690 if (isCheckinRequest) { 12691 pw.println(); 12692 } 12693 } else { 12694 try { 12695 pw.flush(); 12696 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12697 dumpDalvik, innerArgs); 12698 } catch (RemoteException e) { 12699 if (!isCheckinRequest) { 12700 pw.println("Got RemoteException!"); 12701 pw.flush(); 12702 } 12703 } 12704 } 12705 } 12706 12707 final long myTotalPss = mi.getTotalPss(); 12708 final long myTotalUss = mi.getTotalUss(); 12709 12710 synchronized (this) { 12711 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12712 // Record this for posterity if the process has been stable. 12713 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12714 } 12715 } 12716 12717 if (!isCheckinRequest && mi != null) { 12718 totalPss += myTotalPss; 12719 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12720 (hasActivities ? " / activities)" : ")"), 12721 r.processName, myTotalPss, pid, hasActivities); 12722 procMems.add(pssItem); 12723 procMemsMap.put(pid, pssItem); 12724 12725 nativePss += mi.nativePss; 12726 dalvikPss += mi.dalvikPss; 12727 otherPss += mi.otherPss; 12728 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12729 long mem = mi.getOtherPss(j); 12730 miscPss[j] += mem; 12731 otherPss -= mem; 12732 } 12733 12734 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12735 cachedPss += myTotalPss; 12736 } 12737 12738 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12739 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12740 || oomIndex == (oomPss.length-1)) { 12741 oomPss[oomIndex] += myTotalPss; 12742 if (oomProcs[oomIndex] == null) { 12743 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12744 } 12745 oomProcs[oomIndex].add(pssItem); 12746 break; 12747 } 12748 } 12749 } 12750 } 12751 } 12752 12753 long nativeProcTotalPss = 0; 12754 12755 if (!isCheckinRequest && procs.size() > 1) { 12756 // If we are showing aggregations, also look for native processes to 12757 // include so that our aggregations are more accurate. 12758 updateCpuStatsNow(); 12759 synchronized (mProcessCpuThread) { 12760 final int N = mProcessCpuTracker.countStats(); 12761 for (int i=0; i<N; i++) { 12762 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12763 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12764 if (mi == null) { 12765 mi = new Debug.MemoryInfo(); 12766 } 12767 if (!brief && !oomOnly) { 12768 Debug.getMemoryInfo(st.pid, mi); 12769 } else { 12770 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12771 mi.nativePrivateDirty = (int)tmpLong[0]; 12772 } 12773 12774 final long myTotalPss = mi.getTotalPss(); 12775 totalPss += myTotalPss; 12776 nativeProcTotalPss += myTotalPss; 12777 12778 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12779 st.name, myTotalPss, st.pid, false); 12780 procMems.add(pssItem); 12781 12782 nativePss += mi.nativePss; 12783 dalvikPss += mi.dalvikPss; 12784 otherPss += mi.otherPss; 12785 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12786 long mem = mi.getOtherPss(j); 12787 miscPss[j] += mem; 12788 otherPss -= mem; 12789 } 12790 oomPss[0] += myTotalPss; 12791 if (oomProcs[0] == null) { 12792 oomProcs[0] = new ArrayList<MemItem>(); 12793 } 12794 oomProcs[0].add(pssItem); 12795 } 12796 } 12797 } 12798 12799 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12800 12801 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12802 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12803 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12804 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12805 String label = Debug.MemoryInfo.getOtherLabel(j); 12806 catMems.add(new MemItem(label, label, miscPss[j], j)); 12807 } 12808 12809 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12810 for (int j=0; j<oomPss.length; j++) { 12811 if (oomPss[j] != 0) { 12812 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12813 : DUMP_MEM_OOM_LABEL[j]; 12814 MemItem item = new MemItem(label, label, oomPss[j], 12815 DUMP_MEM_OOM_ADJ[j]); 12816 item.subitems = oomProcs[j]; 12817 oomMems.add(item); 12818 } 12819 } 12820 12821 if (!brief && !oomOnly && !isCompact) { 12822 pw.println(); 12823 pw.println("Total PSS by process:"); 12824 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12825 pw.println(); 12826 } 12827 if (!isCompact) { 12828 pw.println("Total PSS by OOM adjustment:"); 12829 } 12830 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12831 if (!brief && !oomOnly) { 12832 PrintWriter out = categoryPw != null ? categoryPw : pw; 12833 if (!isCompact) { 12834 out.println(); 12835 out.println("Total PSS by category:"); 12836 } 12837 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12838 } 12839 if (!isCompact) { 12840 pw.println(); 12841 } 12842 MemInfoReader memInfo = new MemInfoReader(); 12843 memInfo.readMemInfo(); 12844 if (nativeProcTotalPss > 0) { 12845 synchronized (this) { 12846 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12847 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12848 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12849 nativeProcTotalPss); 12850 } 12851 } 12852 if (!brief) { 12853 if (!isCompact) { 12854 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12855 pw.print(" kB (status "); 12856 switch (mLastMemoryLevel) { 12857 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12858 pw.println("normal)"); 12859 break; 12860 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12861 pw.println("moderate)"); 12862 break; 12863 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12864 pw.println("low)"); 12865 break; 12866 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12867 pw.println("critical)"); 12868 break; 12869 default: 12870 pw.print(mLastMemoryLevel); 12871 pw.println(")"); 12872 break; 12873 } 12874 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12875 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12876 pw.print(cachedPss); pw.print(" cached pss + "); 12877 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12878 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12879 } else { 12880 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12881 pw.print(cachedPss + memInfo.getCachedSizeKb() 12882 + memInfo.getFreeSizeKb()); pw.print(","); 12883 pw.println(totalPss - cachedPss); 12884 } 12885 } 12886 if (!isCompact) { 12887 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12888 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12889 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12890 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12891 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12892 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12893 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12894 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12895 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12896 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12897 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12898 } 12899 if (!brief) { 12900 if (memInfo.getZramTotalSizeKb() != 0) { 12901 if (!isCompact) { 12902 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12903 pw.print(" kB physical used for "); 12904 pw.print(memInfo.getSwapTotalSizeKb() 12905 - memInfo.getSwapFreeSizeKb()); 12906 pw.print(" kB in swap ("); 12907 pw.print(memInfo.getSwapTotalSizeKb()); 12908 pw.println(" kB total swap)"); 12909 } else { 12910 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12911 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12912 pw.println(memInfo.getSwapFreeSizeKb()); 12913 } 12914 } 12915 final int[] SINGLE_LONG_FORMAT = new int[] { 12916 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12917 }; 12918 long[] longOut = new long[1]; 12919 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12920 SINGLE_LONG_FORMAT, null, longOut, null); 12921 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12922 longOut[0] = 0; 12923 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12924 SINGLE_LONG_FORMAT, null, longOut, null); 12925 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12926 longOut[0] = 0; 12927 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12928 SINGLE_LONG_FORMAT, null, longOut, null); 12929 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12930 longOut[0] = 0; 12931 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12932 SINGLE_LONG_FORMAT, null, longOut, null); 12933 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12934 if (!isCompact) { 12935 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12936 pw.print(" KSM: "); pw.print(sharing); 12937 pw.print(" kB saved from shared "); 12938 pw.print(shared); pw.println(" kB"); 12939 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12940 pw.print(voltile); pw.println(" kB volatile"); 12941 } 12942 pw.print(" Tuning: "); 12943 pw.print(ActivityManager.staticGetMemoryClass()); 12944 pw.print(" (large "); 12945 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12946 pw.print("), oom "); 12947 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12948 pw.print(" kB"); 12949 pw.print(", restore limit "); 12950 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12951 pw.print(" kB"); 12952 if (ActivityManager.isLowRamDeviceStatic()) { 12953 pw.print(" (low-ram)"); 12954 } 12955 if (ActivityManager.isHighEndGfx()) { 12956 pw.print(" (high-end-gfx)"); 12957 } 12958 pw.println(); 12959 } else { 12960 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12961 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12962 pw.println(voltile); 12963 pw.print("tuning,"); 12964 pw.print(ActivityManager.staticGetMemoryClass()); 12965 pw.print(','); 12966 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12967 pw.print(','); 12968 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12969 if (ActivityManager.isLowRamDeviceStatic()) { 12970 pw.print(",low-ram"); 12971 } 12972 if (ActivityManager.isHighEndGfx()) { 12973 pw.print(",high-end-gfx"); 12974 } 12975 pw.println(); 12976 } 12977 } 12978 } 12979 } 12980 12981 /** 12982 * Searches array of arguments for the specified string 12983 * @param args array of argument strings 12984 * @param value value to search for 12985 * @return true if the value is contained in the array 12986 */ 12987 private static boolean scanArgs(String[] args, String value) { 12988 if (args != null) { 12989 for (String arg : args) { 12990 if (value.equals(arg)) { 12991 return true; 12992 } 12993 } 12994 } 12995 return false; 12996 } 12997 12998 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12999 ContentProviderRecord cpr, boolean always) { 13000 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13001 13002 if (!inLaunching || always) { 13003 synchronized (cpr) { 13004 cpr.launchingApp = null; 13005 cpr.notifyAll(); 13006 } 13007 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13008 String names[] = cpr.info.authority.split(";"); 13009 for (int j = 0; j < names.length; j++) { 13010 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13011 } 13012 } 13013 13014 for (int i=0; i<cpr.connections.size(); i++) { 13015 ContentProviderConnection conn = cpr.connections.get(i); 13016 if (conn.waiting) { 13017 // If this connection is waiting for the provider, then we don't 13018 // need to mess with its process unless we are always removing 13019 // or for some reason the provider is not currently launching. 13020 if (inLaunching && !always) { 13021 continue; 13022 } 13023 } 13024 ProcessRecord capp = conn.client; 13025 conn.dead = true; 13026 if (conn.stableCount > 0) { 13027 if (!capp.persistent && capp.thread != null 13028 && capp.pid != 0 13029 && capp.pid != MY_PID) { 13030 killUnneededProcessLocked(capp, "depends on provider " 13031 + cpr.name.flattenToShortString() 13032 + " in dying proc " + (proc != null ? proc.processName : "??")); 13033 } 13034 } else if (capp.thread != null && conn.provider.provider != null) { 13035 try { 13036 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13037 } catch (RemoteException e) { 13038 } 13039 // In the protocol here, we don't expect the client to correctly 13040 // clean up this connection, we'll just remove it. 13041 cpr.connections.remove(i); 13042 conn.client.conProviders.remove(conn); 13043 } 13044 } 13045 13046 if (inLaunching && always) { 13047 mLaunchingProviders.remove(cpr); 13048 } 13049 return inLaunching; 13050 } 13051 13052 /** 13053 * Main code for cleaning up a process when it has gone away. This is 13054 * called both as a result of the process dying, or directly when stopping 13055 * a process when running in single process mode. 13056 */ 13057 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13058 boolean restarting, boolean allowRestart, int index) { 13059 if (index >= 0) { 13060 removeLruProcessLocked(app); 13061 ProcessList.remove(app.pid); 13062 } 13063 13064 mProcessesToGc.remove(app); 13065 mPendingPssProcesses.remove(app); 13066 13067 // Dismiss any open dialogs. 13068 if (app.crashDialog != null && !app.forceCrashReport) { 13069 app.crashDialog.dismiss(); 13070 app.crashDialog = null; 13071 } 13072 if (app.anrDialog != null) { 13073 app.anrDialog.dismiss(); 13074 app.anrDialog = null; 13075 } 13076 if (app.waitDialog != null) { 13077 app.waitDialog.dismiss(); 13078 app.waitDialog = null; 13079 } 13080 13081 app.crashing = false; 13082 app.notResponding = false; 13083 13084 app.resetPackageList(mProcessStats); 13085 app.unlinkDeathRecipient(); 13086 app.makeInactive(mProcessStats); 13087 app.waitingToKill = null; 13088 app.forcingToForeground = null; 13089 updateProcessForegroundLocked(app, false, false); 13090 app.foregroundActivities = false; 13091 app.hasShownUi = false; 13092 app.treatLikeActivity = false; 13093 app.hasAboveClient = false; 13094 app.hasClientActivities = false; 13095 13096 mServices.killServicesLocked(app, allowRestart); 13097 13098 boolean restart = false; 13099 13100 // Remove published content providers. 13101 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13102 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13103 final boolean always = app.bad || !allowRestart; 13104 if (removeDyingProviderLocked(app, cpr, always) || always) { 13105 // We left the provider in the launching list, need to 13106 // restart it. 13107 restart = true; 13108 } 13109 13110 cpr.provider = null; 13111 cpr.proc = null; 13112 } 13113 app.pubProviders.clear(); 13114 13115 // Take care of any launching providers waiting for this process. 13116 if (checkAppInLaunchingProvidersLocked(app, false)) { 13117 restart = true; 13118 } 13119 13120 // Unregister from connected content providers. 13121 if (!app.conProviders.isEmpty()) { 13122 for (int i=0; i<app.conProviders.size(); i++) { 13123 ContentProviderConnection conn = app.conProviders.get(i); 13124 conn.provider.connections.remove(conn); 13125 } 13126 app.conProviders.clear(); 13127 } 13128 13129 // At this point there may be remaining entries in mLaunchingProviders 13130 // where we were the only one waiting, so they are no longer of use. 13131 // Look for these and clean up if found. 13132 // XXX Commented out for now. Trying to figure out a way to reproduce 13133 // the actual situation to identify what is actually going on. 13134 if (false) { 13135 for (int i=0; i<mLaunchingProviders.size(); i++) { 13136 ContentProviderRecord cpr = (ContentProviderRecord) 13137 mLaunchingProviders.get(i); 13138 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13139 synchronized (cpr) { 13140 cpr.launchingApp = null; 13141 cpr.notifyAll(); 13142 } 13143 } 13144 } 13145 } 13146 13147 skipCurrentReceiverLocked(app); 13148 13149 // Unregister any receivers. 13150 for (int i=app.receivers.size()-1; i>=0; i--) { 13151 removeReceiverLocked(app.receivers.valueAt(i)); 13152 } 13153 app.receivers.clear(); 13154 13155 // If the app is undergoing backup, tell the backup manager about it 13156 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13157 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13158 + mBackupTarget.appInfo + " died during backup"); 13159 try { 13160 IBackupManager bm = IBackupManager.Stub.asInterface( 13161 ServiceManager.getService(Context.BACKUP_SERVICE)); 13162 bm.agentDisconnected(app.info.packageName); 13163 } catch (RemoteException e) { 13164 // can't happen; backup manager is local 13165 } 13166 } 13167 13168 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13169 ProcessChangeItem item = mPendingProcessChanges.get(i); 13170 if (item.pid == app.pid) { 13171 mPendingProcessChanges.remove(i); 13172 mAvailProcessChanges.add(item); 13173 } 13174 } 13175 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13176 13177 // If the caller is restarting this app, then leave it in its 13178 // current lists and let the caller take care of it. 13179 if (restarting) { 13180 return; 13181 } 13182 13183 if (!app.persistent || app.isolated) { 13184 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13185 "Removing non-persistent process during cleanup: " + app); 13186 mProcessNames.remove(app.processName, app.uid); 13187 mIsolatedProcesses.remove(app.uid); 13188 if (mHeavyWeightProcess == app) { 13189 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13190 mHeavyWeightProcess.userId, 0)); 13191 mHeavyWeightProcess = null; 13192 } 13193 } else if (!app.removed) { 13194 // This app is persistent, so we need to keep its record around. 13195 // If it is not already on the pending app list, add it there 13196 // and start a new process for it. 13197 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13198 mPersistentStartingProcesses.add(app); 13199 restart = true; 13200 } 13201 } 13202 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13203 "Clean-up removing on hold: " + app); 13204 mProcessesOnHold.remove(app); 13205 13206 if (app == mHomeProcess) { 13207 mHomeProcess = null; 13208 } 13209 if (app == mPreviousProcess) { 13210 mPreviousProcess = null; 13211 } 13212 13213 if (restart && !app.isolated) { 13214 // We have components that still need to be running in the 13215 // process, so re-launch it. 13216 mProcessNames.put(app.processName, app.uid, app); 13217 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13218 } else if (app.pid > 0 && app.pid != MY_PID) { 13219 // Goodbye! 13220 boolean removed; 13221 synchronized (mPidsSelfLocked) { 13222 mPidsSelfLocked.remove(app.pid); 13223 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13224 } 13225 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13226 app.processName, app.info.uid); 13227 if (app.isolated) { 13228 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13229 } 13230 app.setPid(0); 13231 } 13232 } 13233 13234 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13235 // Look through the content providers we are waiting to have launched, 13236 // and if any run in this process then either schedule a restart of 13237 // the process or kill the client waiting for it if this process has 13238 // gone bad. 13239 int NL = mLaunchingProviders.size(); 13240 boolean restart = false; 13241 for (int i=0; i<NL; i++) { 13242 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13243 if (cpr.launchingApp == app) { 13244 if (!alwaysBad && !app.bad) { 13245 restart = true; 13246 } else { 13247 removeDyingProviderLocked(app, cpr, true); 13248 // cpr should have been removed from mLaunchingProviders 13249 NL = mLaunchingProviders.size(); 13250 i--; 13251 } 13252 } 13253 } 13254 return restart; 13255 } 13256 13257 // ========================================================= 13258 // SERVICES 13259 // ========================================================= 13260 13261 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13262 int flags) { 13263 enforceNotIsolatedCaller("getServices"); 13264 synchronized (this) { 13265 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13266 } 13267 } 13268 13269 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13270 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13271 synchronized (this) { 13272 return mServices.getRunningServiceControlPanelLocked(name); 13273 } 13274 } 13275 13276 public ComponentName startService(IApplicationThread caller, Intent service, 13277 String resolvedType, int userId) { 13278 enforceNotIsolatedCaller("startService"); 13279 // Refuse possible leaked file descriptors 13280 if (service != null && service.hasFileDescriptors() == true) { 13281 throw new IllegalArgumentException("File descriptors passed in Intent"); 13282 } 13283 13284 if (DEBUG_SERVICE) 13285 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13286 synchronized(this) { 13287 final int callingPid = Binder.getCallingPid(); 13288 final int callingUid = Binder.getCallingUid(); 13289 final long origId = Binder.clearCallingIdentity(); 13290 ComponentName res = mServices.startServiceLocked(caller, service, 13291 resolvedType, callingPid, callingUid, userId); 13292 Binder.restoreCallingIdentity(origId); 13293 return res; 13294 } 13295 } 13296 13297 ComponentName startServiceInPackage(int uid, 13298 Intent service, String resolvedType, int userId) { 13299 synchronized(this) { 13300 if (DEBUG_SERVICE) 13301 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13302 final long origId = Binder.clearCallingIdentity(); 13303 ComponentName res = mServices.startServiceLocked(null, service, 13304 resolvedType, -1, uid, userId); 13305 Binder.restoreCallingIdentity(origId); 13306 return res; 13307 } 13308 } 13309 13310 public int stopService(IApplicationThread caller, Intent service, 13311 String resolvedType, int userId) { 13312 enforceNotIsolatedCaller("stopService"); 13313 // Refuse possible leaked file descriptors 13314 if (service != null && service.hasFileDescriptors() == true) { 13315 throw new IllegalArgumentException("File descriptors passed in Intent"); 13316 } 13317 13318 synchronized(this) { 13319 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13320 } 13321 } 13322 13323 public IBinder peekService(Intent service, String resolvedType) { 13324 enforceNotIsolatedCaller("peekService"); 13325 // Refuse possible leaked file descriptors 13326 if (service != null && service.hasFileDescriptors() == true) { 13327 throw new IllegalArgumentException("File descriptors passed in Intent"); 13328 } 13329 synchronized(this) { 13330 return mServices.peekServiceLocked(service, resolvedType); 13331 } 13332 } 13333 13334 public boolean stopServiceToken(ComponentName className, IBinder token, 13335 int startId) { 13336 synchronized(this) { 13337 return mServices.stopServiceTokenLocked(className, token, startId); 13338 } 13339 } 13340 13341 public void setServiceForeground(ComponentName className, IBinder token, 13342 int id, Notification notification, boolean removeNotification) { 13343 synchronized(this) { 13344 mServices.setServiceForegroundLocked(className, token, id, notification, 13345 removeNotification); 13346 } 13347 } 13348 13349 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13350 boolean requireFull, String name, String callerPackage) { 13351 final int callingUserId = UserHandle.getUserId(callingUid); 13352 if (callingUserId != userId) { 13353 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13354 if ((requireFull || checkComponentPermission( 13355 android.Manifest.permission.INTERACT_ACROSS_USERS, 13356 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13357 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13358 callingPid, callingUid, -1, true) 13359 != PackageManager.PERMISSION_GRANTED) { 13360 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13361 // In this case, they would like to just execute as their 13362 // owner user instead of failing. 13363 userId = callingUserId; 13364 } else { 13365 StringBuilder builder = new StringBuilder(128); 13366 builder.append("Permission Denial: "); 13367 builder.append(name); 13368 if (callerPackage != null) { 13369 builder.append(" from "); 13370 builder.append(callerPackage); 13371 } 13372 builder.append(" asks to run as user "); 13373 builder.append(userId); 13374 builder.append(" but is calling from user "); 13375 builder.append(UserHandle.getUserId(callingUid)); 13376 builder.append("; this requires "); 13377 builder.append(INTERACT_ACROSS_USERS_FULL); 13378 if (!requireFull) { 13379 builder.append(" or "); 13380 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13381 } 13382 String msg = builder.toString(); 13383 Slog.w(TAG, msg); 13384 throw new SecurityException(msg); 13385 } 13386 } 13387 } 13388 if (userId == UserHandle.USER_CURRENT 13389 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13390 // Note that we may be accessing this outside of a lock... 13391 // shouldn't be a big deal, if this is being called outside 13392 // of a locked context there is intrinsically a race with 13393 // the value the caller will receive and someone else changing it. 13394 userId = mCurrentUserId; 13395 } 13396 if (!allowAll && userId < 0) { 13397 throw new IllegalArgumentException( 13398 "Call does not support special user #" + userId); 13399 } 13400 } 13401 return userId; 13402 } 13403 13404 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13405 String className, int flags) { 13406 boolean result = false; 13407 // For apps that don't have pre-defined UIDs, check for permission 13408 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13409 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13410 if (ActivityManager.checkUidPermission( 13411 android.Manifest.permission.INTERACT_ACROSS_USERS, 13412 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13413 ComponentName comp = new ComponentName(aInfo.packageName, className); 13414 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13415 + " requests FLAG_SINGLE_USER, but app does not hold " 13416 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13417 Slog.w(TAG, msg); 13418 throw new SecurityException(msg); 13419 } 13420 // Permission passed 13421 result = true; 13422 } 13423 } else if ("system".equals(componentProcessName)) { 13424 result = true; 13425 } else { 13426 // App with pre-defined UID, check if it's a persistent app 13427 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13428 } 13429 if (DEBUG_MU) { 13430 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13431 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13432 } 13433 return result; 13434 } 13435 13436 /** 13437 * Checks to see if the caller is in the same app as the singleton 13438 * component, or the component is in a special app. It allows special apps 13439 * to export singleton components but prevents exporting singleton 13440 * components for regular apps. 13441 */ 13442 boolean isValidSingletonCall(int callingUid, int componentUid) { 13443 int componentAppId = UserHandle.getAppId(componentUid); 13444 return UserHandle.isSameApp(callingUid, componentUid) 13445 || componentAppId == Process.SYSTEM_UID 13446 || componentAppId == Process.PHONE_UID 13447 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13448 == PackageManager.PERMISSION_GRANTED; 13449 } 13450 13451 public int bindService(IApplicationThread caller, IBinder token, 13452 Intent service, String resolvedType, 13453 IServiceConnection connection, int flags, int userId) { 13454 enforceNotIsolatedCaller("bindService"); 13455 // Refuse possible leaked file descriptors 13456 if (service != null && service.hasFileDescriptors() == true) { 13457 throw new IllegalArgumentException("File descriptors passed in Intent"); 13458 } 13459 13460 synchronized(this) { 13461 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13462 connection, flags, userId); 13463 } 13464 } 13465 13466 public boolean unbindService(IServiceConnection connection) { 13467 synchronized (this) { 13468 return mServices.unbindServiceLocked(connection); 13469 } 13470 } 13471 13472 public void publishService(IBinder token, Intent intent, IBinder service) { 13473 // Refuse possible leaked file descriptors 13474 if (intent != null && intent.hasFileDescriptors() == true) { 13475 throw new IllegalArgumentException("File descriptors passed in Intent"); 13476 } 13477 13478 synchronized(this) { 13479 if (!(token instanceof ServiceRecord)) { 13480 throw new IllegalArgumentException("Invalid service token"); 13481 } 13482 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13483 } 13484 } 13485 13486 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13487 // Refuse possible leaked file descriptors 13488 if (intent != null && intent.hasFileDescriptors() == true) { 13489 throw new IllegalArgumentException("File descriptors passed in Intent"); 13490 } 13491 13492 synchronized(this) { 13493 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13494 } 13495 } 13496 13497 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13498 synchronized(this) { 13499 if (!(token instanceof ServiceRecord)) { 13500 throw new IllegalArgumentException("Invalid service token"); 13501 } 13502 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13503 } 13504 } 13505 13506 // ========================================================= 13507 // BACKUP AND RESTORE 13508 // ========================================================= 13509 13510 // Cause the target app to be launched if necessary and its backup agent 13511 // instantiated. The backup agent will invoke backupAgentCreated() on the 13512 // activity manager to announce its creation. 13513 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13514 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13515 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13516 13517 synchronized(this) { 13518 // !!! TODO: currently no check here that we're already bound 13519 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13520 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13521 synchronized (stats) { 13522 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13523 } 13524 13525 // Backup agent is now in use, its package can't be stopped. 13526 try { 13527 AppGlobals.getPackageManager().setPackageStoppedState( 13528 app.packageName, false, UserHandle.getUserId(app.uid)); 13529 } catch (RemoteException e) { 13530 } catch (IllegalArgumentException e) { 13531 Slog.w(TAG, "Failed trying to unstop package " 13532 + app.packageName + ": " + e); 13533 } 13534 13535 BackupRecord r = new BackupRecord(ss, app, backupMode); 13536 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13537 ? new ComponentName(app.packageName, app.backupAgentName) 13538 : new ComponentName("android", "FullBackupAgent"); 13539 // startProcessLocked() returns existing proc's record if it's already running 13540 ProcessRecord proc = startProcessLocked(app.processName, app, 13541 false, 0, "backup", hostingName, false, false, false); 13542 if (proc == null) { 13543 Slog.e(TAG, "Unable to start backup agent process " + r); 13544 return false; 13545 } 13546 13547 r.app = proc; 13548 mBackupTarget = r; 13549 mBackupAppName = app.packageName; 13550 13551 // Try not to kill the process during backup 13552 updateOomAdjLocked(proc); 13553 13554 // If the process is already attached, schedule the creation of the backup agent now. 13555 // If it is not yet live, this will be done when it attaches to the framework. 13556 if (proc.thread != null) { 13557 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13558 try { 13559 proc.thread.scheduleCreateBackupAgent(app, 13560 compatibilityInfoForPackageLocked(app), backupMode); 13561 } catch (RemoteException e) { 13562 // Will time out on the backup manager side 13563 } 13564 } else { 13565 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13566 } 13567 // Invariants: at this point, the target app process exists and the application 13568 // is either already running or in the process of coming up. mBackupTarget and 13569 // mBackupAppName describe the app, so that when it binds back to the AM we 13570 // know that it's scheduled for a backup-agent operation. 13571 } 13572 13573 return true; 13574 } 13575 13576 @Override 13577 public void clearPendingBackup() { 13578 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13579 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13580 13581 synchronized (this) { 13582 mBackupTarget = null; 13583 mBackupAppName = null; 13584 } 13585 } 13586 13587 // A backup agent has just come up 13588 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13589 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13590 + " = " + agent); 13591 13592 synchronized(this) { 13593 if (!agentPackageName.equals(mBackupAppName)) { 13594 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13595 return; 13596 } 13597 } 13598 13599 long oldIdent = Binder.clearCallingIdentity(); 13600 try { 13601 IBackupManager bm = IBackupManager.Stub.asInterface( 13602 ServiceManager.getService(Context.BACKUP_SERVICE)); 13603 bm.agentConnected(agentPackageName, agent); 13604 } catch (RemoteException e) { 13605 // can't happen; the backup manager service is local 13606 } catch (Exception e) { 13607 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13608 e.printStackTrace(); 13609 } finally { 13610 Binder.restoreCallingIdentity(oldIdent); 13611 } 13612 } 13613 13614 // done with this agent 13615 public void unbindBackupAgent(ApplicationInfo appInfo) { 13616 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13617 if (appInfo == null) { 13618 Slog.w(TAG, "unbind backup agent for null app"); 13619 return; 13620 } 13621 13622 synchronized(this) { 13623 try { 13624 if (mBackupAppName == null) { 13625 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13626 return; 13627 } 13628 13629 if (!mBackupAppName.equals(appInfo.packageName)) { 13630 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13631 return; 13632 } 13633 13634 // Not backing this app up any more; reset its OOM adjustment 13635 final ProcessRecord proc = mBackupTarget.app; 13636 updateOomAdjLocked(proc); 13637 13638 // If the app crashed during backup, 'thread' will be null here 13639 if (proc.thread != null) { 13640 try { 13641 proc.thread.scheduleDestroyBackupAgent(appInfo, 13642 compatibilityInfoForPackageLocked(appInfo)); 13643 } catch (Exception e) { 13644 Slog.e(TAG, "Exception when unbinding backup agent:"); 13645 e.printStackTrace(); 13646 } 13647 } 13648 } finally { 13649 mBackupTarget = null; 13650 mBackupAppName = null; 13651 } 13652 } 13653 } 13654 // ========================================================= 13655 // BROADCASTS 13656 // ========================================================= 13657 13658 private final List getStickiesLocked(String action, IntentFilter filter, 13659 List cur, int userId) { 13660 final ContentResolver resolver = mContext.getContentResolver(); 13661 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13662 if (stickies == null) { 13663 return cur; 13664 } 13665 final ArrayList<Intent> list = stickies.get(action); 13666 if (list == null) { 13667 return cur; 13668 } 13669 int N = list.size(); 13670 for (int i=0; i<N; i++) { 13671 Intent intent = list.get(i); 13672 if (filter.match(resolver, intent, true, TAG) >= 0) { 13673 if (cur == null) { 13674 cur = new ArrayList<Intent>(); 13675 } 13676 cur.add(intent); 13677 } 13678 } 13679 return cur; 13680 } 13681 13682 boolean isPendingBroadcastProcessLocked(int pid) { 13683 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13684 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13685 } 13686 13687 void skipPendingBroadcastLocked(int pid) { 13688 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13689 for (BroadcastQueue queue : mBroadcastQueues) { 13690 queue.skipPendingBroadcastLocked(pid); 13691 } 13692 } 13693 13694 // The app just attached; send any pending broadcasts that it should receive 13695 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13696 boolean didSomething = false; 13697 for (BroadcastQueue queue : mBroadcastQueues) { 13698 didSomething |= queue.sendPendingBroadcastsLocked(app); 13699 } 13700 return didSomething; 13701 } 13702 13703 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13704 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13705 enforceNotIsolatedCaller("registerReceiver"); 13706 int callingUid; 13707 int callingPid; 13708 synchronized(this) { 13709 ProcessRecord callerApp = null; 13710 if (caller != null) { 13711 callerApp = getRecordForAppLocked(caller); 13712 if (callerApp == null) { 13713 throw new SecurityException( 13714 "Unable to find app for caller " + caller 13715 + " (pid=" + Binder.getCallingPid() 13716 + ") when registering receiver " + receiver); 13717 } 13718 if (callerApp.info.uid != Process.SYSTEM_UID && 13719 !callerApp.pkgList.containsKey(callerPackage) && 13720 !"android".equals(callerPackage)) { 13721 throw new SecurityException("Given caller package " + callerPackage 13722 + " is not running in process " + callerApp); 13723 } 13724 callingUid = callerApp.info.uid; 13725 callingPid = callerApp.pid; 13726 } else { 13727 callerPackage = null; 13728 callingUid = Binder.getCallingUid(); 13729 callingPid = Binder.getCallingPid(); 13730 } 13731 13732 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13733 true, true, "registerReceiver", callerPackage); 13734 13735 List allSticky = null; 13736 13737 // Look for any matching sticky broadcasts... 13738 Iterator actions = filter.actionsIterator(); 13739 if (actions != null) { 13740 while (actions.hasNext()) { 13741 String action = (String)actions.next(); 13742 allSticky = getStickiesLocked(action, filter, allSticky, 13743 UserHandle.USER_ALL); 13744 allSticky = getStickiesLocked(action, filter, allSticky, 13745 UserHandle.getUserId(callingUid)); 13746 } 13747 } else { 13748 allSticky = getStickiesLocked(null, filter, allSticky, 13749 UserHandle.USER_ALL); 13750 allSticky = getStickiesLocked(null, filter, allSticky, 13751 UserHandle.getUserId(callingUid)); 13752 } 13753 13754 // The first sticky in the list is returned directly back to 13755 // the client. 13756 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13757 13758 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13759 + ": " + sticky); 13760 13761 if (receiver == null) { 13762 return sticky; 13763 } 13764 13765 ReceiverList rl 13766 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13767 if (rl == null) { 13768 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13769 userId, receiver); 13770 if (rl.app != null) { 13771 rl.app.receivers.add(rl); 13772 } else { 13773 try { 13774 receiver.asBinder().linkToDeath(rl, 0); 13775 } catch (RemoteException e) { 13776 return sticky; 13777 } 13778 rl.linkedToDeath = true; 13779 } 13780 mRegisteredReceivers.put(receiver.asBinder(), rl); 13781 } else if (rl.uid != callingUid) { 13782 throw new IllegalArgumentException( 13783 "Receiver requested to register for uid " + callingUid 13784 + " was previously registered for uid " + rl.uid); 13785 } else if (rl.pid != callingPid) { 13786 throw new IllegalArgumentException( 13787 "Receiver requested to register for pid " + callingPid 13788 + " was previously registered for pid " + rl.pid); 13789 } else if (rl.userId != userId) { 13790 throw new IllegalArgumentException( 13791 "Receiver requested to register for user " + userId 13792 + " was previously registered for user " + rl.userId); 13793 } 13794 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13795 permission, callingUid, userId); 13796 rl.add(bf); 13797 if (!bf.debugCheck()) { 13798 Slog.w(TAG, "==> For Dynamic broadast"); 13799 } 13800 mReceiverResolver.addFilter(bf); 13801 13802 // Enqueue broadcasts for all existing stickies that match 13803 // this filter. 13804 if (allSticky != null) { 13805 ArrayList receivers = new ArrayList(); 13806 receivers.add(bf); 13807 13808 int N = allSticky.size(); 13809 for (int i=0; i<N; i++) { 13810 Intent intent = (Intent)allSticky.get(i); 13811 BroadcastQueue queue = broadcastQueueForIntent(intent); 13812 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13813 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13814 null, null, false, true, true, -1); 13815 queue.enqueueParallelBroadcastLocked(r); 13816 queue.scheduleBroadcastsLocked(); 13817 } 13818 } 13819 13820 return sticky; 13821 } 13822 } 13823 13824 public void unregisterReceiver(IIntentReceiver receiver) { 13825 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13826 13827 final long origId = Binder.clearCallingIdentity(); 13828 try { 13829 boolean doTrim = false; 13830 13831 synchronized(this) { 13832 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13833 if (rl != null) { 13834 if (rl.curBroadcast != null) { 13835 BroadcastRecord r = rl.curBroadcast; 13836 final boolean doNext = finishReceiverLocked( 13837 receiver.asBinder(), r.resultCode, r.resultData, 13838 r.resultExtras, r.resultAbort); 13839 if (doNext) { 13840 doTrim = true; 13841 r.queue.processNextBroadcast(false); 13842 } 13843 } 13844 13845 if (rl.app != null) { 13846 rl.app.receivers.remove(rl); 13847 } 13848 removeReceiverLocked(rl); 13849 if (rl.linkedToDeath) { 13850 rl.linkedToDeath = false; 13851 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13852 } 13853 } 13854 } 13855 13856 // If we actually concluded any broadcasts, we might now be able 13857 // to trim the recipients' apps from our working set 13858 if (doTrim) { 13859 trimApplications(); 13860 return; 13861 } 13862 13863 } finally { 13864 Binder.restoreCallingIdentity(origId); 13865 } 13866 } 13867 13868 void removeReceiverLocked(ReceiverList rl) { 13869 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13870 int N = rl.size(); 13871 for (int i=0; i<N; i++) { 13872 mReceiverResolver.removeFilter(rl.get(i)); 13873 } 13874 } 13875 13876 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13877 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13878 ProcessRecord r = mLruProcesses.get(i); 13879 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13880 try { 13881 r.thread.dispatchPackageBroadcast(cmd, packages); 13882 } catch (RemoteException ex) { 13883 } 13884 } 13885 } 13886 } 13887 13888 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13889 int[] users) { 13890 List<ResolveInfo> receivers = null; 13891 try { 13892 HashSet<ComponentName> singleUserReceivers = null; 13893 boolean scannedFirstReceivers = false; 13894 for (int user : users) { 13895 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13896 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13897 if (user != 0 && newReceivers != null) { 13898 // If this is not the primary user, we need to check for 13899 // any receivers that should be filtered out. 13900 for (int i=0; i<newReceivers.size(); i++) { 13901 ResolveInfo ri = newReceivers.get(i); 13902 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13903 newReceivers.remove(i); 13904 i--; 13905 } 13906 } 13907 } 13908 if (newReceivers != null && newReceivers.size() == 0) { 13909 newReceivers = null; 13910 } 13911 if (receivers == null) { 13912 receivers = newReceivers; 13913 } else if (newReceivers != null) { 13914 // We need to concatenate the additional receivers 13915 // found with what we have do far. This would be easy, 13916 // but we also need to de-dup any receivers that are 13917 // singleUser. 13918 if (!scannedFirstReceivers) { 13919 // Collect any single user receivers we had already retrieved. 13920 scannedFirstReceivers = true; 13921 for (int i=0; i<receivers.size(); i++) { 13922 ResolveInfo ri = receivers.get(i); 13923 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13924 ComponentName cn = new ComponentName( 13925 ri.activityInfo.packageName, ri.activityInfo.name); 13926 if (singleUserReceivers == null) { 13927 singleUserReceivers = new HashSet<ComponentName>(); 13928 } 13929 singleUserReceivers.add(cn); 13930 } 13931 } 13932 } 13933 // Add the new results to the existing results, tracking 13934 // and de-dupping single user receivers. 13935 for (int i=0; i<newReceivers.size(); i++) { 13936 ResolveInfo ri = newReceivers.get(i); 13937 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13938 ComponentName cn = new ComponentName( 13939 ri.activityInfo.packageName, ri.activityInfo.name); 13940 if (singleUserReceivers == null) { 13941 singleUserReceivers = new HashSet<ComponentName>(); 13942 } 13943 if (!singleUserReceivers.contains(cn)) { 13944 singleUserReceivers.add(cn); 13945 receivers.add(ri); 13946 } 13947 } else { 13948 receivers.add(ri); 13949 } 13950 } 13951 } 13952 } 13953 } catch (RemoteException ex) { 13954 // pm is in same process, this will never happen. 13955 } 13956 return receivers; 13957 } 13958 13959 private final int broadcastIntentLocked(ProcessRecord callerApp, 13960 String callerPackage, Intent intent, String resolvedType, 13961 IIntentReceiver resultTo, int resultCode, String resultData, 13962 Bundle map, String requiredPermission, int appOp, 13963 boolean ordered, boolean sticky, int callingPid, int callingUid, 13964 int userId) { 13965 intent = new Intent(intent); 13966 13967 // By default broadcasts do not go to stopped apps. 13968 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13969 13970 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13971 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13972 + " ordered=" + ordered + " userid=" + userId); 13973 if ((resultTo != null) && !ordered) { 13974 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13975 } 13976 13977 userId = handleIncomingUser(callingPid, callingUid, userId, 13978 true, false, "broadcast", callerPackage); 13979 13980 // Make sure that the user who is receiving this broadcast is started. 13981 // If not, we will just skip it. 13982 13983 13984 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13985 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13986 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13987 Slog.w(TAG, "Skipping broadcast of " + intent 13988 + ": user " + userId + " is stopped"); 13989 return ActivityManager.BROADCAST_SUCCESS; 13990 } 13991 } 13992 13993 /* 13994 * Prevent non-system code (defined here to be non-persistent 13995 * processes) from sending protected broadcasts. 13996 */ 13997 int callingAppId = UserHandle.getAppId(callingUid); 13998 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13999 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14000 || callingAppId == Process.NFC_UID || callingUid == 0) { 14001 // Always okay. 14002 } else if (callerApp == null || !callerApp.persistent) { 14003 try { 14004 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14005 intent.getAction())) { 14006 String msg = "Permission Denial: not allowed to send broadcast " 14007 + intent.getAction() + " from pid=" 14008 + callingPid + ", uid=" + callingUid; 14009 Slog.w(TAG, msg); 14010 throw new SecurityException(msg); 14011 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14012 // Special case for compatibility: we don't want apps to send this, 14013 // but historically it has not been protected and apps may be using it 14014 // to poke their own app widget. So, instead of making it protected, 14015 // just limit it to the caller. 14016 if (callerApp == null) { 14017 String msg = "Permission Denial: not allowed to send broadcast " 14018 + intent.getAction() + " from unknown caller."; 14019 Slog.w(TAG, msg); 14020 throw new SecurityException(msg); 14021 } else if (intent.getComponent() != null) { 14022 // They are good enough to send to an explicit component... verify 14023 // it is being sent to the calling app. 14024 if (!intent.getComponent().getPackageName().equals( 14025 callerApp.info.packageName)) { 14026 String msg = "Permission Denial: not allowed to send broadcast " 14027 + intent.getAction() + " to " 14028 + intent.getComponent().getPackageName() + " from " 14029 + callerApp.info.packageName; 14030 Slog.w(TAG, msg); 14031 throw new SecurityException(msg); 14032 } 14033 } else { 14034 // Limit broadcast to their own package. 14035 intent.setPackage(callerApp.info.packageName); 14036 } 14037 } 14038 } catch (RemoteException e) { 14039 Slog.w(TAG, "Remote exception", e); 14040 return ActivityManager.BROADCAST_SUCCESS; 14041 } 14042 } 14043 14044 // Handle special intents: if this broadcast is from the package 14045 // manager about a package being removed, we need to remove all of 14046 // its activities from the history stack. 14047 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14048 intent.getAction()); 14049 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14050 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14051 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14052 || uidRemoved) { 14053 if (checkComponentPermission( 14054 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14055 callingPid, callingUid, -1, true) 14056 == PackageManager.PERMISSION_GRANTED) { 14057 if (uidRemoved) { 14058 final Bundle intentExtras = intent.getExtras(); 14059 final int uid = intentExtras != null 14060 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14061 if (uid >= 0) { 14062 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14063 synchronized (bs) { 14064 bs.removeUidStatsLocked(uid); 14065 } 14066 mAppOpsService.uidRemoved(uid); 14067 } 14068 } else { 14069 // If resources are unavailable just force stop all 14070 // those packages and flush the attribute cache as well. 14071 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14072 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14073 if (list != null && (list.length > 0)) { 14074 for (String pkg : list) { 14075 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14076 "storage unmount"); 14077 } 14078 sendPackageBroadcastLocked( 14079 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14080 } 14081 } else { 14082 Uri data = intent.getData(); 14083 String ssp; 14084 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14085 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14086 intent.getAction()); 14087 boolean fullUninstall = removed && 14088 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14089 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14090 forceStopPackageLocked(ssp, UserHandle.getAppId( 14091 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14092 false, fullUninstall, userId, 14093 removed ? "pkg removed" : "pkg changed"); 14094 } 14095 if (removed) { 14096 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14097 new String[] {ssp}, userId); 14098 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14099 mAppOpsService.packageRemoved( 14100 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14101 14102 // Remove all permissions granted from/to this package 14103 removeUriPermissionsForPackageLocked(ssp, userId, true); 14104 } 14105 } 14106 } 14107 } 14108 } 14109 } else { 14110 String msg = "Permission Denial: " + intent.getAction() 14111 + " broadcast from " + callerPackage + " (pid=" + callingPid 14112 + ", uid=" + callingUid + ")" 14113 + " requires " 14114 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14115 Slog.w(TAG, msg); 14116 throw new SecurityException(msg); 14117 } 14118 14119 // Special case for adding a package: by default turn on compatibility 14120 // mode. 14121 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14122 Uri data = intent.getData(); 14123 String ssp; 14124 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14125 mCompatModePackages.handlePackageAddedLocked(ssp, 14126 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14127 } 14128 } 14129 14130 /* 14131 * If this is the time zone changed action, queue up a message that will reset the timezone 14132 * of all currently running processes. This message will get queued up before the broadcast 14133 * happens. 14134 */ 14135 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14136 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14137 } 14138 14139 /* 14140 * If the user set the time, let all running processes know. 14141 */ 14142 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14143 final int is24Hour = intent.getBooleanExtra( 14144 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14145 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14146 } 14147 14148 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14149 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14150 } 14151 14152 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14153 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14154 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14155 } 14156 14157 // Add to the sticky list if requested. 14158 if (sticky) { 14159 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14160 callingPid, callingUid) 14161 != PackageManager.PERMISSION_GRANTED) { 14162 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14163 + callingPid + ", uid=" + callingUid 14164 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14165 Slog.w(TAG, msg); 14166 throw new SecurityException(msg); 14167 } 14168 if (requiredPermission != null) { 14169 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14170 + " and enforce permission " + requiredPermission); 14171 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14172 } 14173 if (intent.getComponent() != null) { 14174 throw new SecurityException( 14175 "Sticky broadcasts can't target a specific component"); 14176 } 14177 // We use userId directly here, since the "all" target is maintained 14178 // as a separate set of sticky broadcasts. 14179 if (userId != UserHandle.USER_ALL) { 14180 // But first, if this is not a broadcast to all users, then 14181 // make sure it doesn't conflict with an existing broadcast to 14182 // all users. 14183 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14184 UserHandle.USER_ALL); 14185 if (stickies != null) { 14186 ArrayList<Intent> list = stickies.get(intent.getAction()); 14187 if (list != null) { 14188 int N = list.size(); 14189 int i; 14190 for (i=0; i<N; i++) { 14191 if (intent.filterEquals(list.get(i))) { 14192 throw new IllegalArgumentException( 14193 "Sticky broadcast " + intent + " for user " 14194 + userId + " conflicts with existing global broadcast"); 14195 } 14196 } 14197 } 14198 } 14199 } 14200 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14201 if (stickies == null) { 14202 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14203 mStickyBroadcasts.put(userId, stickies); 14204 } 14205 ArrayList<Intent> list = stickies.get(intent.getAction()); 14206 if (list == null) { 14207 list = new ArrayList<Intent>(); 14208 stickies.put(intent.getAction(), list); 14209 } 14210 int N = list.size(); 14211 int i; 14212 for (i=0; i<N; i++) { 14213 if (intent.filterEquals(list.get(i))) { 14214 // This sticky already exists, replace it. 14215 list.set(i, new Intent(intent)); 14216 break; 14217 } 14218 } 14219 if (i >= N) { 14220 list.add(new Intent(intent)); 14221 } 14222 } 14223 14224 int[] users; 14225 if (userId == UserHandle.USER_ALL) { 14226 // Caller wants broadcast to go to all started users. 14227 users = mStartedUserArray; 14228 } else { 14229 // Caller wants broadcast to go to one specific user. 14230 users = new int[] {userId}; 14231 } 14232 14233 // Figure out who all will receive this broadcast. 14234 List receivers = null; 14235 List<BroadcastFilter> registeredReceivers = null; 14236 // Need to resolve the intent to interested receivers... 14237 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14238 == 0) { 14239 receivers = collectReceiverComponents(intent, resolvedType, users); 14240 } 14241 if (intent.getComponent() == null) { 14242 registeredReceivers = mReceiverResolver.queryIntent(intent, 14243 resolvedType, false, userId); 14244 } 14245 14246 final boolean replacePending = 14247 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14248 14249 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14250 + " replacePending=" + replacePending); 14251 14252 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14253 if (!ordered && NR > 0) { 14254 // If we are not serializing this broadcast, then send the 14255 // registered receivers separately so they don't wait for the 14256 // components to be launched. 14257 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14258 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14259 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14260 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14261 ordered, sticky, false, userId); 14262 if (DEBUG_BROADCAST) Slog.v( 14263 TAG, "Enqueueing parallel broadcast " + r); 14264 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14265 if (!replaced) { 14266 queue.enqueueParallelBroadcastLocked(r); 14267 queue.scheduleBroadcastsLocked(); 14268 } 14269 registeredReceivers = null; 14270 NR = 0; 14271 } 14272 14273 // Merge into one list. 14274 int ir = 0; 14275 if (receivers != null) { 14276 // A special case for PACKAGE_ADDED: do not allow the package 14277 // being added to see this broadcast. This prevents them from 14278 // using this as a back door to get run as soon as they are 14279 // installed. Maybe in the future we want to have a special install 14280 // broadcast or such for apps, but we'd like to deliberately make 14281 // this decision. 14282 String skipPackages[] = null; 14283 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14284 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14285 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14286 Uri data = intent.getData(); 14287 if (data != null) { 14288 String pkgName = data.getSchemeSpecificPart(); 14289 if (pkgName != null) { 14290 skipPackages = new String[] { pkgName }; 14291 } 14292 } 14293 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14294 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14295 } 14296 if (skipPackages != null && (skipPackages.length > 0)) { 14297 for (String skipPackage : skipPackages) { 14298 if (skipPackage != null) { 14299 int NT = receivers.size(); 14300 for (int it=0; it<NT; it++) { 14301 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14302 if (curt.activityInfo.packageName.equals(skipPackage)) { 14303 receivers.remove(it); 14304 it--; 14305 NT--; 14306 } 14307 } 14308 } 14309 } 14310 } 14311 14312 int NT = receivers != null ? receivers.size() : 0; 14313 int it = 0; 14314 ResolveInfo curt = null; 14315 BroadcastFilter curr = null; 14316 while (it < NT && ir < NR) { 14317 if (curt == null) { 14318 curt = (ResolveInfo)receivers.get(it); 14319 } 14320 if (curr == null) { 14321 curr = registeredReceivers.get(ir); 14322 } 14323 if (curr.getPriority() >= curt.priority) { 14324 // Insert this broadcast record into the final list. 14325 receivers.add(it, curr); 14326 ir++; 14327 curr = null; 14328 it++; 14329 NT++; 14330 } else { 14331 // Skip to the next ResolveInfo in the final list. 14332 it++; 14333 curt = null; 14334 } 14335 } 14336 } 14337 while (ir < NR) { 14338 if (receivers == null) { 14339 receivers = new ArrayList(); 14340 } 14341 receivers.add(registeredReceivers.get(ir)); 14342 ir++; 14343 } 14344 14345 if ((receivers != null && receivers.size() > 0) 14346 || resultTo != null) { 14347 BroadcastQueue queue = broadcastQueueForIntent(intent); 14348 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14349 callerPackage, callingPid, callingUid, resolvedType, 14350 requiredPermission, appOp, receivers, resultTo, resultCode, 14351 resultData, map, ordered, sticky, false, userId); 14352 if (DEBUG_BROADCAST) Slog.v( 14353 TAG, "Enqueueing ordered broadcast " + r 14354 + ": prev had " + queue.mOrderedBroadcasts.size()); 14355 if (DEBUG_BROADCAST) { 14356 int seq = r.intent.getIntExtra("seq", -1); 14357 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14358 } 14359 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14360 if (!replaced) { 14361 queue.enqueueOrderedBroadcastLocked(r); 14362 queue.scheduleBroadcastsLocked(); 14363 } 14364 } 14365 14366 return ActivityManager.BROADCAST_SUCCESS; 14367 } 14368 14369 final Intent verifyBroadcastLocked(Intent intent) { 14370 // Refuse possible leaked file descriptors 14371 if (intent != null && intent.hasFileDescriptors() == true) { 14372 throw new IllegalArgumentException("File descriptors passed in Intent"); 14373 } 14374 14375 int flags = intent.getFlags(); 14376 14377 if (!mProcessesReady) { 14378 // if the caller really truly claims to know what they're doing, go 14379 // ahead and allow the broadcast without launching any receivers 14380 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14381 intent = new Intent(intent); 14382 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14383 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14384 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14385 + " before boot completion"); 14386 throw new IllegalStateException("Cannot broadcast before boot completed"); 14387 } 14388 } 14389 14390 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14391 throw new IllegalArgumentException( 14392 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14393 } 14394 14395 return intent; 14396 } 14397 14398 public final int broadcastIntent(IApplicationThread caller, 14399 Intent intent, String resolvedType, IIntentReceiver resultTo, 14400 int resultCode, String resultData, Bundle map, 14401 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14402 enforceNotIsolatedCaller("broadcastIntent"); 14403 synchronized(this) { 14404 intent = verifyBroadcastLocked(intent); 14405 14406 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14407 final int callingPid = Binder.getCallingPid(); 14408 final int callingUid = Binder.getCallingUid(); 14409 final long origId = Binder.clearCallingIdentity(); 14410 int res = broadcastIntentLocked(callerApp, 14411 callerApp != null ? callerApp.info.packageName : null, 14412 intent, resolvedType, resultTo, 14413 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14414 callingPid, callingUid, userId); 14415 Binder.restoreCallingIdentity(origId); 14416 return res; 14417 } 14418 } 14419 14420 int broadcastIntentInPackage(String packageName, int uid, 14421 Intent intent, String resolvedType, IIntentReceiver resultTo, 14422 int resultCode, String resultData, Bundle map, 14423 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14424 synchronized(this) { 14425 intent = verifyBroadcastLocked(intent); 14426 14427 final long origId = Binder.clearCallingIdentity(); 14428 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14429 resultTo, resultCode, resultData, map, requiredPermission, 14430 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14431 Binder.restoreCallingIdentity(origId); 14432 return res; 14433 } 14434 } 14435 14436 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14437 // Refuse possible leaked file descriptors 14438 if (intent != null && intent.hasFileDescriptors() == true) { 14439 throw new IllegalArgumentException("File descriptors passed in Intent"); 14440 } 14441 14442 userId = handleIncomingUser(Binder.getCallingPid(), 14443 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14444 14445 synchronized(this) { 14446 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14447 != PackageManager.PERMISSION_GRANTED) { 14448 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14449 + Binder.getCallingPid() 14450 + ", uid=" + Binder.getCallingUid() 14451 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14452 Slog.w(TAG, msg); 14453 throw new SecurityException(msg); 14454 } 14455 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14456 if (stickies != null) { 14457 ArrayList<Intent> list = stickies.get(intent.getAction()); 14458 if (list != null) { 14459 int N = list.size(); 14460 int i; 14461 for (i=0; i<N; i++) { 14462 if (intent.filterEquals(list.get(i))) { 14463 list.remove(i); 14464 break; 14465 } 14466 } 14467 if (list.size() <= 0) { 14468 stickies.remove(intent.getAction()); 14469 } 14470 } 14471 if (stickies.size() <= 0) { 14472 mStickyBroadcasts.remove(userId); 14473 } 14474 } 14475 } 14476 } 14477 14478 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14479 String resultData, Bundle resultExtras, boolean resultAbort) { 14480 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14481 if (r == null) { 14482 Slog.w(TAG, "finishReceiver called but not found on queue"); 14483 return false; 14484 } 14485 14486 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14487 } 14488 14489 void backgroundServicesFinishedLocked(int userId) { 14490 for (BroadcastQueue queue : mBroadcastQueues) { 14491 queue.backgroundServicesFinishedLocked(userId); 14492 } 14493 } 14494 14495 public void finishReceiver(IBinder who, int resultCode, String resultData, 14496 Bundle resultExtras, boolean resultAbort) { 14497 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14498 14499 // Refuse possible leaked file descriptors 14500 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14501 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14502 } 14503 14504 final long origId = Binder.clearCallingIdentity(); 14505 try { 14506 boolean doNext = false; 14507 BroadcastRecord r; 14508 14509 synchronized(this) { 14510 r = broadcastRecordForReceiverLocked(who); 14511 if (r != null) { 14512 doNext = r.queue.finishReceiverLocked(r, resultCode, 14513 resultData, resultExtras, resultAbort, true); 14514 } 14515 } 14516 14517 if (doNext) { 14518 r.queue.processNextBroadcast(false); 14519 } 14520 trimApplications(); 14521 } finally { 14522 Binder.restoreCallingIdentity(origId); 14523 } 14524 } 14525 14526 // ========================================================= 14527 // INSTRUMENTATION 14528 // ========================================================= 14529 14530 public boolean startInstrumentation(ComponentName className, 14531 String profileFile, int flags, Bundle arguments, 14532 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14533 int userId, String abiOverride) { 14534 enforceNotIsolatedCaller("startInstrumentation"); 14535 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14536 userId, false, true, "startInstrumentation", null); 14537 // Refuse possible leaked file descriptors 14538 if (arguments != null && arguments.hasFileDescriptors()) { 14539 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14540 } 14541 14542 synchronized(this) { 14543 InstrumentationInfo ii = null; 14544 ApplicationInfo ai = null; 14545 try { 14546 ii = mContext.getPackageManager().getInstrumentationInfo( 14547 className, STOCK_PM_FLAGS); 14548 ai = AppGlobals.getPackageManager().getApplicationInfo( 14549 ii.targetPackage, STOCK_PM_FLAGS, userId); 14550 } catch (PackageManager.NameNotFoundException e) { 14551 } catch (RemoteException e) { 14552 } 14553 if (ii == null) { 14554 reportStartInstrumentationFailure(watcher, className, 14555 "Unable to find instrumentation info for: " + className); 14556 return false; 14557 } 14558 if (ai == null) { 14559 reportStartInstrumentationFailure(watcher, className, 14560 "Unable to find instrumentation target package: " + ii.targetPackage); 14561 return false; 14562 } 14563 14564 int match = mContext.getPackageManager().checkSignatures( 14565 ii.targetPackage, ii.packageName); 14566 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14567 String msg = "Permission Denial: starting instrumentation " 14568 + className + " from pid=" 14569 + Binder.getCallingPid() 14570 + ", uid=" + Binder.getCallingPid() 14571 + " not allowed because package " + ii.packageName 14572 + " does not have a signature matching the target " 14573 + ii.targetPackage; 14574 reportStartInstrumentationFailure(watcher, className, msg); 14575 throw new SecurityException(msg); 14576 } 14577 14578 final long origId = Binder.clearCallingIdentity(); 14579 // Instrumentation can kill and relaunch even persistent processes 14580 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14581 "start instr"); 14582 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14583 app.instrumentationClass = className; 14584 app.instrumentationInfo = ai; 14585 app.instrumentationProfileFile = profileFile; 14586 app.instrumentationArguments = arguments; 14587 app.instrumentationWatcher = watcher; 14588 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14589 app.instrumentationResultClass = className; 14590 Binder.restoreCallingIdentity(origId); 14591 } 14592 14593 return true; 14594 } 14595 14596 /** 14597 * Report errors that occur while attempting to start Instrumentation. Always writes the 14598 * error to the logs, but if somebody is watching, send the report there too. This enables 14599 * the "am" command to report errors with more information. 14600 * 14601 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14602 * @param cn The component name of the instrumentation. 14603 * @param report The error report. 14604 */ 14605 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14606 ComponentName cn, String report) { 14607 Slog.w(TAG, report); 14608 try { 14609 if (watcher != null) { 14610 Bundle results = new Bundle(); 14611 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14612 results.putString("Error", report); 14613 watcher.instrumentationStatus(cn, -1, results); 14614 } 14615 } catch (RemoteException e) { 14616 Slog.w(TAG, e); 14617 } 14618 } 14619 14620 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14621 if (app.instrumentationWatcher != null) { 14622 try { 14623 // NOTE: IInstrumentationWatcher *must* be oneway here 14624 app.instrumentationWatcher.instrumentationFinished( 14625 app.instrumentationClass, 14626 resultCode, 14627 results); 14628 } catch (RemoteException e) { 14629 } 14630 } 14631 if (app.instrumentationUiAutomationConnection != null) { 14632 try { 14633 app.instrumentationUiAutomationConnection.shutdown(); 14634 } catch (RemoteException re) { 14635 /* ignore */ 14636 } 14637 // Only a UiAutomation can set this flag and now that 14638 // it is finished we make sure it is reset to its default. 14639 mUserIsMonkey = false; 14640 } 14641 app.instrumentationWatcher = null; 14642 app.instrumentationUiAutomationConnection = null; 14643 app.instrumentationClass = null; 14644 app.instrumentationInfo = null; 14645 app.instrumentationProfileFile = null; 14646 app.instrumentationArguments = null; 14647 14648 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14649 "finished inst"); 14650 } 14651 14652 public void finishInstrumentation(IApplicationThread target, 14653 int resultCode, Bundle results) { 14654 int userId = UserHandle.getCallingUserId(); 14655 // Refuse possible leaked file descriptors 14656 if (results != null && results.hasFileDescriptors()) { 14657 throw new IllegalArgumentException("File descriptors passed in Intent"); 14658 } 14659 14660 synchronized(this) { 14661 ProcessRecord app = getRecordForAppLocked(target); 14662 if (app == null) { 14663 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14664 return; 14665 } 14666 final long origId = Binder.clearCallingIdentity(); 14667 finishInstrumentationLocked(app, resultCode, results); 14668 Binder.restoreCallingIdentity(origId); 14669 } 14670 } 14671 14672 // ========================================================= 14673 // CONFIGURATION 14674 // ========================================================= 14675 14676 public ConfigurationInfo getDeviceConfigurationInfo() { 14677 ConfigurationInfo config = new ConfigurationInfo(); 14678 synchronized (this) { 14679 config.reqTouchScreen = mConfiguration.touchscreen; 14680 config.reqKeyboardType = mConfiguration.keyboard; 14681 config.reqNavigation = mConfiguration.navigation; 14682 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14683 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14684 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14685 } 14686 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14687 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14688 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14689 } 14690 config.reqGlEsVersion = GL_ES_VERSION; 14691 } 14692 return config; 14693 } 14694 14695 ActivityStack getFocusedStack() { 14696 return mStackSupervisor.getFocusedStack(); 14697 } 14698 14699 public Configuration getConfiguration() { 14700 Configuration ci; 14701 synchronized(this) { 14702 ci = new Configuration(mConfiguration); 14703 } 14704 return ci; 14705 } 14706 14707 public void updatePersistentConfiguration(Configuration values) { 14708 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14709 "updateConfiguration()"); 14710 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14711 "updateConfiguration()"); 14712 if (values == null) { 14713 throw new NullPointerException("Configuration must not be null"); 14714 } 14715 14716 synchronized(this) { 14717 final long origId = Binder.clearCallingIdentity(); 14718 updateConfigurationLocked(values, null, true, false); 14719 Binder.restoreCallingIdentity(origId); 14720 } 14721 } 14722 14723 public void updateConfiguration(Configuration values) { 14724 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14725 "updateConfiguration()"); 14726 14727 synchronized(this) { 14728 if (values == null && mWindowManager != null) { 14729 // sentinel: fetch the current configuration from the window manager 14730 values = mWindowManager.computeNewConfiguration(); 14731 } 14732 14733 if (mWindowManager != null) { 14734 mProcessList.applyDisplaySize(mWindowManager); 14735 } 14736 14737 final long origId = Binder.clearCallingIdentity(); 14738 if (values != null) { 14739 Settings.System.clearConfiguration(values); 14740 } 14741 updateConfigurationLocked(values, null, false, false); 14742 Binder.restoreCallingIdentity(origId); 14743 } 14744 } 14745 14746 /** 14747 * Do either or both things: (1) change the current configuration, and (2) 14748 * make sure the given activity is running with the (now) current 14749 * configuration. Returns true if the activity has been left running, or 14750 * false if <var>starting</var> is being destroyed to match the new 14751 * configuration. 14752 * @param persistent TODO 14753 */ 14754 boolean updateConfigurationLocked(Configuration values, 14755 ActivityRecord starting, boolean persistent, boolean initLocale) { 14756 int changes = 0; 14757 14758 if (values != null) { 14759 Configuration newConfig = new Configuration(mConfiguration); 14760 changes = newConfig.updateFrom(values); 14761 if (changes != 0) { 14762 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14763 Slog.i(TAG, "Updating configuration to: " + values); 14764 } 14765 14766 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14767 14768 if (values.locale != null && !initLocale) { 14769 saveLocaleLocked(values.locale, 14770 !values.locale.equals(mConfiguration.locale), 14771 values.userSetLocale); 14772 } 14773 14774 mConfigurationSeq++; 14775 if (mConfigurationSeq <= 0) { 14776 mConfigurationSeq = 1; 14777 } 14778 newConfig.seq = mConfigurationSeq; 14779 mConfiguration = newConfig; 14780 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14781 mUsageStatsService.noteStartConfig(newConfig); 14782 14783 final Configuration configCopy = new Configuration(mConfiguration); 14784 14785 // TODO: If our config changes, should we auto dismiss any currently 14786 // showing dialogs? 14787 mShowDialogs = shouldShowDialogs(newConfig); 14788 14789 AttributeCache ac = AttributeCache.instance(); 14790 if (ac != null) { 14791 ac.updateConfiguration(configCopy); 14792 } 14793 14794 // Make sure all resources in our process are updated 14795 // right now, so that anyone who is going to retrieve 14796 // resource values after we return will be sure to get 14797 // the new ones. This is especially important during 14798 // boot, where the first config change needs to guarantee 14799 // all resources have that config before following boot 14800 // code is executed. 14801 mSystemThread.applyConfigurationToResources(configCopy); 14802 14803 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14804 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14805 msg.obj = new Configuration(configCopy); 14806 mHandler.sendMessage(msg); 14807 } 14808 14809 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14810 ProcessRecord app = mLruProcesses.get(i); 14811 try { 14812 if (app.thread != null) { 14813 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14814 + app.processName + " new config " + mConfiguration); 14815 app.thread.scheduleConfigurationChanged(configCopy); 14816 } 14817 } catch (Exception e) { 14818 } 14819 } 14820 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14821 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14822 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14823 | Intent.FLAG_RECEIVER_FOREGROUND); 14824 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14825 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14826 Process.SYSTEM_UID, UserHandle.USER_ALL); 14827 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14828 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14829 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14830 broadcastIntentLocked(null, null, intent, 14831 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14832 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14833 } 14834 } 14835 } 14836 14837 boolean kept = true; 14838 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14839 // mainStack is null during startup. 14840 if (mainStack != null) { 14841 if (changes != 0 && starting == null) { 14842 // If the configuration changed, and the caller is not already 14843 // in the process of starting an activity, then find the top 14844 // activity to check if its configuration needs to change. 14845 starting = mainStack.topRunningActivityLocked(null); 14846 } 14847 14848 if (starting != null) { 14849 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14850 // And we need to make sure at this point that all other activities 14851 // are made visible with the correct configuration. 14852 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14853 } 14854 } 14855 14856 if (values != null && mWindowManager != null) { 14857 mWindowManager.setNewConfiguration(mConfiguration); 14858 } 14859 14860 return kept; 14861 } 14862 14863 /** 14864 * Decide based on the configuration whether we should shouw the ANR, 14865 * crash, etc dialogs. The idea is that if there is no affordnace to 14866 * press the on-screen buttons, we shouldn't show the dialog. 14867 * 14868 * A thought: SystemUI might also want to get told about this, the Power 14869 * dialog / global actions also might want different behaviors. 14870 */ 14871 private static final boolean shouldShowDialogs(Configuration config) { 14872 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14873 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14874 } 14875 14876 /** 14877 * Save the locale. You must be inside a synchronized (this) block. 14878 */ 14879 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14880 if(isDiff) { 14881 SystemProperties.set("user.language", l.getLanguage()); 14882 SystemProperties.set("user.region", l.getCountry()); 14883 } 14884 14885 if(isPersist) { 14886 SystemProperties.set("persist.sys.language", l.getLanguage()); 14887 SystemProperties.set("persist.sys.country", l.getCountry()); 14888 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14889 } 14890 } 14891 14892 @Override 14893 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14894 ActivityRecord srec = ActivityRecord.forToken(token); 14895 return srec != null && srec.task.affinity != null && 14896 srec.task.affinity.equals(destAffinity); 14897 } 14898 14899 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14900 Intent resultData) { 14901 14902 synchronized (this) { 14903 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14904 if (stack != null) { 14905 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14906 } 14907 return false; 14908 } 14909 } 14910 14911 public int getLaunchedFromUid(IBinder activityToken) { 14912 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14913 if (srec == null) { 14914 return -1; 14915 } 14916 return srec.launchedFromUid; 14917 } 14918 14919 public String getLaunchedFromPackage(IBinder activityToken) { 14920 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14921 if (srec == null) { 14922 return null; 14923 } 14924 return srec.launchedFromPackage; 14925 } 14926 14927 // ========================================================= 14928 // LIFETIME MANAGEMENT 14929 // ========================================================= 14930 14931 // Returns which broadcast queue the app is the current [or imminent] receiver 14932 // on, or 'null' if the app is not an active broadcast recipient. 14933 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14934 BroadcastRecord r = app.curReceiver; 14935 if (r != null) { 14936 return r.queue; 14937 } 14938 14939 // It's not the current receiver, but it might be starting up to become one 14940 synchronized (this) { 14941 for (BroadcastQueue queue : mBroadcastQueues) { 14942 r = queue.mPendingBroadcast; 14943 if (r != null && r.curApp == app) { 14944 // found it; report which queue it's in 14945 return queue; 14946 } 14947 } 14948 } 14949 14950 return null; 14951 } 14952 14953 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14954 boolean doingAll, long now) { 14955 if (mAdjSeq == app.adjSeq) { 14956 // This adjustment has already been computed. 14957 return app.curRawAdj; 14958 } 14959 14960 if (app.thread == null) { 14961 app.adjSeq = mAdjSeq; 14962 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14963 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14964 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14965 } 14966 14967 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14968 app.adjSource = null; 14969 app.adjTarget = null; 14970 app.empty = false; 14971 app.cached = false; 14972 14973 final int activitiesSize = app.activities.size(); 14974 14975 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14976 // The max adjustment doesn't allow this app to be anything 14977 // below foreground, so it is not worth doing work for it. 14978 app.adjType = "fixed"; 14979 app.adjSeq = mAdjSeq; 14980 app.curRawAdj = app.maxAdj; 14981 app.foregroundActivities = false; 14982 app.keeping = true; 14983 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14984 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14985 // System processes can do UI, and when they do we want to have 14986 // them trim their memory after the user leaves the UI. To 14987 // facilitate this, here we need to determine whether or not it 14988 // is currently showing UI. 14989 app.systemNoUi = true; 14990 if (app == TOP_APP) { 14991 app.systemNoUi = false; 14992 } else if (activitiesSize > 0) { 14993 for (int j = 0; j < activitiesSize; j++) { 14994 final ActivityRecord r = app.activities.get(j); 14995 if (r.visible) { 14996 app.systemNoUi = false; 14997 } 14998 } 14999 } 15000 if (!app.systemNoUi) { 15001 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15002 } 15003 return (app.curAdj=app.maxAdj); 15004 } 15005 15006 app.keeping = false; 15007 app.systemNoUi = false; 15008 15009 // Determine the importance of the process, starting with most 15010 // important to least, and assign an appropriate OOM adjustment. 15011 int adj; 15012 int schedGroup; 15013 int procState; 15014 boolean foregroundActivities = false; 15015 BroadcastQueue queue; 15016 if (app == TOP_APP) { 15017 // The last app on the list is the foreground app. 15018 adj = ProcessList.FOREGROUND_APP_ADJ; 15019 schedGroup = Process.THREAD_GROUP_DEFAULT; 15020 app.adjType = "top-activity"; 15021 foregroundActivities = true; 15022 procState = ActivityManager.PROCESS_STATE_TOP; 15023 } else if (app.instrumentationClass != null) { 15024 // Don't want to kill running instrumentation. 15025 adj = ProcessList.FOREGROUND_APP_ADJ; 15026 schedGroup = Process.THREAD_GROUP_DEFAULT; 15027 app.adjType = "instrumentation"; 15028 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15029 } else if ((queue = isReceivingBroadcast(app)) != null) { 15030 // An app that is currently receiving a broadcast also 15031 // counts as being in the foreground for OOM killer purposes. 15032 // It's placed in a sched group based on the nature of the 15033 // broadcast as reflected by which queue it's active in. 15034 adj = ProcessList.FOREGROUND_APP_ADJ; 15035 schedGroup = (queue == mFgBroadcastQueue) 15036 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15037 app.adjType = "broadcast"; 15038 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15039 } else if (app.executingServices.size() > 0) { 15040 // An app that is currently executing a service callback also 15041 // counts as being in the foreground. 15042 adj = ProcessList.FOREGROUND_APP_ADJ; 15043 schedGroup = app.execServicesFg ? 15044 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15045 app.adjType = "exec-service"; 15046 procState = ActivityManager.PROCESS_STATE_SERVICE; 15047 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15048 } else { 15049 // As far as we know the process is empty. We may change our mind later. 15050 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15051 // At this point we don't actually know the adjustment. Use the cached adj 15052 // value that the caller wants us to. 15053 adj = cachedAdj; 15054 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15055 app.cached = true; 15056 app.empty = true; 15057 app.adjType = "cch-empty"; 15058 } 15059 15060 // Examine all activities if not already foreground. 15061 if (!foregroundActivities && activitiesSize > 0) { 15062 for (int j = 0; j < activitiesSize; j++) { 15063 final ActivityRecord r = app.activities.get(j); 15064 if (r.app != app) { 15065 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15066 + app + "?!?"); 15067 continue; 15068 } 15069 if (r.visible) { 15070 // App has a visible activity; only upgrade adjustment. 15071 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15072 adj = ProcessList.VISIBLE_APP_ADJ; 15073 app.adjType = "visible"; 15074 } 15075 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15076 procState = ActivityManager.PROCESS_STATE_TOP; 15077 } 15078 schedGroup = Process.THREAD_GROUP_DEFAULT; 15079 app.cached = false; 15080 app.empty = false; 15081 foregroundActivities = true; 15082 break; 15083 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15084 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15085 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15086 app.adjType = "pausing"; 15087 } 15088 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15089 procState = ActivityManager.PROCESS_STATE_TOP; 15090 } 15091 schedGroup = Process.THREAD_GROUP_DEFAULT; 15092 app.cached = false; 15093 app.empty = false; 15094 foregroundActivities = true; 15095 } else if (r.state == ActivityState.STOPPING) { 15096 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15097 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15098 app.adjType = "stopping"; 15099 } 15100 // For the process state, we will at this point consider the 15101 // process to be cached. It will be cached either as an activity 15102 // or empty depending on whether the activity is finishing. We do 15103 // this so that we can treat the process as cached for purposes of 15104 // memory trimming (determing current memory level, trim command to 15105 // send to process) since there can be an arbitrary number of stopping 15106 // processes and they should soon all go into the cached state. 15107 if (!r.finishing) { 15108 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15109 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15110 } 15111 } 15112 app.cached = false; 15113 app.empty = false; 15114 foregroundActivities = true; 15115 } else { 15116 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15117 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15118 app.adjType = "cch-act"; 15119 } 15120 } 15121 } 15122 } 15123 15124 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15125 if (app.foregroundServices) { 15126 // The user is aware of this app, so make it visible. 15127 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15128 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15129 app.cached = false; 15130 app.adjType = "fg-service"; 15131 schedGroup = Process.THREAD_GROUP_DEFAULT; 15132 } else if (app.forcingToForeground != null) { 15133 // The user is aware of this app, so make it visible. 15134 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15135 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15136 app.cached = false; 15137 app.adjType = "force-fg"; 15138 app.adjSource = app.forcingToForeground; 15139 schedGroup = Process.THREAD_GROUP_DEFAULT; 15140 } 15141 } 15142 15143 if (app == mHeavyWeightProcess) { 15144 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15145 // We don't want to kill the current heavy-weight process. 15146 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15147 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15148 app.cached = false; 15149 app.adjType = "heavy"; 15150 } 15151 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15152 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15153 } 15154 } 15155 15156 if (app == mHomeProcess) { 15157 if (adj > ProcessList.HOME_APP_ADJ) { 15158 // This process is hosting what we currently consider to be the 15159 // home app, so we don't want to let it go into the background. 15160 adj = ProcessList.HOME_APP_ADJ; 15161 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15162 app.cached = false; 15163 app.adjType = "home"; 15164 } 15165 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15166 procState = ActivityManager.PROCESS_STATE_HOME; 15167 } 15168 } 15169 15170 if (app == mPreviousProcess && app.activities.size() > 0) { 15171 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15172 // This was the previous process that showed UI to the user. 15173 // We want to try to keep it around more aggressively, to give 15174 // a good experience around switching between two apps. 15175 adj = ProcessList.PREVIOUS_APP_ADJ; 15176 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15177 app.cached = false; 15178 app.adjType = "previous"; 15179 } 15180 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15181 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15182 } 15183 } 15184 15185 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15186 + " reason=" + app.adjType); 15187 15188 // By default, we use the computed adjustment. It may be changed if 15189 // there are applications dependent on our services or providers, but 15190 // this gives us a baseline and makes sure we don't get into an 15191 // infinite recursion. 15192 app.adjSeq = mAdjSeq; 15193 app.curRawAdj = adj; 15194 app.hasStartedServices = false; 15195 15196 if (mBackupTarget != null && app == mBackupTarget.app) { 15197 // If possible we want to avoid killing apps while they're being backed up 15198 if (adj > ProcessList.BACKUP_APP_ADJ) { 15199 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15200 adj = ProcessList.BACKUP_APP_ADJ; 15201 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15202 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15203 } 15204 app.adjType = "backup"; 15205 app.cached = false; 15206 } 15207 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15208 procState = ActivityManager.PROCESS_STATE_BACKUP; 15209 } 15210 } 15211 15212 boolean mayBeTop = false; 15213 15214 for (int is = app.services.size()-1; 15215 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15216 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15217 || procState > ActivityManager.PROCESS_STATE_TOP); 15218 is--) { 15219 ServiceRecord s = app.services.valueAt(is); 15220 if (s.startRequested) { 15221 app.hasStartedServices = true; 15222 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15223 procState = ActivityManager.PROCESS_STATE_SERVICE; 15224 } 15225 if (app.hasShownUi && app != mHomeProcess) { 15226 // If this process has shown some UI, let it immediately 15227 // go to the LRU list because it may be pretty heavy with 15228 // UI stuff. We'll tag it with a label just to help 15229 // debug and understand what is going on. 15230 if (adj > ProcessList.SERVICE_ADJ) { 15231 app.adjType = "cch-started-ui-services"; 15232 } 15233 } else { 15234 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15235 // This service has seen some activity within 15236 // recent memory, so we will keep its process ahead 15237 // of the background processes. 15238 if (adj > ProcessList.SERVICE_ADJ) { 15239 adj = ProcessList.SERVICE_ADJ; 15240 app.adjType = "started-services"; 15241 app.cached = false; 15242 } 15243 } 15244 // If we have let the service slide into the background 15245 // state, still have some text describing what it is doing 15246 // even though the service no longer has an impact. 15247 if (adj > ProcessList.SERVICE_ADJ) { 15248 app.adjType = "cch-started-services"; 15249 } 15250 } 15251 // Don't kill this process because it is doing work; it 15252 // has said it is doing work. 15253 app.keeping = true; 15254 } 15255 for (int conni = s.connections.size()-1; 15256 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15257 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15258 || procState > ActivityManager.PROCESS_STATE_TOP); 15259 conni--) { 15260 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15261 for (int i = 0; 15262 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15263 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15264 || procState > ActivityManager.PROCESS_STATE_TOP); 15265 i++) { 15266 // XXX should compute this based on the max of 15267 // all connected clients. 15268 ConnectionRecord cr = clist.get(i); 15269 if (cr.binding.client == app) { 15270 // Binding to ourself is not interesting. 15271 continue; 15272 } 15273 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15274 ProcessRecord client = cr.binding.client; 15275 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15276 TOP_APP, doingAll, now); 15277 int clientProcState = client.curProcState; 15278 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15279 // If the other app is cached for any reason, for purposes here 15280 // we are going to consider it empty. The specific cached state 15281 // doesn't propagate except under certain conditions. 15282 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15283 } 15284 String adjType = null; 15285 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15286 // Not doing bind OOM management, so treat 15287 // this guy more like a started service. 15288 if (app.hasShownUi && app != mHomeProcess) { 15289 // If this process has shown some UI, let it immediately 15290 // go to the LRU list because it may be pretty heavy with 15291 // UI stuff. We'll tag it with a label just to help 15292 // debug and understand what is going on. 15293 if (adj > clientAdj) { 15294 adjType = "cch-bound-ui-services"; 15295 } 15296 app.cached = false; 15297 clientAdj = adj; 15298 clientProcState = procState; 15299 } else { 15300 if (now >= (s.lastActivity 15301 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15302 // This service has not seen activity within 15303 // recent memory, so allow it to drop to the 15304 // LRU list if there is no other reason to keep 15305 // it around. We'll also tag it with a label just 15306 // to help debug and undertand what is going on. 15307 if (adj > clientAdj) { 15308 adjType = "cch-bound-services"; 15309 } 15310 clientAdj = adj; 15311 } 15312 } 15313 } 15314 if (adj > clientAdj) { 15315 // If this process has recently shown UI, and 15316 // the process that is binding to it is less 15317 // important than being visible, then we don't 15318 // care about the binding as much as we care 15319 // about letting this process get into the LRU 15320 // list to be killed and restarted if needed for 15321 // memory. 15322 if (app.hasShownUi && app != mHomeProcess 15323 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15324 adjType = "cch-bound-ui-services"; 15325 } else { 15326 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15327 |Context.BIND_IMPORTANT)) != 0) { 15328 adj = clientAdj; 15329 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15330 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15331 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15332 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15333 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15334 adj = clientAdj; 15335 } else { 15336 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15337 adj = ProcessList.VISIBLE_APP_ADJ; 15338 } 15339 } 15340 if (!client.cached) { 15341 app.cached = false; 15342 } 15343 if (client.keeping) { 15344 app.keeping = true; 15345 } 15346 adjType = "service"; 15347 } 15348 } 15349 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15350 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15351 schedGroup = Process.THREAD_GROUP_DEFAULT; 15352 } 15353 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15354 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15355 // Special handling of clients who are in the top state. 15356 // We *may* want to consider this process to be in the 15357 // top state as well, but only if there is not another 15358 // reason for it to be running. Being on the top is a 15359 // special state, meaning you are specifically running 15360 // for the current top app. If the process is already 15361 // running in the background for some other reason, it 15362 // is more important to continue considering it to be 15363 // in the background state. 15364 mayBeTop = true; 15365 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15366 } else { 15367 // Special handling for above-top states (persistent 15368 // processes). These should not bring the current process 15369 // into the top state, since they are not on top. Instead 15370 // give them the best state after that. 15371 clientProcState = 15372 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15373 } 15374 } 15375 } else { 15376 if (clientProcState < 15377 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15378 clientProcState = 15379 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15380 } 15381 } 15382 if (procState > clientProcState) { 15383 procState = clientProcState; 15384 } 15385 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15386 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15387 app.pendingUiClean = true; 15388 } 15389 if (adjType != null) { 15390 app.adjType = adjType; 15391 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15392 .REASON_SERVICE_IN_USE; 15393 app.adjSource = cr.binding.client; 15394 app.adjSourceOom = clientAdj; 15395 app.adjTarget = s.name; 15396 } 15397 } 15398 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15399 app.treatLikeActivity = true; 15400 } 15401 final ActivityRecord a = cr.activity; 15402 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15403 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15404 (a.visible || a.state == ActivityState.RESUMED 15405 || a.state == ActivityState.PAUSING)) { 15406 adj = ProcessList.FOREGROUND_APP_ADJ; 15407 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15408 schedGroup = Process.THREAD_GROUP_DEFAULT; 15409 } 15410 app.cached = false; 15411 app.adjType = "service"; 15412 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15413 .REASON_SERVICE_IN_USE; 15414 app.adjSource = a; 15415 app.adjSourceOom = adj; 15416 app.adjTarget = s.name; 15417 } 15418 } 15419 } 15420 } 15421 } 15422 15423 for (int provi = app.pubProviders.size()-1; 15424 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15425 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15426 || procState > ActivityManager.PROCESS_STATE_TOP); 15427 provi--) { 15428 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15429 for (int i = cpr.connections.size()-1; 15430 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15431 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15432 || procState > ActivityManager.PROCESS_STATE_TOP); 15433 i--) { 15434 ContentProviderConnection conn = cpr.connections.get(i); 15435 ProcessRecord client = conn.client; 15436 if (client == app) { 15437 // Being our own client is not interesting. 15438 continue; 15439 } 15440 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15441 int clientProcState = client.curProcState; 15442 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15443 // If the other app is cached for any reason, for purposes here 15444 // we are going to consider it empty. 15445 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15446 } 15447 if (adj > clientAdj) { 15448 if (app.hasShownUi && app != mHomeProcess 15449 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15450 app.adjType = "cch-ui-provider"; 15451 } else { 15452 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15453 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15454 app.adjType = "provider"; 15455 } 15456 app.cached &= client.cached; 15457 app.keeping |= client.keeping; 15458 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15459 .REASON_PROVIDER_IN_USE; 15460 app.adjSource = client; 15461 app.adjSourceOom = clientAdj; 15462 app.adjTarget = cpr.name; 15463 } 15464 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15465 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15466 // Special handling of clients who are in the top state. 15467 // We *may* want to consider this process to be in the 15468 // top state as well, but only if there is not another 15469 // reason for it to be running. Being on the top is a 15470 // special state, meaning you are specifically running 15471 // for the current top app. If the process is already 15472 // running in the background for some other reason, it 15473 // is more important to continue considering it to be 15474 // in the background state. 15475 mayBeTop = true; 15476 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15477 } else { 15478 // Special handling for above-top states (persistent 15479 // processes). These should not bring the current process 15480 // into the top state, since they are not on top. Instead 15481 // give them the best state after that. 15482 clientProcState = 15483 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15484 } 15485 } 15486 if (procState > clientProcState) { 15487 procState = clientProcState; 15488 } 15489 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15490 schedGroup = Process.THREAD_GROUP_DEFAULT; 15491 } 15492 } 15493 // If the provider has external (non-framework) process 15494 // dependencies, ensure that its adjustment is at least 15495 // FOREGROUND_APP_ADJ. 15496 if (cpr.hasExternalProcessHandles()) { 15497 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15498 adj = ProcessList.FOREGROUND_APP_ADJ; 15499 schedGroup = Process.THREAD_GROUP_DEFAULT; 15500 app.cached = false; 15501 app.keeping = true; 15502 app.adjType = "provider"; 15503 app.adjTarget = cpr.name; 15504 } 15505 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15506 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15507 } 15508 } 15509 } 15510 15511 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15512 // A client of one of our services or providers is in the top state. We 15513 // *may* want to be in the top state, but not if we are already running in 15514 // the background for some other reason. For the decision here, we are going 15515 // to pick out a few specific states that we want to remain in when a client 15516 // is top (states that tend to be longer-term) and otherwise allow it to go 15517 // to the top state. 15518 switch (procState) { 15519 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15520 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15521 case ActivityManager.PROCESS_STATE_SERVICE: 15522 // These all are longer-term states, so pull them up to the top 15523 // of the background states, but not all the way to the top state. 15524 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15525 break; 15526 default: 15527 // Otherwise, top is a better choice, so take it. 15528 procState = ActivityManager.PROCESS_STATE_TOP; 15529 break; 15530 } 15531 } 15532 15533 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15534 if (app.hasClientActivities) { 15535 // This is a cached process, but with client activities. Mark it so. 15536 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15537 app.adjType = "cch-client-act"; 15538 } else if (app.treatLikeActivity) { 15539 // This is a cached process, but somebody wants us to treat it like it has 15540 // an activity, okay! 15541 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15542 app.adjType = "cch-as-act"; 15543 } 15544 } 15545 15546 if (adj == ProcessList.SERVICE_ADJ) { 15547 if (doingAll) { 15548 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15549 mNewNumServiceProcs++; 15550 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15551 if (!app.serviceb) { 15552 // This service isn't far enough down on the LRU list to 15553 // normally be a B service, but if we are low on RAM and it 15554 // is large we want to force it down since we would prefer to 15555 // keep launcher over it. 15556 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15557 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15558 app.serviceHighRam = true; 15559 app.serviceb = true; 15560 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15561 } else { 15562 mNewNumAServiceProcs++; 15563 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15564 } 15565 } else { 15566 app.serviceHighRam = false; 15567 } 15568 } 15569 if (app.serviceb) { 15570 adj = ProcessList.SERVICE_B_ADJ; 15571 } 15572 } 15573 15574 app.curRawAdj = adj; 15575 15576 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15577 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15578 if (adj > app.maxAdj) { 15579 adj = app.maxAdj; 15580 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15581 schedGroup = Process.THREAD_GROUP_DEFAULT; 15582 } 15583 } 15584 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15585 app.keeping = true; 15586 } 15587 15588 // Do final modification to adj. Everything we do between here and applying 15589 // the final setAdj must be done in this function, because we will also use 15590 // it when computing the final cached adj later. Note that we don't need to 15591 // worry about this for max adj above, since max adj will always be used to 15592 // keep it out of the cached vaues. 15593 app.curAdj = app.modifyRawOomAdj(adj); 15594 app.curSchedGroup = schedGroup; 15595 app.curProcState = procState; 15596 app.foregroundActivities = foregroundActivities; 15597 15598 return app.curRawAdj; 15599 } 15600 15601 /** 15602 * Schedule PSS collection of a process. 15603 */ 15604 void requestPssLocked(ProcessRecord proc, int procState) { 15605 if (mPendingPssProcesses.contains(proc)) { 15606 return; 15607 } 15608 if (mPendingPssProcesses.size() == 0) { 15609 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15610 } 15611 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15612 proc.pssProcState = procState; 15613 mPendingPssProcesses.add(proc); 15614 } 15615 15616 /** 15617 * Schedule PSS collection of all processes. 15618 */ 15619 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15620 if (!always) { 15621 if (now < (mLastFullPssTime + 15622 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15623 return; 15624 } 15625 } 15626 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15627 mLastFullPssTime = now; 15628 mFullPssPending = true; 15629 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15630 mPendingPssProcesses.clear(); 15631 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15632 ProcessRecord app = mLruProcesses.get(i); 15633 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15634 app.pssProcState = app.setProcState; 15635 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15636 isSleeping(), now); 15637 mPendingPssProcesses.add(app); 15638 } 15639 } 15640 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15641 } 15642 15643 /** 15644 * Ask a given process to GC right now. 15645 */ 15646 final void performAppGcLocked(ProcessRecord app) { 15647 try { 15648 app.lastRequestedGc = SystemClock.uptimeMillis(); 15649 if (app.thread != null) { 15650 if (app.reportLowMemory) { 15651 app.reportLowMemory = false; 15652 app.thread.scheduleLowMemory(); 15653 } else { 15654 app.thread.processInBackground(); 15655 } 15656 } 15657 } catch (Exception e) { 15658 // whatever. 15659 } 15660 } 15661 15662 /** 15663 * Returns true if things are idle enough to perform GCs. 15664 */ 15665 private final boolean canGcNowLocked() { 15666 boolean processingBroadcasts = false; 15667 for (BroadcastQueue q : mBroadcastQueues) { 15668 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15669 processingBroadcasts = true; 15670 } 15671 } 15672 return !processingBroadcasts 15673 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15674 } 15675 15676 /** 15677 * Perform GCs on all processes that are waiting for it, but only 15678 * if things are idle. 15679 */ 15680 final void performAppGcsLocked() { 15681 final int N = mProcessesToGc.size(); 15682 if (N <= 0) { 15683 return; 15684 } 15685 if (canGcNowLocked()) { 15686 while (mProcessesToGc.size() > 0) { 15687 ProcessRecord proc = mProcessesToGc.remove(0); 15688 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15689 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15690 <= SystemClock.uptimeMillis()) { 15691 // To avoid spamming the system, we will GC processes one 15692 // at a time, waiting a few seconds between each. 15693 performAppGcLocked(proc); 15694 scheduleAppGcsLocked(); 15695 return; 15696 } else { 15697 // It hasn't been long enough since we last GCed this 15698 // process... put it in the list to wait for its time. 15699 addProcessToGcListLocked(proc); 15700 break; 15701 } 15702 } 15703 } 15704 15705 scheduleAppGcsLocked(); 15706 } 15707 } 15708 15709 /** 15710 * If all looks good, perform GCs on all processes waiting for them. 15711 */ 15712 final void performAppGcsIfAppropriateLocked() { 15713 if (canGcNowLocked()) { 15714 performAppGcsLocked(); 15715 return; 15716 } 15717 // Still not idle, wait some more. 15718 scheduleAppGcsLocked(); 15719 } 15720 15721 /** 15722 * Schedule the execution of all pending app GCs. 15723 */ 15724 final void scheduleAppGcsLocked() { 15725 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15726 15727 if (mProcessesToGc.size() > 0) { 15728 // Schedule a GC for the time to the next process. 15729 ProcessRecord proc = mProcessesToGc.get(0); 15730 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15731 15732 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15733 long now = SystemClock.uptimeMillis(); 15734 if (when < (now+GC_TIMEOUT)) { 15735 when = now + GC_TIMEOUT; 15736 } 15737 mHandler.sendMessageAtTime(msg, when); 15738 } 15739 } 15740 15741 /** 15742 * Add a process to the array of processes waiting to be GCed. Keeps the 15743 * list in sorted order by the last GC time. The process can't already be 15744 * on the list. 15745 */ 15746 final void addProcessToGcListLocked(ProcessRecord proc) { 15747 boolean added = false; 15748 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15749 if (mProcessesToGc.get(i).lastRequestedGc < 15750 proc.lastRequestedGc) { 15751 added = true; 15752 mProcessesToGc.add(i+1, proc); 15753 break; 15754 } 15755 } 15756 if (!added) { 15757 mProcessesToGc.add(0, proc); 15758 } 15759 } 15760 15761 /** 15762 * Set up to ask a process to GC itself. This will either do it 15763 * immediately, or put it on the list of processes to gc the next 15764 * time things are idle. 15765 */ 15766 final void scheduleAppGcLocked(ProcessRecord app) { 15767 long now = SystemClock.uptimeMillis(); 15768 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15769 return; 15770 } 15771 if (!mProcessesToGc.contains(app)) { 15772 addProcessToGcListLocked(app); 15773 scheduleAppGcsLocked(); 15774 } 15775 } 15776 15777 final void checkExcessivePowerUsageLocked(boolean doKills) { 15778 updateCpuStatsNow(); 15779 15780 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15781 boolean doWakeKills = doKills; 15782 boolean doCpuKills = doKills; 15783 if (mLastPowerCheckRealtime == 0) { 15784 doWakeKills = false; 15785 } 15786 if (mLastPowerCheckUptime == 0) { 15787 doCpuKills = false; 15788 } 15789 if (stats.isScreenOn()) { 15790 doWakeKills = false; 15791 } 15792 final long curRealtime = SystemClock.elapsedRealtime(); 15793 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15794 final long curUptime = SystemClock.uptimeMillis(); 15795 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15796 mLastPowerCheckRealtime = curRealtime; 15797 mLastPowerCheckUptime = curUptime; 15798 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15799 doWakeKills = false; 15800 } 15801 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15802 doCpuKills = false; 15803 } 15804 int i = mLruProcesses.size(); 15805 while (i > 0) { 15806 i--; 15807 ProcessRecord app = mLruProcesses.get(i); 15808 if (!app.keeping) { 15809 long wtime; 15810 synchronized (stats) { 15811 wtime = stats.getProcessWakeTime(app.info.uid, 15812 app.pid, curRealtime); 15813 } 15814 long wtimeUsed = wtime - app.lastWakeTime; 15815 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15816 if (DEBUG_POWER) { 15817 StringBuilder sb = new StringBuilder(128); 15818 sb.append("Wake for "); 15819 app.toShortString(sb); 15820 sb.append(": over "); 15821 TimeUtils.formatDuration(realtimeSince, sb); 15822 sb.append(" used "); 15823 TimeUtils.formatDuration(wtimeUsed, sb); 15824 sb.append(" ("); 15825 sb.append((wtimeUsed*100)/realtimeSince); 15826 sb.append("%)"); 15827 Slog.i(TAG, sb.toString()); 15828 sb.setLength(0); 15829 sb.append("CPU for "); 15830 app.toShortString(sb); 15831 sb.append(": over "); 15832 TimeUtils.formatDuration(uptimeSince, sb); 15833 sb.append(" used "); 15834 TimeUtils.formatDuration(cputimeUsed, sb); 15835 sb.append(" ("); 15836 sb.append((cputimeUsed*100)/uptimeSince); 15837 sb.append("%)"); 15838 Slog.i(TAG, sb.toString()); 15839 } 15840 // If a process has held a wake lock for more 15841 // than 50% of the time during this period, 15842 // that sounds bad. Kill! 15843 if (doWakeKills && realtimeSince > 0 15844 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15845 synchronized (stats) { 15846 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15847 realtimeSince, wtimeUsed); 15848 } 15849 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15850 + " during " + realtimeSince); 15851 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15852 } else if (doCpuKills && uptimeSince > 0 15853 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15854 synchronized (stats) { 15855 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15856 uptimeSince, cputimeUsed); 15857 } 15858 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15859 + " during " + uptimeSince); 15860 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15861 } else { 15862 app.lastWakeTime = wtime; 15863 app.lastCpuTime = app.curCpuTime; 15864 } 15865 } 15866 } 15867 } 15868 15869 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15870 ProcessRecord TOP_APP, boolean doingAll, long now) { 15871 boolean success = true; 15872 15873 if (app.curRawAdj != app.setRawAdj) { 15874 if (wasKeeping && !app.keeping) { 15875 // This app is no longer something we want to keep. Note 15876 // its current wake lock time to later know to kill it if 15877 // it is not behaving well. 15878 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15879 synchronized (stats) { 15880 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15881 app.pid, SystemClock.elapsedRealtime()); 15882 } 15883 app.lastCpuTime = app.curCpuTime; 15884 } 15885 15886 app.setRawAdj = app.curRawAdj; 15887 } 15888 15889 int changes = 0; 15890 15891 if (app.curAdj != app.setAdj) { 15892 ProcessList.setOomAdj(app.pid, app.curAdj); 15893 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15894 TAG, "Set " + app.pid + " " + app.processName + 15895 " adj " + app.curAdj + ": " + app.adjType); 15896 app.setAdj = app.curAdj; 15897 } 15898 15899 if (app.setSchedGroup != app.curSchedGroup) { 15900 app.setSchedGroup = app.curSchedGroup; 15901 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15902 "Setting process group of " + app.processName 15903 + " to " + app.curSchedGroup); 15904 if (app.waitingToKill != null && 15905 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15906 killUnneededProcessLocked(app, app.waitingToKill); 15907 success = false; 15908 } else { 15909 if (true) { 15910 long oldId = Binder.clearCallingIdentity(); 15911 try { 15912 Process.setProcessGroup(app.pid, app.curSchedGroup); 15913 } catch (Exception e) { 15914 Slog.w(TAG, "Failed setting process group of " + app.pid 15915 + " to " + app.curSchedGroup); 15916 e.printStackTrace(); 15917 } finally { 15918 Binder.restoreCallingIdentity(oldId); 15919 } 15920 } else { 15921 if (app.thread != null) { 15922 try { 15923 app.thread.setSchedulingGroup(app.curSchedGroup); 15924 } catch (RemoteException e) { 15925 } 15926 } 15927 } 15928 Process.setSwappiness(app.pid, 15929 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15930 } 15931 } 15932 if (app.repForegroundActivities != app.foregroundActivities) { 15933 app.repForegroundActivities = app.foregroundActivities; 15934 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15935 } 15936 if (app.repProcState != app.curProcState) { 15937 app.repProcState = app.curProcState; 15938 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15939 if (app.thread != null) { 15940 try { 15941 if (false) { 15942 //RuntimeException h = new RuntimeException("here"); 15943 Slog.i(TAG, "Sending new process state " + app.repProcState 15944 + " to " + app /*, h*/); 15945 } 15946 app.thread.setProcessState(app.repProcState); 15947 } catch (RemoteException e) { 15948 } 15949 } 15950 } 15951 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15952 app.setProcState)) { 15953 app.lastStateTime = now; 15954 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15955 isSleeping(), now); 15956 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15957 + ProcessList.makeProcStateString(app.setProcState) + " to " 15958 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15959 + (app.nextPssTime-now) + ": " + app); 15960 } else { 15961 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15962 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15963 requestPssLocked(app, app.setProcState); 15964 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15965 isSleeping(), now); 15966 } else if (false && DEBUG_PSS) { 15967 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15968 } 15969 } 15970 if (app.setProcState != app.curProcState) { 15971 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15972 "Proc state change of " + app.processName 15973 + " to " + app.curProcState); 15974 app.setProcState = app.curProcState; 15975 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15976 app.notCachedSinceIdle = false; 15977 } 15978 if (!doingAll) { 15979 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15980 } else { 15981 app.procStateChanged = true; 15982 } 15983 } 15984 15985 if (changes != 0) { 15986 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15987 int i = mPendingProcessChanges.size()-1; 15988 ProcessChangeItem item = null; 15989 while (i >= 0) { 15990 item = mPendingProcessChanges.get(i); 15991 if (item.pid == app.pid) { 15992 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15993 break; 15994 } 15995 i--; 15996 } 15997 if (i < 0) { 15998 // No existing item in pending changes; need a new one. 15999 final int NA = mAvailProcessChanges.size(); 16000 if (NA > 0) { 16001 item = mAvailProcessChanges.remove(NA-1); 16002 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16003 } else { 16004 item = new ProcessChangeItem(); 16005 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16006 } 16007 item.changes = 0; 16008 item.pid = app.pid; 16009 item.uid = app.info.uid; 16010 if (mPendingProcessChanges.size() == 0) { 16011 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16012 "*** Enqueueing dispatch processes changed!"); 16013 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16014 } 16015 mPendingProcessChanges.add(item); 16016 } 16017 item.changes |= changes; 16018 item.processState = app.repProcState; 16019 item.foregroundActivities = app.repForegroundActivities; 16020 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16021 + Integer.toHexString(System.identityHashCode(item)) 16022 + " " + app.toShortString() + ": changes=" + item.changes 16023 + " procState=" + item.processState 16024 + " foreground=" + item.foregroundActivities 16025 + " type=" + app.adjType + " source=" + app.adjSource 16026 + " target=" + app.adjTarget); 16027 } 16028 16029 return success; 16030 } 16031 16032 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16033 if (proc.thread != null && proc.baseProcessTracker != null) { 16034 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16035 } 16036 } 16037 16038 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16039 ProcessRecord TOP_APP, boolean doingAll, long now) { 16040 if (app.thread == null) { 16041 return false; 16042 } 16043 16044 final boolean wasKeeping = app.keeping; 16045 16046 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16047 16048 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16049 } 16050 16051 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16052 boolean oomAdj) { 16053 if (isForeground != proc.foregroundServices) { 16054 proc.foregroundServices = isForeground; 16055 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16056 proc.info.uid); 16057 if (isForeground) { 16058 if (curProcs == null) { 16059 curProcs = new ArrayList<ProcessRecord>(); 16060 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16061 } 16062 if (!curProcs.contains(proc)) { 16063 curProcs.add(proc); 16064 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16065 proc.info.packageName, proc.info.uid); 16066 } 16067 } else { 16068 if (curProcs != null) { 16069 if (curProcs.remove(proc)) { 16070 mBatteryStatsService.noteEvent( 16071 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16072 proc.info.packageName, proc.info.uid); 16073 if (curProcs.size() <= 0) { 16074 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16075 } 16076 } 16077 } 16078 } 16079 if (oomAdj) { 16080 updateOomAdjLocked(); 16081 } 16082 } 16083 } 16084 16085 private final ActivityRecord resumedAppLocked() { 16086 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16087 String pkg; 16088 int uid; 16089 if (act != null && !act.sleeping) { 16090 pkg = act.packageName; 16091 uid = act.info.applicationInfo.uid; 16092 } else { 16093 pkg = null; 16094 uid = -1; 16095 } 16096 // Has the UID or resumed package name changed? 16097 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16098 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16099 if (mCurResumedPackage != null) { 16100 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16101 mCurResumedPackage, mCurResumedUid); 16102 } 16103 mCurResumedPackage = pkg; 16104 mCurResumedUid = uid; 16105 if (mCurResumedPackage != null) { 16106 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16107 mCurResumedPackage, mCurResumedUid); 16108 } 16109 } 16110 return act; 16111 } 16112 16113 final boolean updateOomAdjLocked(ProcessRecord app) { 16114 final ActivityRecord TOP_ACT = resumedAppLocked(); 16115 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16116 final boolean wasCached = app.cached; 16117 16118 mAdjSeq++; 16119 16120 // This is the desired cached adjusment we want to tell it to use. 16121 // If our app is currently cached, we know it, and that is it. Otherwise, 16122 // we don't know it yet, and it needs to now be cached we will then 16123 // need to do a complete oom adj. 16124 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16125 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16126 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16127 SystemClock.uptimeMillis()); 16128 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16129 // Changed to/from cached state, so apps after it in the LRU 16130 // list may also be changed. 16131 updateOomAdjLocked(); 16132 } 16133 return success; 16134 } 16135 16136 final void updateOomAdjLocked() { 16137 final ActivityRecord TOP_ACT = resumedAppLocked(); 16138 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16139 final long now = SystemClock.uptimeMillis(); 16140 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16141 final int N = mLruProcesses.size(); 16142 16143 if (false) { 16144 RuntimeException e = new RuntimeException(); 16145 e.fillInStackTrace(); 16146 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16147 } 16148 16149 mAdjSeq++; 16150 mNewNumServiceProcs = 0; 16151 mNewNumAServiceProcs = 0; 16152 16153 final int emptyProcessLimit; 16154 final int cachedProcessLimit; 16155 if (mProcessLimit <= 0) { 16156 emptyProcessLimit = cachedProcessLimit = 0; 16157 } else if (mProcessLimit == 1) { 16158 emptyProcessLimit = 1; 16159 cachedProcessLimit = 0; 16160 } else { 16161 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16162 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16163 } 16164 16165 // Let's determine how many processes we have running vs. 16166 // how many slots we have for background processes; we may want 16167 // to put multiple processes in a slot of there are enough of 16168 // them. 16169 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16170 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16171 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16172 if (numEmptyProcs > cachedProcessLimit) { 16173 // If there are more empty processes than our limit on cached 16174 // processes, then use the cached process limit for the factor. 16175 // This ensures that the really old empty processes get pushed 16176 // down to the bottom, so if we are running low on memory we will 16177 // have a better chance at keeping around more cached processes 16178 // instead of a gazillion empty processes. 16179 numEmptyProcs = cachedProcessLimit; 16180 } 16181 int emptyFactor = numEmptyProcs/numSlots; 16182 if (emptyFactor < 1) emptyFactor = 1; 16183 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16184 if (cachedFactor < 1) cachedFactor = 1; 16185 int stepCached = 0; 16186 int stepEmpty = 0; 16187 int numCached = 0; 16188 int numEmpty = 0; 16189 int numTrimming = 0; 16190 16191 mNumNonCachedProcs = 0; 16192 mNumCachedHiddenProcs = 0; 16193 16194 // First update the OOM adjustment for each of the 16195 // application processes based on their current state. 16196 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16197 int nextCachedAdj = curCachedAdj+1; 16198 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16199 int nextEmptyAdj = curEmptyAdj+2; 16200 for (int i=N-1; i>=0; i--) { 16201 ProcessRecord app = mLruProcesses.get(i); 16202 if (!app.killedByAm && app.thread != null) { 16203 app.procStateChanged = false; 16204 final boolean wasKeeping = app.keeping; 16205 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16206 16207 // If we haven't yet assigned the final cached adj 16208 // to the process, do that now. 16209 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16210 switch (app.curProcState) { 16211 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16212 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16213 // This process is a cached process holding activities... 16214 // assign it the next cached value for that type, and then 16215 // step that cached level. 16216 app.curRawAdj = curCachedAdj; 16217 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16218 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16219 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16220 + ")"); 16221 if (curCachedAdj != nextCachedAdj) { 16222 stepCached++; 16223 if (stepCached >= cachedFactor) { 16224 stepCached = 0; 16225 curCachedAdj = nextCachedAdj; 16226 nextCachedAdj += 2; 16227 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16228 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16229 } 16230 } 16231 } 16232 break; 16233 default: 16234 // For everything else, assign next empty cached process 16235 // level and bump that up. Note that this means that 16236 // long-running services that have dropped down to the 16237 // cached level will be treated as empty (since their process 16238 // state is still as a service), which is what we want. 16239 app.curRawAdj = curEmptyAdj; 16240 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16241 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16242 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16243 + ")"); 16244 if (curEmptyAdj != nextEmptyAdj) { 16245 stepEmpty++; 16246 if (stepEmpty >= emptyFactor) { 16247 stepEmpty = 0; 16248 curEmptyAdj = nextEmptyAdj; 16249 nextEmptyAdj += 2; 16250 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16251 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16252 } 16253 } 16254 } 16255 break; 16256 } 16257 } 16258 16259 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16260 16261 // Count the number of process types. 16262 switch (app.curProcState) { 16263 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16264 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16265 mNumCachedHiddenProcs++; 16266 numCached++; 16267 if (numCached > cachedProcessLimit) { 16268 killUnneededProcessLocked(app, "cached #" + numCached); 16269 } 16270 break; 16271 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16272 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16273 && app.lastActivityTime < oldTime) { 16274 killUnneededProcessLocked(app, "empty for " 16275 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16276 / 1000) + "s"); 16277 } else { 16278 numEmpty++; 16279 if (numEmpty > emptyProcessLimit) { 16280 killUnneededProcessLocked(app, "empty #" + numEmpty); 16281 } 16282 } 16283 break; 16284 default: 16285 mNumNonCachedProcs++; 16286 break; 16287 } 16288 16289 if (app.isolated && app.services.size() <= 0) { 16290 // If this is an isolated process, and there are no 16291 // services running in it, then the process is no longer 16292 // needed. We agressively kill these because we can by 16293 // definition not re-use the same process again, and it is 16294 // good to avoid having whatever code was running in them 16295 // left sitting around after no longer needed. 16296 killUnneededProcessLocked(app, "isolated not needed"); 16297 } 16298 16299 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16300 && !app.killedByAm) { 16301 numTrimming++; 16302 } 16303 } 16304 } 16305 16306 mNumServiceProcs = mNewNumServiceProcs; 16307 16308 // Now determine the memory trimming level of background processes. 16309 // Unfortunately we need to start at the back of the list to do this 16310 // properly. We only do this if the number of background apps we 16311 // are managing to keep around is less than half the maximum we desire; 16312 // if we are keeping a good number around, we'll let them use whatever 16313 // memory they want. 16314 final int numCachedAndEmpty = numCached + numEmpty; 16315 int memFactor; 16316 if (numCached <= ProcessList.TRIM_CACHED_APPS 16317 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16318 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16319 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16320 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16321 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16322 } else { 16323 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16324 } 16325 } else { 16326 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16327 } 16328 // We always allow the memory level to go up (better). We only allow it to go 16329 // down if we are in a state where that is allowed, *and* the total number of processes 16330 // has gone down since last time. 16331 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16332 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16333 + " last=" + mLastNumProcesses); 16334 if (memFactor > mLastMemoryLevel) { 16335 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16336 memFactor = mLastMemoryLevel; 16337 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16338 } 16339 } 16340 mLastMemoryLevel = memFactor; 16341 mLastNumProcesses = mLruProcesses.size(); 16342 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16343 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16344 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16345 if (mLowRamStartTime == 0) { 16346 mLowRamStartTime = now; 16347 } 16348 int step = 0; 16349 int fgTrimLevel; 16350 switch (memFactor) { 16351 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16352 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16353 break; 16354 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16355 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16356 break; 16357 default: 16358 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16359 break; 16360 } 16361 int factor = numTrimming/3; 16362 int minFactor = 2; 16363 if (mHomeProcess != null) minFactor++; 16364 if (mPreviousProcess != null) minFactor++; 16365 if (factor < minFactor) factor = minFactor; 16366 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16367 for (int i=N-1; i>=0; i--) { 16368 ProcessRecord app = mLruProcesses.get(i); 16369 if (allChanged || app.procStateChanged) { 16370 setProcessTrackerState(app, trackerMemFactor, now); 16371 app.procStateChanged = false; 16372 } 16373 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16374 && !app.killedByAm) { 16375 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16376 try { 16377 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16378 "Trimming memory of " + app.processName 16379 + " to " + curLevel); 16380 app.thread.scheduleTrimMemory(curLevel); 16381 } catch (RemoteException e) { 16382 } 16383 if (false) { 16384 // For now we won't do this; our memory trimming seems 16385 // to be good enough at this point that destroying 16386 // activities causes more harm than good. 16387 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16388 && app != mHomeProcess && app != mPreviousProcess) { 16389 // Need to do this on its own message because the stack may not 16390 // be in a consistent state at this point. 16391 // For these apps we will also finish their activities 16392 // to help them free memory. 16393 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16394 } 16395 } 16396 } 16397 app.trimMemoryLevel = curLevel; 16398 step++; 16399 if (step >= factor) { 16400 step = 0; 16401 switch (curLevel) { 16402 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16403 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16404 break; 16405 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16406 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16407 break; 16408 } 16409 } 16410 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16411 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16412 && app.thread != null) { 16413 try { 16414 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16415 "Trimming memory of heavy-weight " + app.processName 16416 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16417 app.thread.scheduleTrimMemory( 16418 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16419 } catch (RemoteException e) { 16420 } 16421 } 16422 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16423 } else { 16424 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16425 || app.systemNoUi) && app.pendingUiClean) { 16426 // If this application is now in the background and it 16427 // had done UI, then give it the special trim level to 16428 // have it free UI resources. 16429 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16430 if (app.trimMemoryLevel < level && app.thread != null) { 16431 try { 16432 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16433 "Trimming memory of bg-ui " + app.processName 16434 + " to " + level); 16435 app.thread.scheduleTrimMemory(level); 16436 } catch (RemoteException e) { 16437 } 16438 } 16439 app.pendingUiClean = false; 16440 } 16441 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16442 try { 16443 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16444 "Trimming memory of fg " + app.processName 16445 + " to " + fgTrimLevel); 16446 app.thread.scheduleTrimMemory(fgTrimLevel); 16447 } catch (RemoteException e) { 16448 } 16449 } 16450 app.trimMemoryLevel = fgTrimLevel; 16451 } 16452 } 16453 } else { 16454 if (mLowRamStartTime != 0) { 16455 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16456 mLowRamStartTime = 0; 16457 } 16458 for (int i=N-1; i>=0; i--) { 16459 ProcessRecord app = mLruProcesses.get(i); 16460 if (allChanged || app.procStateChanged) { 16461 setProcessTrackerState(app, trackerMemFactor, now); 16462 app.procStateChanged = false; 16463 } 16464 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16465 || app.systemNoUi) && app.pendingUiClean) { 16466 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16467 && app.thread != null) { 16468 try { 16469 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16470 "Trimming memory of ui hidden " + app.processName 16471 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16472 app.thread.scheduleTrimMemory( 16473 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16474 } catch (RemoteException e) { 16475 } 16476 } 16477 app.pendingUiClean = false; 16478 } 16479 app.trimMemoryLevel = 0; 16480 } 16481 } 16482 16483 if (mAlwaysFinishActivities) { 16484 // Need to do this on its own message because the stack may not 16485 // be in a consistent state at this point. 16486 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16487 } 16488 16489 if (allChanged) { 16490 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16491 } 16492 16493 if (mProcessStats.shouldWriteNowLocked(now)) { 16494 mHandler.post(new Runnable() { 16495 @Override public void run() { 16496 synchronized (ActivityManagerService.this) { 16497 mProcessStats.writeStateAsyncLocked(); 16498 } 16499 } 16500 }); 16501 } 16502 16503 if (DEBUG_OOM_ADJ) { 16504 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16505 } 16506 } 16507 16508 final void trimApplications() { 16509 synchronized (this) { 16510 int i; 16511 16512 // First remove any unused application processes whose package 16513 // has been removed. 16514 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16515 final ProcessRecord app = mRemovedProcesses.get(i); 16516 if (app.activities.size() == 0 16517 && app.curReceiver == null && app.services.size() == 0) { 16518 Slog.i( 16519 TAG, "Exiting empty application process " 16520 + app.processName + " (" 16521 + (app.thread != null ? app.thread.asBinder() : null) 16522 + ")\n"); 16523 if (app.pid > 0 && app.pid != MY_PID) { 16524 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16525 app.processName, app.setAdj, "empty"); 16526 app.killedByAm = true; 16527 Process.killProcessQuiet(app.pid); 16528 } else { 16529 try { 16530 app.thread.scheduleExit(); 16531 } catch (Exception e) { 16532 // Ignore exceptions. 16533 } 16534 } 16535 cleanUpApplicationRecordLocked(app, false, true, -1); 16536 mRemovedProcesses.remove(i); 16537 16538 if (app.persistent) { 16539 if (app.persistent) { 16540 addAppLocked(app.info, false, null /* ABI override */); 16541 } 16542 } 16543 } 16544 } 16545 16546 // Now update the oom adj for all processes. 16547 updateOomAdjLocked(); 16548 } 16549 } 16550 16551 /** This method sends the specified signal to each of the persistent apps */ 16552 public void signalPersistentProcesses(int sig) throws RemoteException { 16553 if (sig != Process.SIGNAL_USR1) { 16554 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16555 } 16556 16557 synchronized (this) { 16558 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16559 != PackageManager.PERMISSION_GRANTED) { 16560 throw new SecurityException("Requires permission " 16561 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16562 } 16563 16564 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16565 ProcessRecord r = mLruProcesses.get(i); 16566 if (r.thread != null && r.persistent) { 16567 Process.sendSignal(r.pid, sig); 16568 } 16569 } 16570 } 16571 } 16572 16573 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16574 if (proc == null || proc == mProfileProc) { 16575 proc = mProfileProc; 16576 path = mProfileFile; 16577 profileType = mProfileType; 16578 clearProfilerLocked(); 16579 } 16580 if (proc == null) { 16581 return; 16582 } 16583 try { 16584 proc.thread.profilerControl(false, path, null, profileType); 16585 } catch (RemoteException e) { 16586 throw new IllegalStateException("Process disappeared"); 16587 } 16588 } 16589 16590 private void clearProfilerLocked() { 16591 if (mProfileFd != null) { 16592 try { 16593 mProfileFd.close(); 16594 } catch (IOException e) { 16595 } 16596 } 16597 mProfileApp = null; 16598 mProfileProc = null; 16599 mProfileFile = null; 16600 mProfileType = 0; 16601 mAutoStopProfiler = false; 16602 } 16603 16604 public boolean profileControl(String process, int userId, boolean start, 16605 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16606 16607 try { 16608 synchronized (this) { 16609 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16610 // its own permission. 16611 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16612 != PackageManager.PERMISSION_GRANTED) { 16613 throw new SecurityException("Requires permission " 16614 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16615 } 16616 16617 if (start && fd == null) { 16618 throw new IllegalArgumentException("null fd"); 16619 } 16620 16621 ProcessRecord proc = null; 16622 if (process != null) { 16623 proc = findProcessLocked(process, userId, "profileControl"); 16624 } 16625 16626 if (start && (proc == null || proc.thread == null)) { 16627 throw new IllegalArgumentException("Unknown process: " + process); 16628 } 16629 16630 if (start) { 16631 stopProfilerLocked(null, null, 0); 16632 setProfileApp(proc.info, proc.processName, path, fd, false); 16633 mProfileProc = proc; 16634 mProfileType = profileType; 16635 try { 16636 fd = fd.dup(); 16637 } catch (IOException e) { 16638 fd = null; 16639 } 16640 proc.thread.profilerControl(start, path, fd, profileType); 16641 fd = null; 16642 mProfileFd = null; 16643 } else { 16644 stopProfilerLocked(proc, path, profileType); 16645 if (fd != null) { 16646 try { 16647 fd.close(); 16648 } catch (IOException e) { 16649 } 16650 } 16651 } 16652 16653 return true; 16654 } 16655 } catch (RemoteException e) { 16656 throw new IllegalStateException("Process disappeared"); 16657 } finally { 16658 if (fd != null) { 16659 try { 16660 fd.close(); 16661 } catch (IOException e) { 16662 } 16663 } 16664 } 16665 } 16666 16667 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16669 userId, true, true, callName, null); 16670 ProcessRecord proc = null; 16671 try { 16672 int pid = Integer.parseInt(process); 16673 synchronized (mPidsSelfLocked) { 16674 proc = mPidsSelfLocked.get(pid); 16675 } 16676 } catch (NumberFormatException e) { 16677 } 16678 16679 if (proc == null) { 16680 ArrayMap<String, SparseArray<ProcessRecord>> all 16681 = mProcessNames.getMap(); 16682 SparseArray<ProcessRecord> procs = all.get(process); 16683 if (procs != null && procs.size() > 0) { 16684 proc = procs.valueAt(0); 16685 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16686 for (int i=1; i<procs.size(); i++) { 16687 ProcessRecord thisProc = procs.valueAt(i); 16688 if (thisProc.userId == userId) { 16689 proc = thisProc; 16690 break; 16691 } 16692 } 16693 } 16694 } 16695 } 16696 16697 return proc; 16698 } 16699 16700 public boolean dumpHeap(String process, int userId, boolean managed, 16701 String path, ParcelFileDescriptor fd) throws RemoteException { 16702 16703 try { 16704 synchronized (this) { 16705 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16706 // its own permission (same as profileControl). 16707 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16708 != PackageManager.PERMISSION_GRANTED) { 16709 throw new SecurityException("Requires permission " 16710 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16711 } 16712 16713 if (fd == null) { 16714 throw new IllegalArgumentException("null fd"); 16715 } 16716 16717 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16718 if (proc == null || proc.thread == null) { 16719 throw new IllegalArgumentException("Unknown process: " + process); 16720 } 16721 16722 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16723 if (!isDebuggable) { 16724 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16725 throw new SecurityException("Process not debuggable: " + proc); 16726 } 16727 } 16728 16729 proc.thread.dumpHeap(managed, path, fd); 16730 fd = null; 16731 return true; 16732 } 16733 } catch (RemoteException e) { 16734 throw new IllegalStateException("Process disappeared"); 16735 } finally { 16736 if (fd != null) { 16737 try { 16738 fd.close(); 16739 } catch (IOException e) { 16740 } 16741 } 16742 } 16743 } 16744 16745 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16746 public void monitor() { 16747 synchronized (this) { } 16748 } 16749 16750 void onCoreSettingsChange(Bundle settings) { 16751 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16752 ProcessRecord processRecord = mLruProcesses.get(i); 16753 try { 16754 if (processRecord.thread != null) { 16755 processRecord.thread.setCoreSettings(settings); 16756 } 16757 } catch (RemoteException re) { 16758 /* ignore */ 16759 } 16760 } 16761 } 16762 16763 // Multi-user methods 16764 16765 /** 16766 * Start user, if its not already running, but don't bring it to foreground. 16767 */ 16768 @Override 16769 public boolean startUserInBackground(final int userId) { 16770 return startUser(userId, /* foreground */ false); 16771 } 16772 16773 /** 16774 * Refreshes the list of users related to the current user when either a 16775 * user switch happens or when a new related user is started in the 16776 * background. 16777 */ 16778 private void updateCurrentProfileIdsLocked() { 16779 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16780 mCurrentUserId, false /* enabledOnly */); 16781 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16782 for (int i = 0; i < currentProfileIds.length; i++) { 16783 currentProfileIds[i] = profiles.get(i).id; 16784 } 16785 mCurrentProfileIds = currentProfileIds; 16786 } 16787 16788 private Set getProfileIdsLocked(int userId) { 16789 Set userIds = new HashSet<Integer>(); 16790 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16791 userId, false /* enabledOnly */); 16792 for (UserInfo user : profiles) { 16793 userIds.add(Integer.valueOf(user.id)); 16794 } 16795 return userIds; 16796 } 16797 16798 @Override 16799 public boolean switchUser(final int userId) { 16800 return startUser(userId, /* foregound */ true); 16801 } 16802 16803 private boolean startUser(final int userId, boolean foreground) { 16804 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16805 != PackageManager.PERMISSION_GRANTED) { 16806 String msg = "Permission Denial: switchUser() from pid=" 16807 + Binder.getCallingPid() 16808 + ", uid=" + Binder.getCallingUid() 16809 + " requires " + INTERACT_ACROSS_USERS_FULL; 16810 Slog.w(TAG, msg); 16811 throw new SecurityException(msg); 16812 } 16813 16814 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16815 16816 final long ident = Binder.clearCallingIdentity(); 16817 try { 16818 synchronized (this) { 16819 final int oldUserId = mCurrentUserId; 16820 if (oldUserId == userId) { 16821 return true; 16822 } 16823 16824 mStackSupervisor.setLockTaskModeLocked(null, false); 16825 16826 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16827 if (userInfo == null) { 16828 Slog.w(TAG, "No user info for user #" + userId); 16829 return false; 16830 } 16831 16832 if (foreground) { 16833 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16834 R.anim.screen_user_enter); 16835 } 16836 16837 boolean needStart = false; 16838 16839 // If the user we are switching to is not currently started, then 16840 // we need to start it now. 16841 if (mStartedUsers.get(userId) == null) { 16842 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16843 updateStartedUserArrayLocked(); 16844 needStart = true; 16845 } 16846 16847 final Integer userIdInt = Integer.valueOf(userId); 16848 mUserLru.remove(userIdInt); 16849 mUserLru.add(userIdInt); 16850 16851 if (foreground) { 16852 mCurrentUserId = userId; 16853 updateCurrentProfileIdsLocked(); 16854 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16855 // Once the internal notion of the active user has switched, we lock the device 16856 // with the option to show the user switcher on the keyguard. 16857 mWindowManager.lockNow(null); 16858 } else { 16859 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16860 updateCurrentProfileIdsLocked(); 16861 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16862 mUserLru.remove(currentUserIdInt); 16863 mUserLru.add(currentUserIdInt); 16864 } 16865 16866 final UserStartedState uss = mStartedUsers.get(userId); 16867 16868 // Make sure user is in the started state. If it is currently 16869 // stopping, we need to knock that off. 16870 if (uss.mState == UserStartedState.STATE_STOPPING) { 16871 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16872 // so we can just fairly silently bring the user back from 16873 // the almost-dead. 16874 uss.mState = UserStartedState.STATE_RUNNING; 16875 updateStartedUserArrayLocked(); 16876 needStart = true; 16877 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16878 // This means ACTION_SHUTDOWN has been sent, so we will 16879 // need to treat this as a new boot of the user. 16880 uss.mState = UserStartedState.STATE_BOOTING; 16881 updateStartedUserArrayLocked(); 16882 needStart = true; 16883 } 16884 16885 if (uss.mState == UserStartedState.STATE_BOOTING) { 16886 // Booting up a new user, need to tell system services about it. 16887 // Note that this is on the same handler as scheduling of broadcasts, 16888 // which is important because it needs to go first. 16889 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16890 } 16891 16892 if (foreground) { 16893 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16894 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16895 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16896 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16897 oldUserId, userId, uss)); 16898 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16899 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16900 } 16901 16902 if (needStart) { 16903 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16904 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16905 | Intent.FLAG_RECEIVER_FOREGROUND); 16906 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16907 broadcastIntentLocked(null, null, intent, 16908 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16909 false, false, MY_PID, Process.SYSTEM_UID, userId); 16910 } 16911 16912 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16913 if (userId != UserHandle.USER_OWNER) { 16914 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16915 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16916 broadcastIntentLocked(null, null, intent, null, 16917 new IIntentReceiver.Stub() { 16918 public void performReceive(Intent intent, int resultCode, 16919 String data, Bundle extras, boolean ordered, 16920 boolean sticky, int sendingUser) { 16921 userInitialized(uss, userId); 16922 } 16923 }, 0, null, null, null, AppOpsManager.OP_NONE, 16924 true, false, MY_PID, Process.SYSTEM_UID, 16925 userId); 16926 uss.initializing = true; 16927 } else { 16928 getUserManagerLocked().makeInitialized(userInfo.id); 16929 } 16930 } 16931 16932 if (foreground) { 16933 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16934 if (homeInFront) { 16935 startHomeActivityLocked(userId); 16936 } else { 16937 mStackSupervisor.resumeTopActivitiesLocked(); 16938 } 16939 EventLogTags.writeAmSwitchUser(userId); 16940 getUserManagerLocked().userForeground(userId); 16941 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16942 } else { 16943 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16944 } 16945 16946 if (needStart) { 16947 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16948 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16949 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16950 broadcastIntentLocked(null, null, intent, 16951 null, new IIntentReceiver.Stub() { 16952 @Override 16953 public void performReceive(Intent intent, int resultCode, String data, 16954 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16955 throws RemoteException { 16956 } 16957 }, 0, null, null, 16958 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16959 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16960 } 16961 } 16962 } finally { 16963 Binder.restoreCallingIdentity(ident); 16964 } 16965 16966 return true; 16967 } 16968 16969 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16970 long ident = Binder.clearCallingIdentity(); 16971 try { 16972 Intent intent; 16973 if (oldUserId >= 0) { 16974 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16975 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16976 | Intent.FLAG_RECEIVER_FOREGROUND); 16977 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16978 broadcastIntentLocked(null, null, intent, 16979 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16980 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16981 } 16982 if (newUserId >= 0) { 16983 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16984 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16985 | Intent.FLAG_RECEIVER_FOREGROUND); 16986 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16987 broadcastIntentLocked(null, null, intent, 16988 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16989 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16990 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16991 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16992 | Intent.FLAG_RECEIVER_FOREGROUND); 16993 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16994 broadcastIntentLocked(null, null, intent, 16995 null, null, 0, null, null, 16996 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16997 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16998 } 16999 } finally { 17000 Binder.restoreCallingIdentity(ident); 17001 } 17002 } 17003 17004 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17005 final int newUserId) { 17006 final int N = mUserSwitchObservers.beginBroadcast(); 17007 if (N > 0) { 17008 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17009 int mCount = 0; 17010 @Override 17011 public void sendResult(Bundle data) throws RemoteException { 17012 synchronized (ActivityManagerService.this) { 17013 if (mCurUserSwitchCallback == this) { 17014 mCount++; 17015 if (mCount == N) { 17016 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17017 } 17018 } 17019 } 17020 } 17021 }; 17022 synchronized (this) { 17023 uss.switching = true; 17024 mCurUserSwitchCallback = callback; 17025 } 17026 for (int i=0; i<N; i++) { 17027 try { 17028 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17029 newUserId, callback); 17030 } catch (RemoteException e) { 17031 } 17032 } 17033 } else { 17034 synchronized (this) { 17035 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17036 } 17037 } 17038 mUserSwitchObservers.finishBroadcast(); 17039 } 17040 17041 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17042 synchronized (this) { 17043 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17044 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17045 } 17046 } 17047 17048 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17049 mCurUserSwitchCallback = null; 17050 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17051 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17052 oldUserId, newUserId, uss)); 17053 } 17054 17055 void userInitialized(UserStartedState uss, int newUserId) { 17056 completeSwitchAndInitalize(uss, newUserId, true, false); 17057 } 17058 17059 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17060 completeSwitchAndInitalize(uss, newUserId, false, true); 17061 } 17062 17063 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17064 boolean clearInitializing, boolean clearSwitching) { 17065 boolean unfrozen = false; 17066 synchronized (this) { 17067 if (clearInitializing) { 17068 uss.initializing = false; 17069 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17070 } 17071 if (clearSwitching) { 17072 uss.switching = false; 17073 } 17074 if (!uss.switching && !uss.initializing) { 17075 mWindowManager.stopFreezingScreen(); 17076 unfrozen = true; 17077 } 17078 } 17079 if (unfrozen) { 17080 final int N = mUserSwitchObservers.beginBroadcast(); 17081 for (int i=0; i<N; i++) { 17082 try { 17083 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17084 } catch (RemoteException e) { 17085 } 17086 } 17087 mUserSwitchObservers.finishBroadcast(); 17088 } 17089 } 17090 17091 void scheduleStartProfilesLocked() { 17092 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17093 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17094 DateUtils.SECOND_IN_MILLIS); 17095 } 17096 } 17097 17098 void startProfilesLocked() { 17099 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17100 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17101 mCurrentUserId, false /* enabledOnly */); 17102 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17103 for (UserInfo user : profiles) { 17104 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17105 && user.id != mCurrentUserId) { 17106 toStart.add(user); 17107 } 17108 } 17109 final int n = toStart.size(); 17110 int i = 0; 17111 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17112 startUserInBackground(toStart.get(i).id); 17113 } 17114 if (i < n) { 17115 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17116 } 17117 } 17118 17119 void finishUserBoot(UserStartedState uss) { 17120 synchronized (this) { 17121 if (uss.mState == UserStartedState.STATE_BOOTING 17122 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17123 uss.mState = UserStartedState.STATE_RUNNING; 17124 final int userId = uss.mHandle.getIdentifier(); 17125 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17126 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17127 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17128 broadcastIntentLocked(null, null, intent, 17129 null, null, 0, null, null, 17130 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17131 true, false, MY_PID, Process.SYSTEM_UID, userId); 17132 } 17133 } 17134 } 17135 17136 void finishUserSwitch(UserStartedState uss) { 17137 synchronized (this) { 17138 finishUserBoot(uss); 17139 17140 startProfilesLocked(); 17141 17142 int num = mUserLru.size(); 17143 int i = 0; 17144 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17145 Integer oldUserId = mUserLru.get(i); 17146 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17147 if (oldUss == null) { 17148 // Shouldn't happen, but be sane if it does. 17149 mUserLru.remove(i); 17150 num--; 17151 continue; 17152 } 17153 if (oldUss.mState == UserStartedState.STATE_STOPPING 17154 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17155 // This user is already stopping, doesn't count. 17156 num--; 17157 i++; 17158 continue; 17159 } 17160 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17161 // Owner and current can't be stopped, but count as running. 17162 i++; 17163 continue; 17164 } 17165 // This is a user to be stopped. 17166 stopUserLocked(oldUserId, null); 17167 num--; 17168 i++; 17169 } 17170 } 17171 } 17172 17173 @Override 17174 public int stopUser(final int userId, final IStopUserCallback callback) { 17175 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17176 != PackageManager.PERMISSION_GRANTED) { 17177 String msg = "Permission Denial: switchUser() from pid=" 17178 + Binder.getCallingPid() 17179 + ", uid=" + Binder.getCallingUid() 17180 + " requires " + INTERACT_ACROSS_USERS_FULL; 17181 Slog.w(TAG, msg); 17182 throw new SecurityException(msg); 17183 } 17184 if (userId <= 0) { 17185 throw new IllegalArgumentException("Can't stop primary user " + userId); 17186 } 17187 synchronized (this) { 17188 return stopUserLocked(userId, callback); 17189 } 17190 } 17191 17192 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17193 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17194 if (mCurrentUserId == userId) { 17195 return ActivityManager.USER_OP_IS_CURRENT; 17196 } 17197 17198 final UserStartedState uss = mStartedUsers.get(userId); 17199 if (uss == null) { 17200 // User is not started, nothing to do... but we do need to 17201 // callback if requested. 17202 if (callback != null) { 17203 mHandler.post(new Runnable() { 17204 @Override 17205 public void run() { 17206 try { 17207 callback.userStopped(userId); 17208 } catch (RemoteException e) { 17209 } 17210 } 17211 }); 17212 } 17213 return ActivityManager.USER_OP_SUCCESS; 17214 } 17215 17216 if (callback != null) { 17217 uss.mStopCallbacks.add(callback); 17218 } 17219 17220 if (uss.mState != UserStartedState.STATE_STOPPING 17221 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17222 uss.mState = UserStartedState.STATE_STOPPING; 17223 updateStartedUserArrayLocked(); 17224 17225 long ident = Binder.clearCallingIdentity(); 17226 try { 17227 // We are going to broadcast ACTION_USER_STOPPING and then 17228 // once that is done send a final ACTION_SHUTDOWN and then 17229 // stop the user. 17230 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17231 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17232 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17233 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17234 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17235 // This is the result receiver for the final shutdown broadcast. 17236 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17237 @Override 17238 public void performReceive(Intent intent, int resultCode, String data, 17239 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17240 finishUserStop(uss); 17241 } 17242 }; 17243 // This is the result receiver for the initial stopping broadcast. 17244 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17245 @Override 17246 public void performReceive(Intent intent, int resultCode, String data, 17247 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17248 // On to the next. 17249 synchronized (ActivityManagerService.this) { 17250 if (uss.mState != UserStartedState.STATE_STOPPING) { 17251 // Whoops, we are being started back up. Abort, abort! 17252 return; 17253 } 17254 uss.mState = UserStartedState.STATE_SHUTDOWN; 17255 } 17256 mSystemServiceManager.stopUser(userId); 17257 broadcastIntentLocked(null, null, shutdownIntent, 17258 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17259 true, false, MY_PID, Process.SYSTEM_UID, userId); 17260 } 17261 }; 17262 // Kick things off. 17263 broadcastIntentLocked(null, null, stoppingIntent, 17264 null, stoppingReceiver, 0, null, null, 17265 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17266 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17267 } finally { 17268 Binder.restoreCallingIdentity(ident); 17269 } 17270 } 17271 17272 return ActivityManager.USER_OP_SUCCESS; 17273 } 17274 17275 void finishUserStop(UserStartedState uss) { 17276 final int userId = uss.mHandle.getIdentifier(); 17277 boolean stopped; 17278 ArrayList<IStopUserCallback> callbacks; 17279 synchronized (this) { 17280 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17281 if (mStartedUsers.get(userId) != uss) { 17282 stopped = false; 17283 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17284 stopped = false; 17285 } else { 17286 stopped = true; 17287 // User can no longer run. 17288 mStartedUsers.remove(userId); 17289 mUserLru.remove(Integer.valueOf(userId)); 17290 updateStartedUserArrayLocked(); 17291 17292 // Clean up all state and processes associated with the user. 17293 // Kill all the processes for the user. 17294 forceStopUserLocked(userId, "finish user"); 17295 } 17296 } 17297 17298 for (int i=0; i<callbacks.size(); i++) { 17299 try { 17300 if (stopped) callbacks.get(i).userStopped(userId); 17301 else callbacks.get(i).userStopAborted(userId); 17302 } catch (RemoteException e) { 17303 } 17304 } 17305 17306 if (stopped) { 17307 mSystemServiceManager.cleanupUser(userId); 17308 synchronized (this) { 17309 mStackSupervisor.removeUserLocked(userId); 17310 } 17311 } 17312 } 17313 17314 @Override 17315 public UserInfo getCurrentUser() { 17316 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17317 != PackageManager.PERMISSION_GRANTED) && ( 17318 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17319 != PackageManager.PERMISSION_GRANTED)) { 17320 String msg = "Permission Denial: getCurrentUser() from pid=" 17321 + Binder.getCallingPid() 17322 + ", uid=" + Binder.getCallingUid() 17323 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17324 Slog.w(TAG, msg); 17325 throw new SecurityException(msg); 17326 } 17327 synchronized (this) { 17328 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17329 } 17330 } 17331 17332 int getCurrentUserIdLocked() { 17333 return mCurrentUserId; 17334 } 17335 17336 @Override 17337 public boolean isUserRunning(int userId, boolean orStopped) { 17338 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17339 != PackageManager.PERMISSION_GRANTED) { 17340 String msg = "Permission Denial: isUserRunning() from pid=" 17341 + Binder.getCallingPid() 17342 + ", uid=" + Binder.getCallingUid() 17343 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17344 Slog.w(TAG, msg); 17345 throw new SecurityException(msg); 17346 } 17347 synchronized (this) { 17348 return isUserRunningLocked(userId, orStopped); 17349 } 17350 } 17351 17352 boolean isUserRunningLocked(int userId, boolean orStopped) { 17353 UserStartedState state = mStartedUsers.get(userId); 17354 if (state == null) { 17355 return false; 17356 } 17357 if (orStopped) { 17358 return true; 17359 } 17360 return state.mState != UserStartedState.STATE_STOPPING 17361 && state.mState != UserStartedState.STATE_SHUTDOWN; 17362 } 17363 17364 @Override 17365 public int[] getRunningUserIds() { 17366 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17367 != PackageManager.PERMISSION_GRANTED) { 17368 String msg = "Permission Denial: isUserRunning() from pid=" 17369 + Binder.getCallingPid() 17370 + ", uid=" + Binder.getCallingUid() 17371 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17372 Slog.w(TAG, msg); 17373 throw new SecurityException(msg); 17374 } 17375 synchronized (this) { 17376 return mStartedUserArray; 17377 } 17378 } 17379 17380 private void updateStartedUserArrayLocked() { 17381 int num = 0; 17382 for (int i=0; i<mStartedUsers.size(); i++) { 17383 UserStartedState uss = mStartedUsers.valueAt(i); 17384 // This list does not include stopping users. 17385 if (uss.mState != UserStartedState.STATE_STOPPING 17386 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17387 num++; 17388 } 17389 } 17390 mStartedUserArray = new int[num]; 17391 num = 0; 17392 for (int i=0; i<mStartedUsers.size(); i++) { 17393 UserStartedState uss = mStartedUsers.valueAt(i); 17394 if (uss.mState != UserStartedState.STATE_STOPPING 17395 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17396 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17397 num++; 17398 } 17399 } 17400 } 17401 17402 @Override 17403 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17404 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17405 != PackageManager.PERMISSION_GRANTED) { 17406 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17407 + Binder.getCallingPid() 17408 + ", uid=" + Binder.getCallingUid() 17409 + " requires " + INTERACT_ACROSS_USERS_FULL; 17410 Slog.w(TAG, msg); 17411 throw new SecurityException(msg); 17412 } 17413 17414 mUserSwitchObservers.register(observer); 17415 } 17416 17417 @Override 17418 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17419 mUserSwitchObservers.unregister(observer); 17420 } 17421 17422 private boolean userExists(int userId) { 17423 if (userId == 0) { 17424 return true; 17425 } 17426 UserManagerService ums = getUserManagerLocked(); 17427 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17428 } 17429 17430 int[] getUsersLocked() { 17431 UserManagerService ums = getUserManagerLocked(); 17432 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17433 } 17434 17435 UserManagerService getUserManagerLocked() { 17436 if (mUserManager == null) { 17437 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17438 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17439 } 17440 return mUserManager; 17441 } 17442 17443 private int applyUserId(int uid, int userId) { 17444 return UserHandle.getUid(userId, uid); 17445 } 17446 17447 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17448 if (info == null) return null; 17449 ApplicationInfo newInfo = new ApplicationInfo(info); 17450 newInfo.uid = applyUserId(info.uid, userId); 17451 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17452 + info.packageName; 17453 return newInfo; 17454 } 17455 17456 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17457 if (aInfo == null 17458 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17459 return aInfo; 17460 } 17461 17462 ActivityInfo info = new ActivityInfo(aInfo); 17463 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17464 return info; 17465 } 17466 17467 private final class LocalService extends ActivityManagerInternal { 17468 @Override 17469 public void goingToSleep() { 17470 ActivityManagerService.this.goingToSleep(); 17471 } 17472 17473 @Override 17474 public void wakingUp() { 17475 ActivityManagerService.this.wakingUp(); 17476 } 17477 } 17478 17479 /** 17480 * An implementation of IAppTask, that allows an app to manage its own tasks via 17481 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17482 * only the process that calls getAppTasks() can call the AppTask methods. 17483 */ 17484 class AppTaskImpl extends IAppTask.Stub { 17485 private int mTaskId; 17486 private int mCallingUid; 17487 17488 public AppTaskImpl(int taskId, int callingUid) { 17489 mTaskId = taskId; 17490 mCallingUid = callingUid; 17491 } 17492 17493 @Override 17494 public void finishAndRemoveTask() { 17495 // Ensure that we are called from the same process that created this AppTask 17496 if (mCallingUid != Binder.getCallingUid()) { 17497 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17498 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17499 return; 17500 } 17501 17502 synchronized (ActivityManagerService.this) { 17503 long origId = Binder.clearCallingIdentity(); 17504 try { 17505 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17506 if (tr != null) { 17507 // Only kill the process if we are not a new document 17508 int flags = tr.getBaseIntent().getFlags(); 17509 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17510 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17511 removeTaskByIdLocked(mTaskId, 17512 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17513 } 17514 } finally { 17515 Binder.restoreCallingIdentity(origId); 17516 } 17517 } 17518 } 17519 17520 @Override 17521 public ActivityManager.RecentTaskInfo getTaskInfo() { 17522 // Ensure that we are called from the same process that created this AppTask 17523 if (mCallingUid != Binder.getCallingUid()) { 17524 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17525 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17526 return null; 17527 } 17528 17529 synchronized (ActivityManagerService.this) { 17530 long origId = Binder.clearCallingIdentity(); 17531 try { 17532 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17533 if (tr != null) { 17534 return createRecentTaskInfoFromTaskRecord(tr); 17535 } 17536 } finally { 17537 Binder.restoreCallingIdentity(origId); 17538 } 17539 return null; 17540 } 17541 } 17542 } 17543} 17544