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