ActivityManagerService.java revision 4451419fc675e02acd6df2664e6c4eafcca9c261
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 20import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21import static com.android.internal.util.XmlUtils.readBooleanAttribute; 22import static com.android.internal.util.XmlUtils.readIntAttribute; 23import static com.android.internal.util.XmlUtils.readLongAttribute; 24import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 25import static com.android.internal.util.XmlUtils.writeIntAttribute; 26import static com.android.internal.util.XmlUtils.writeLongAttribute; 27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 29import static org.xmlpull.v1.XmlPullParser.START_TAG; 30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 31 32import android.Manifest; 33import android.app.AppOpsManager; 34import android.app.IActivityContainer; 35import android.app.IActivityContainerCallback; 36import android.app.IAppTask; 37import android.app.admin.DevicePolicyManager; 38import android.appwidget.AppWidgetManager; 39import android.graphics.Rect; 40import android.os.BatteryStats; 41import android.os.PersistableBundle; 42import android.service.voice.IVoiceInteractionSession; 43import android.util.ArrayMap; 44 45import com.android.internal.R; 46import com.android.internal.annotations.GuardedBy; 47import com.android.internal.app.IAppOpsService; 48import com.android.internal.app.IVoiceInteractor; 49import com.android.internal.app.ProcessMap; 50import com.android.internal.app.ProcessStats; 51import com.android.internal.content.PackageMonitor; 52import com.android.internal.os.BackgroundThread; 53import com.android.internal.os.BatteryStatsImpl; 54import com.android.internal.os.ProcessCpuTracker; 55import com.android.internal.os.TransferPipe; 56import com.android.internal.os.Zygote; 57import com.android.internal.util.FastPrintWriter; 58import com.android.internal.util.FastXmlSerializer; 59import com.android.internal.util.MemInfoReader; 60import com.android.internal.util.Preconditions; 61import com.android.server.AppOpsService; 62import com.android.server.AttributeCache; 63import com.android.server.IntentResolver; 64import com.android.server.LocalServices; 65import com.android.server.ServiceThread; 66import com.android.server.SystemService; 67import com.android.server.SystemServiceManager; 68import com.android.server.Watchdog; 69import com.android.server.am.ActivityStack.ActivityState; 70import com.android.server.firewall.IntentFirewall; 71import com.android.server.pm.UserManagerService; 72import com.android.server.wm.AppTransition; 73import com.android.server.wm.WindowManagerService; 74import com.google.android.collect.Lists; 75import com.google.android.collect.Maps; 76 77import libcore.io.IoUtils; 78 79import org.xmlpull.v1.XmlPullParser; 80import org.xmlpull.v1.XmlPullParserException; 81import org.xmlpull.v1.XmlSerializer; 82 83import android.app.Activity; 84import android.app.ActivityManager; 85import android.app.ActivityManager.RunningTaskInfo; 86import android.app.ActivityManager.StackInfo; 87import android.app.ActivityManagerInternal; 88import android.app.ActivityManagerNative; 89import android.app.ActivityOptions; 90import android.app.ActivityThread; 91import android.app.AlertDialog; 92import android.app.AppGlobals; 93import android.app.ApplicationErrorReport; 94import android.app.Dialog; 95import android.app.IActivityController; 96import android.app.IApplicationThread; 97import android.app.IInstrumentationWatcher; 98import android.app.INotificationManager; 99import android.app.IProcessObserver; 100import android.app.IServiceConnection; 101import android.app.IStopUserCallback; 102import android.app.IUiAutomationConnection; 103import android.app.IUserSwitchObserver; 104import android.app.Instrumentation; 105import android.app.Notification; 106import android.app.NotificationManager; 107import android.app.PendingIntent; 108import android.app.backup.IBackupManager; 109import android.content.ActivityNotFoundException; 110import android.content.BroadcastReceiver; 111import android.content.ClipData; 112import android.content.ComponentCallbacks2; 113import android.content.ComponentName; 114import android.content.ContentProvider; 115import android.content.ContentResolver; 116import android.content.Context; 117import android.content.DialogInterface; 118import android.content.IContentProvider; 119import android.content.IIntentReceiver; 120import android.content.IIntentSender; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.pm.ActivityInfo; 125import android.content.pm.ApplicationInfo; 126import android.content.pm.ConfigurationInfo; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageManager; 129import android.content.pm.InstrumentationInfo; 130import android.content.pm.PackageInfo; 131import android.content.pm.PackageManager; 132import android.content.pm.ParceledListSlice; 133import android.content.pm.UserInfo; 134import android.content.pm.PackageManager.NameNotFoundException; 135import android.content.pm.PathPermission; 136import android.content.pm.ProviderInfo; 137import android.content.pm.ResolveInfo; 138import android.content.pm.ServiceInfo; 139import android.content.res.CompatibilityInfo; 140import android.content.res.Configuration; 141import android.graphics.Bitmap; 142import android.net.Proxy; 143import android.net.ProxyInfo; 144import android.net.Uri; 145import android.os.Binder; 146import android.os.Build; 147import android.os.Bundle; 148import android.os.Debug; 149import android.os.DropBoxManager; 150import android.os.Environment; 151import android.os.FactoryTest; 152import android.os.FileObserver; 153import android.os.FileUtils; 154import android.os.Handler; 155import android.os.IBinder; 156import android.os.IPermissionController; 157import android.os.IRemoteCallback; 158import android.os.IUserManager; 159import android.os.Looper; 160import android.os.Message; 161import android.os.Parcel; 162import android.os.ParcelFileDescriptor; 163import android.os.Process; 164import android.os.RemoteCallbackList; 165import android.os.RemoteException; 166import android.os.SELinux; 167import android.os.ServiceManager; 168import android.os.StrictMode; 169import android.os.SystemClock; 170import android.os.SystemProperties; 171import android.os.UpdateLock; 172import android.os.UserHandle; 173import android.provider.Settings; 174import android.text.format.DateUtils; 175import android.text.format.Time; 176import android.util.AtomicFile; 177import android.util.EventLog; 178import android.util.Log; 179import android.util.Pair; 180import android.util.PrintWriterPrinter; 181import android.util.Slog; 182import android.util.SparseArray; 183import android.util.TimeUtils; 184import android.util.Xml; 185import android.view.Gravity; 186import android.view.LayoutInflater; 187import android.view.View; 188import android.view.WindowManager; 189 190import java.io.BufferedInputStream; 191import java.io.BufferedOutputStream; 192import java.io.DataInputStream; 193import java.io.DataOutputStream; 194import java.io.File; 195import java.io.FileDescriptor; 196import java.io.FileInputStream; 197import java.io.FileNotFoundException; 198import java.io.FileOutputStream; 199import java.io.IOException; 200import java.io.InputStreamReader; 201import java.io.PrintWriter; 202import java.io.StringWriter; 203import java.lang.ref.WeakReference; 204import java.util.ArrayList; 205import java.util.Arrays; 206import java.util.Collections; 207import java.util.Comparator; 208import java.util.HashMap; 209import java.util.HashSet; 210import java.util.Iterator; 211import java.util.List; 212import java.util.Locale; 213import java.util.Map; 214import java.util.Set; 215import java.util.concurrent.atomic.AtomicBoolean; 216import java.util.concurrent.atomic.AtomicLong; 217 218public final class ActivityManagerService extends ActivityManagerNative 219 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 220 private static final String USER_DATA_DIR = "/data/user/"; 221 static final String TAG = "ActivityManager"; 222 static final String TAG_MU = "ActivityManagerServiceMU"; 223 static final boolean DEBUG = false; 224 static final boolean localLOGV = DEBUG; 225 static final boolean DEBUG_BACKUP = localLOGV || false; 226 static final boolean DEBUG_BROADCAST = localLOGV || false; 227 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 228 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 229 static final boolean DEBUG_CLEANUP = localLOGV || false; 230 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 231 static final boolean DEBUG_FOCUS = false; 232 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 233 static final boolean DEBUG_MU = localLOGV || false; 234 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 235 static final boolean DEBUG_LRU = localLOGV || false; 236 static final boolean DEBUG_PAUSE = localLOGV || false; 237 static final boolean DEBUG_POWER = localLOGV || false; 238 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 239 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 240 static final boolean DEBUG_PROCESSES = localLOGV || false; 241 static final boolean DEBUG_PROVIDER = localLOGV || false; 242 static final boolean DEBUG_RESULTS = localLOGV || false; 243 static final boolean DEBUG_SERVICE = localLOGV || false; 244 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 245 static final boolean DEBUG_STACK = localLOGV || false; 246 static final boolean DEBUG_SWITCH = localLOGV || false; 247 static final boolean DEBUG_TASKS = localLOGV || false; 248 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 249 static final boolean DEBUG_TRANSITION = localLOGV || false; 250 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 251 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 252 static final boolean DEBUG_VISBILITY = localLOGV || false; 253 static final boolean DEBUG_PSS = localLOGV || false; 254 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 255 static final boolean VALIDATE_TOKENS = false; 256 static final boolean SHOW_ACTIVITY_START_TIME = true; 257 258 // Control over CPU and battery monitoring. 259 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 260 static final boolean MONITOR_CPU_USAGE = true; 261 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 262 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 263 static final boolean MONITOR_THREAD_CPU_USAGE = false; 264 265 // The flags that are set for all calls we make to the package manager. 266 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 267 268 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 269 270 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 271 272 // Maximum number of recent tasks that we can remember. 273 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 274 275 // Maximum number recent bitmaps to keep in memory. 276 static final int MAX_RECENT_BITMAPS = 5; 277 278 // Amount of time after a call to stopAppSwitches() during which we will 279 // prevent further untrusted switches from happening. 280 static final long APP_SWITCH_DELAY_TIME = 5*1000; 281 282 // How long we wait for a launched process to attach to the activity manager 283 // before we decide it's never going to come up for real. 284 static final int PROC_START_TIMEOUT = 10*1000; 285 286 // How long we wait for a launched process to attach to the activity manager 287 // before we decide it's never going to come up for real, when the process was 288 // started with a wrapper for instrumentation (such as Valgrind) because it 289 // could take much longer than usual. 290 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 291 292 // How long to wait after going idle before forcing apps to GC. 293 static final int GC_TIMEOUT = 5*1000; 294 295 // The minimum amount of time between successive GC requests for a process. 296 static final int GC_MIN_INTERVAL = 60*1000; 297 298 // The minimum amount of time between successive PSS requests for a process. 299 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 300 301 // The minimum amount of time between successive PSS requests for a process 302 // when the request is due to the memory state being lowered. 303 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 304 305 // The rate at which we check for apps using excessive power -- 15 mins. 306 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 307 308 // The minimum sample duration we will allow before deciding we have 309 // enough data on wake locks to start killing things. 310 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 311 312 // The minimum sample duration we will allow before deciding we have 313 // enough data on CPU usage to start killing things. 314 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 315 316 // How long we allow a receiver to run before giving up on it. 317 static final int BROADCAST_FG_TIMEOUT = 10*1000; 318 static final int BROADCAST_BG_TIMEOUT = 60*1000; 319 320 // How long we wait until we timeout on key dispatching. 321 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 322 323 // How long we wait until we timeout on key dispatching during instrumentation. 324 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 325 326 // Amount of time we wait for observers to handle a user switch before 327 // giving up on them and unfreezing the screen. 328 static final int USER_SWITCH_TIMEOUT = 2*1000; 329 330 // Maximum number of users we allow to be running at a time. 331 static final int MAX_RUNNING_USERS = 3; 332 333 // How long to wait in getAssistContextExtras for the activity and foreground services 334 // to respond with the result. 335 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 336 337 // Maximum number of persisted Uri grants a package is allowed 338 static final int MAX_PERSISTED_URI_GRANTS = 128; 339 340 static final int MY_PID = Process.myPid(); 341 342 static final String[] EMPTY_STRING_ARRAY = new String[0]; 343 344 // How many bytes to write into the dropbox log before truncating 345 static final int DROPBOX_MAX_SIZE = 256 * 1024; 346 347 /** All system services */ 348 SystemServiceManager mSystemServiceManager; 349 350 /** Run all ActivityStacks through this */ 351 ActivityStackSupervisor mStackSupervisor; 352 353 public IntentFirewall mIntentFirewall; 354 355 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 356 // default actuion automatically. Important for devices without direct input 357 // devices. 358 private boolean mShowDialogs = true; 359 360 /** 361 * Description of a request to start a new activity, which has been held 362 * due to app switches being disabled. 363 */ 364 static class PendingActivityLaunch { 365 final ActivityRecord r; 366 final ActivityRecord sourceRecord; 367 final int startFlags; 368 final ActivityStack stack; 369 370 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 371 int _startFlags, ActivityStack _stack) { 372 r = _r; 373 sourceRecord = _sourceRecord; 374 startFlags = _startFlags; 375 stack = _stack; 376 } 377 } 378 379 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 380 = new ArrayList<PendingActivityLaunch>(); 381 382 BroadcastQueue mFgBroadcastQueue; 383 BroadcastQueue mBgBroadcastQueue; 384 // Convenient for easy iteration over the queues. Foreground is first 385 // so that dispatch of foreground broadcasts gets precedence. 386 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 387 388 BroadcastQueue broadcastQueueForIntent(Intent intent) { 389 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 390 if (DEBUG_BACKGROUND_BROADCAST) { 391 Slog.i(TAG, "Broadcast intent " + intent + " on " 392 + (isFg ? "foreground" : "background") 393 + " queue"); 394 } 395 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 396 } 397 398 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 399 for (BroadcastQueue queue : mBroadcastQueues) { 400 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 401 if (r != null) { 402 return r; 403 } 404 } 405 return null; 406 } 407 408 /** 409 * Activity we have told the window manager to have key focus. 410 */ 411 ActivityRecord mFocusedActivity = null; 412 413 /** 414 * List of intents that were used to start the most recent tasks. 415 */ 416 ArrayList<TaskRecord> mRecentTasks; 417 418 public class PendingAssistExtras extends Binder implements Runnable { 419 public final ActivityRecord activity; 420 public boolean haveResult = false; 421 public Bundle result = null; 422 public PendingAssistExtras(ActivityRecord _activity) { 423 activity = _activity; 424 } 425 @Override 426 public void run() { 427 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 428 synchronized (this) { 429 haveResult = true; 430 notifyAll(); 431 } 432 } 433 } 434 435 final ArrayList<PendingAssistExtras> mPendingAssistExtras 436 = new ArrayList<PendingAssistExtras>(); 437 438 /** 439 * Process management. 440 */ 441 final ProcessList mProcessList = new ProcessList(); 442 443 /** 444 * All of the applications we currently have running organized by name. 445 * The keys are strings of the application package name (as 446 * returned by the package manager), and the keys are ApplicationRecord 447 * objects. 448 */ 449 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 450 451 /** 452 * Tracking long-term execution of processes to look for abuse and other 453 * bad app behavior. 454 */ 455 final ProcessStatsService mProcessStats; 456 457 /** 458 * The currently running isolated processes. 459 */ 460 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 461 462 /** 463 * Counter for assigning isolated process uids, to avoid frequently reusing the 464 * same ones. 465 */ 466 int mNextIsolatedProcessUid = 0; 467 468 /** 469 * The currently running heavy-weight process, if any. 470 */ 471 ProcessRecord mHeavyWeightProcess = null; 472 473 /** 474 * The last time that various processes have crashed. 475 */ 476 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 477 478 /** 479 * Information about a process that is currently marked as bad. 480 */ 481 static final class BadProcessInfo { 482 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 483 this.time = time; 484 this.shortMsg = shortMsg; 485 this.longMsg = longMsg; 486 this.stack = stack; 487 } 488 489 final long time; 490 final String shortMsg; 491 final String longMsg; 492 final String stack; 493 } 494 495 /** 496 * Set of applications that we consider to be bad, and will reject 497 * incoming broadcasts from (which the user has no control over). 498 * Processes are added to this set when they have crashed twice within 499 * a minimum amount of time; they are removed from it when they are 500 * later restarted (hopefully due to some user action). The value is the 501 * time it was added to the list. 502 */ 503 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 504 505 /** 506 * All of the processes we currently have running organized by pid. 507 * The keys are the pid running the application. 508 * 509 * <p>NOTE: This object is protected by its own lock, NOT the global 510 * activity manager lock! 511 */ 512 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 513 514 /** 515 * All of the processes that have been forced to be foreground. The key 516 * is the pid of the caller who requested it (we hold a death 517 * link on it). 518 */ 519 abstract class ForegroundToken implements IBinder.DeathRecipient { 520 int pid; 521 IBinder token; 522 } 523 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 524 525 /** 526 * List of records for processes that someone had tried to start before the 527 * system was ready. We don't start them at that point, but ensure they 528 * are started by the time booting is complete. 529 */ 530 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 531 532 /** 533 * List of persistent applications that are in the process 534 * of being started. 535 */ 536 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * Processes that are being forcibly torn down. 540 */ 541 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * List of running applications, sorted by recent usage. 545 * The first entry in the list is the least recently used. 546 */ 547 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 548 549 /** 550 * Where in mLruProcesses that the processes hosting activities start. 551 */ 552 int mLruProcessActivityStart = 0; 553 554 /** 555 * Where in mLruProcesses that the processes hosting services start. 556 * This is after (lower index) than mLruProcessesActivityStart. 557 */ 558 int mLruProcessServiceStart = 0; 559 560 /** 561 * List of processes that should gc as soon as things are idle. 562 */ 563 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Processes we want to collect PSS data from. 567 */ 568 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 569 570 /** 571 * Last time we requested PSS data of all processes. 572 */ 573 long mLastFullPssTime = SystemClock.uptimeMillis(); 574 575 /** 576 * If set, the next time we collect PSS data we should do a full collection 577 * with data from native processes and the kernel. 578 */ 579 boolean mFullPssPending = false; 580 581 /** 582 * This is the process holding what we currently consider to be 583 * the "home" activity. 584 */ 585 ProcessRecord mHomeProcess; 586 587 /** 588 * This is the process holding the activity the user last visited that 589 * is in a different process from the one they are currently in. 590 */ 591 ProcessRecord mPreviousProcess; 592 593 /** 594 * The time at which the previous process was last visible. 595 */ 596 long mPreviousProcessVisibleTime; 597 598 /** 599 * Which uses have been started, so are allowed to run code. 600 */ 601 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 602 603 /** 604 * LRU list of history of current users. Most recently current is at the end. 605 */ 606 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 607 608 /** 609 * Constant array of the users that are currently started. 610 */ 611 int[] mStartedUserArray = new int[] { 0 }; 612 613 /** 614 * Registered observers of the user switching mechanics. 615 */ 616 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 617 = new RemoteCallbackList<IUserSwitchObserver>(); 618 619 /** 620 * Currently active user switch. 621 */ 622 Object mCurUserSwitchCallback; 623 624 /** 625 * Packages that the user has asked to have run in screen size 626 * compatibility mode instead of filling the screen. 627 */ 628 final CompatModePackages mCompatModePackages; 629 630 /** 631 * Set of IntentSenderRecord objects that are currently active. 632 */ 633 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 634 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 635 636 /** 637 * Fingerprints (hashCode()) of stack traces that we've 638 * already logged DropBox entries for. Guarded by itself. If 639 * something (rogue user app) forces this over 640 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 641 */ 642 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 643 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 644 645 /** 646 * Strict Mode background batched logging state. 647 * 648 * The string buffer is guarded by itself, and its lock is also 649 * used to determine if another batched write is already 650 * in-flight. 651 */ 652 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 653 654 /** 655 * Keeps track of all IIntentReceivers that have been registered for 656 * broadcasts. Hash keys are the receiver IBinder, hash value is 657 * a ReceiverList. 658 */ 659 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 660 new HashMap<IBinder, ReceiverList>(); 661 662 /** 663 * Resolver for broadcast intents to registered receivers. 664 * Holds BroadcastFilter (subclass of IntentFilter). 665 */ 666 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 667 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 668 @Override 669 protected boolean allowFilterResult( 670 BroadcastFilter filter, List<BroadcastFilter> dest) { 671 IBinder target = filter.receiverList.receiver.asBinder(); 672 for (int i=dest.size()-1; i>=0; i--) { 673 if (dest.get(i).receiverList.receiver.asBinder() == target) { 674 return false; 675 } 676 } 677 return true; 678 } 679 680 @Override 681 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 682 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 683 || userId == filter.owningUserId) { 684 return super.newResult(filter, match, userId); 685 } 686 return null; 687 } 688 689 @Override 690 protected BroadcastFilter[] newArray(int size) { 691 return new BroadcastFilter[size]; 692 } 693 694 @Override 695 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 696 return packageName.equals(filter.packageName); 697 } 698 }; 699 700 /** 701 * State of all active sticky broadcasts per user. Keys are the action of the 702 * sticky Intent, values are an ArrayList of all broadcasted intents with 703 * that action (which should usually be one). The SparseArray is keyed 704 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 705 * for stickies that are sent to all users. 706 */ 707 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 708 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 709 710 final ActiveServices mServices; 711 712 /** 713 * Backup/restore process management 714 */ 715 String mBackupAppName = null; 716 BackupRecord mBackupTarget = null; 717 718 final ProviderMap mProviderMap; 719 720 /** 721 * List of content providers who have clients waiting for them. The 722 * application is currently being launched and the provider will be 723 * removed from this list once it is published. 724 */ 725 final ArrayList<ContentProviderRecord> mLaunchingProviders 726 = new ArrayList<ContentProviderRecord>(); 727 728 /** 729 * File storing persisted {@link #mGrantedUriPermissions}. 730 */ 731 private final AtomicFile mGrantFile; 732 733 /** XML constants used in {@link #mGrantFile} */ 734 private static final String TAG_URI_GRANTS = "uri-grants"; 735 private static final String TAG_URI_GRANT = "uri-grant"; 736 private static final String ATTR_USER_HANDLE = "userHandle"; 737 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 738 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 739 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 740 private static final String ATTR_TARGET_PKG = "targetPkg"; 741 private static final String ATTR_URI = "uri"; 742 private static final String ATTR_MODE_FLAGS = "modeFlags"; 743 private static final String ATTR_CREATED_TIME = "createdTime"; 744 private static final String ATTR_PREFIX = "prefix"; 745 746 /** 747 * Global set of specific {@link Uri} permissions that have been granted. 748 * This optimized lookup structure maps from {@link UriPermission#targetUid} 749 * to {@link UriPermission#uri} to {@link UriPermission}. 750 */ 751 @GuardedBy("this") 752 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 753 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 754 755 public static class GrantUri { 756 public final int sourceUserId; 757 public final Uri uri; 758 public boolean prefix; 759 760 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 761 this.sourceUserId = sourceUserId; 762 this.uri = uri; 763 this.prefix = prefix; 764 } 765 766 @Override 767 public int hashCode() { 768 return toString().hashCode(); 769 } 770 771 @Override 772 public boolean equals(Object o) { 773 if (o instanceof GrantUri) { 774 GrantUri other = (GrantUri) o; 775 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 776 && prefix == other.prefix; 777 } 778 return false; 779 } 780 781 @Override 782 public String toString() { 783 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 784 if (prefix) result += " [prefix]"; 785 return result; 786 } 787 788 public String toSafeString() { 789 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 790 if (prefix) result += " [prefix]"; 791 return result; 792 } 793 794 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 795 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 796 ContentProvider.getUriWithoutUserId(uri), false); 797 } 798 } 799 800 CoreSettingsObserver mCoreSettingsObserver; 801 802 /** 803 * Thread-local storage used to carry caller permissions over through 804 * indirect content-provider access. 805 */ 806 private class Identity { 807 public int pid; 808 public int uid; 809 810 Identity(int _pid, int _uid) { 811 pid = _pid; 812 uid = _uid; 813 } 814 } 815 816 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 817 818 /** 819 * All information we have collected about the runtime performance of 820 * any user id that can impact battery performance. 821 */ 822 final BatteryStatsService mBatteryStatsService; 823 824 /** 825 * Information about component usage 826 */ 827 final UsageStatsService mUsageStatsService; 828 829 /** 830 * Information about and control over application operations 831 */ 832 final AppOpsService mAppOpsService; 833 834 /** 835 * Save recent tasks information across reboots. 836 */ 837 final TaskPersister mTaskPersister; 838 839 /** 840 * Current configuration information. HistoryRecord objects are given 841 * a reference to this object to indicate which configuration they are 842 * currently running in, so this object must be kept immutable. 843 */ 844 Configuration mConfiguration = new Configuration(); 845 846 /** 847 * Current sequencing integer of the configuration, for skipping old 848 * configurations. 849 */ 850 int mConfigurationSeq = 0; 851 852 /** 853 * Hardware-reported OpenGLES version. 854 */ 855 final int GL_ES_VERSION; 856 857 /** 858 * List of initialization arguments to pass to all processes when binding applications to them. 859 * For example, references to the commonly used services. 860 */ 861 HashMap<String, IBinder> mAppBindArgs; 862 863 /** 864 * Temporary to avoid allocations. Protected by main lock. 865 */ 866 final StringBuilder mStringBuilder = new StringBuilder(256); 867 868 /** 869 * Used to control how we initialize the service. 870 */ 871 ComponentName mTopComponent; 872 String mTopAction = Intent.ACTION_MAIN; 873 String mTopData; 874 boolean mProcessesReady = false; 875 boolean mSystemReady = false; 876 boolean mBooting = false; 877 boolean mWaitingUpdate = false; 878 boolean mDidUpdate = false; 879 boolean mOnBattery = false; 880 boolean mLaunchWarningShown = false; 881 882 Context mContext; 883 884 int mFactoryTest; 885 886 boolean mCheckedForSetup; 887 888 /** 889 * The time at which we will allow normal application switches again, 890 * after a call to {@link #stopAppSwitches()}. 891 */ 892 long mAppSwitchesAllowedTime; 893 894 /** 895 * This is set to true after the first switch after mAppSwitchesAllowedTime 896 * is set; any switches after that will clear the time. 897 */ 898 boolean mDidAppSwitch; 899 900 /** 901 * Last time (in realtime) at which we checked for power usage. 902 */ 903 long mLastPowerCheckRealtime; 904 905 /** 906 * Last time (in uptime) at which we checked for power usage. 907 */ 908 long mLastPowerCheckUptime; 909 910 /** 911 * Set while we are wanting to sleep, to prevent any 912 * activities from being started/resumed. 913 */ 914 private boolean mSleeping = false; 915 916 /** 917 * Set while we are running a voice interaction. This overrides 918 * sleeping while it is active. 919 */ 920 private boolean mRunningVoice = false; 921 922 /** 923 * State of external calls telling us if the device is asleep. 924 */ 925 private boolean mWentToSleep = false; 926 927 /** 928 * State of external call telling us if the lock screen is shown. 929 */ 930 private boolean mLockScreenShown = false; 931 932 /** 933 * Set if we are shutting down the system, similar to sleeping. 934 */ 935 boolean mShuttingDown = false; 936 937 /** 938 * Current sequence id for oom_adj computation traversal. 939 */ 940 int mAdjSeq = 0; 941 942 /** 943 * Current sequence id for process LRU updating. 944 */ 945 int mLruSeq = 0; 946 947 /** 948 * Keep track of the non-cached/empty process we last found, to help 949 * determine how to distribute cached/empty processes next time. 950 */ 951 int mNumNonCachedProcs = 0; 952 953 /** 954 * Keep track of the number of cached hidden procs, to balance oom adj 955 * distribution between those and empty procs. 956 */ 957 int mNumCachedHiddenProcs = 0; 958 959 /** 960 * Keep track of the number of service processes we last found, to 961 * determine on the next iteration which should be B services. 962 */ 963 int mNumServiceProcs = 0; 964 int mNewNumAServiceProcs = 0; 965 int mNewNumServiceProcs = 0; 966 967 /** 968 * Allow the current computed overall memory level of the system to go down? 969 * This is set to false when we are killing processes for reasons other than 970 * memory management, so that the now smaller process list will not be taken as 971 * an indication that memory is tighter. 972 */ 973 boolean mAllowLowerMemLevel = false; 974 975 /** 976 * The last computed memory level, for holding when we are in a state that 977 * processes are going away for other reasons. 978 */ 979 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 980 981 /** 982 * The last total number of process we have, to determine if changes actually look 983 * like a shrinking number of process due to lower RAM. 984 */ 985 int mLastNumProcesses; 986 987 /** 988 * The uptime of the last time we performed idle maintenance. 989 */ 990 long mLastIdleTime = SystemClock.uptimeMillis(); 991 992 /** 993 * Total time spent with RAM that has been added in the past since the last idle time. 994 */ 995 long mLowRamTimeSinceLastIdle = 0; 996 997 /** 998 * If RAM is currently low, when that horrible situation started. 999 */ 1000 long mLowRamStartTime = 0; 1001 1002 /** 1003 * For reporting to battery stats the current top application. 1004 */ 1005 private String mCurResumedPackage = null; 1006 private int mCurResumedUid = -1; 1007 1008 /** 1009 * For reporting to battery stats the apps currently running foreground 1010 * service. The ProcessMap is package/uid tuples; each of these contain 1011 * an array of the currently foreground processes. 1012 */ 1013 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1014 = new ProcessMap<ArrayList<ProcessRecord>>(); 1015 1016 /** 1017 * This is set if we had to do a delayed dexopt of an app before launching 1018 * it, to increase the ANR timeouts in that case. 1019 */ 1020 boolean mDidDexOpt; 1021 1022 /** 1023 * Set if the systemServer made a call to enterSafeMode. 1024 */ 1025 boolean mSafeMode; 1026 1027 String mDebugApp = null; 1028 boolean mWaitForDebugger = false; 1029 boolean mDebugTransient = false; 1030 String mOrigDebugApp = null; 1031 boolean mOrigWaitForDebugger = false; 1032 boolean mAlwaysFinishActivities = false; 1033 IActivityController mController = null; 1034 String mProfileApp = null; 1035 ProcessRecord mProfileProc = null; 1036 String mProfileFile; 1037 ParcelFileDescriptor mProfileFd; 1038 int mProfileType = 0; 1039 boolean mAutoStopProfiler = false; 1040 String mOpenGlTraceApp = null; 1041 1042 static class ProcessChangeItem { 1043 static final int CHANGE_ACTIVITIES = 1<<0; 1044 static final int CHANGE_PROCESS_STATE = 1<<1; 1045 int changes; 1046 int uid; 1047 int pid; 1048 int processState; 1049 boolean foregroundActivities; 1050 } 1051 1052 final RemoteCallbackList<IProcessObserver> mProcessObservers 1053 = new RemoteCallbackList<IProcessObserver>(); 1054 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1055 1056 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1057 = new ArrayList<ProcessChangeItem>(); 1058 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1059 = new ArrayList<ProcessChangeItem>(); 1060 1061 /** 1062 * Runtime CPU use collection thread. This object's lock is used to 1063 * protect all related state. 1064 */ 1065 final Thread mProcessCpuThread; 1066 1067 /** 1068 * Used to collect process stats when showing not responding dialog. 1069 * Protected by mProcessCpuThread. 1070 */ 1071 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1072 MONITOR_THREAD_CPU_USAGE); 1073 final AtomicLong mLastCpuTime = new AtomicLong(0); 1074 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1075 1076 long mLastWriteTime = 0; 1077 1078 /** 1079 * Used to retain an update lock when the foreground activity is in 1080 * immersive mode. 1081 */ 1082 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1083 1084 /** 1085 * Set to true after the system has finished booting. 1086 */ 1087 boolean mBooted = false; 1088 1089 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1090 int mProcessLimitOverride = -1; 1091 1092 WindowManagerService mWindowManager; 1093 1094 final ActivityThread mSystemThread; 1095 1096 int mCurrentUserId = 0; 1097 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1098 private UserManagerService mUserManager; 1099 1100 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1101 final ProcessRecord mApp; 1102 final int mPid; 1103 final IApplicationThread mAppThread; 1104 1105 AppDeathRecipient(ProcessRecord app, int pid, 1106 IApplicationThread thread) { 1107 if (localLOGV) Slog.v( 1108 TAG, "New death recipient " + this 1109 + " for thread " + thread.asBinder()); 1110 mApp = app; 1111 mPid = pid; 1112 mAppThread = thread; 1113 } 1114 1115 @Override 1116 public void binderDied() { 1117 if (localLOGV) Slog.v( 1118 TAG, "Death received in " + this 1119 + " for thread " + mAppThread.asBinder()); 1120 synchronized(ActivityManagerService.this) { 1121 appDiedLocked(mApp, mPid, mAppThread); 1122 } 1123 } 1124 } 1125 1126 static final int SHOW_ERROR_MSG = 1; 1127 static final int SHOW_NOT_RESPONDING_MSG = 2; 1128 static final int SHOW_FACTORY_ERROR_MSG = 3; 1129 static final int UPDATE_CONFIGURATION_MSG = 4; 1130 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1131 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1132 static final int SERVICE_TIMEOUT_MSG = 12; 1133 static final int UPDATE_TIME_ZONE = 13; 1134 static final int SHOW_UID_ERROR_MSG = 14; 1135 static final int IM_FEELING_LUCKY_MSG = 15; 1136 static final int PROC_START_TIMEOUT_MSG = 20; 1137 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1138 static final int KILL_APPLICATION_MSG = 22; 1139 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1140 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1141 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1142 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1143 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1144 static final int CLEAR_DNS_CACHE_MSG = 28; 1145 static final int UPDATE_HTTP_PROXY_MSG = 29; 1146 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1147 static final int DISPATCH_PROCESSES_CHANGED = 31; 1148 static final int DISPATCH_PROCESS_DIED = 32; 1149 static final int REPORT_MEM_USAGE_MSG = 33; 1150 static final int REPORT_USER_SWITCH_MSG = 34; 1151 static final int CONTINUE_USER_SWITCH_MSG = 35; 1152 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1153 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1154 static final int PERSIST_URI_GRANTS_MSG = 38; 1155 static final int REQUEST_ALL_PSS_MSG = 39; 1156 static final int START_PROFILES_MSG = 40; 1157 static final int UPDATE_TIME = 41; 1158 static final int SYSTEM_USER_START_MSG = 42; 1159 static final int SYSTEM_USER_CURRENT_MSG = 43; 1160 1161 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1162 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1163 static final int FIRST_COMPAT_MODE_MSG = 300; 1164 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1165 1166 AlertDialog mUidAlert; 1167 CompatModeDialog mCompatModeDialog; 1168 long mLastMemUsageReportTime = 0; 1169 1170 private LockToAppRequestDialog mLockToAppRequest; 1171 1172 /** 1173 * Flag whether the current user is a "monkey", i.e. whether 1174 * the UI is driven by a UI automation tool. 1175 */ 1176 private boolean mUserIsMonkey; 1177 1178 final ServiceThread mHandlerThread; 1179 final MainHandler mHandler; 1180 1181 final class MainHandler extends Handler { 1182 public MainHandler(Looper looper) { 1183 super(looper, null, true); 1184 } 1185 1186 @Override 1187 public void handleMessage(Message msg) { 1188 switch (msg.what) { 1189 case SHOW_ERROR_MSG: { 1190 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1191 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1192 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1193 synchronized (ActivityManagerService.this) { 1194 ProcessRecord proc = (ProcessRecord)data.get("app"); 1195 AppErrorResult res = (AppErrorResult) data.get("result"); 1196 if (proc != null && proc.crashDialog != null) { 1197 Slog.e(TAG, "App already has crash dialog: " + proc); 1198 if (res != null) { 1199 res.set(0); 1200 } 1201 return; 1202 } 1203 if (!showBackground && UserHandle.getAppId(proc.uid) 1204 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1205 && proc.pid != MY_PID) { 1206 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1207 if (res != null) { 1208 res.set(0); 1209 } 1210 return; 1211 } 1212 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1213 Dialog d = new AppErrorDialog(mContext, 1214 ActivityManagerService.this, res, proc); 1215 d.show(); 1216 proc.crashDialog = d; 1217 } else { 1218 // The device is asleep, so just pretend that the user 1219 // saw a crash dialog and hit "force quit". 1220 if (res != null) { 1221 res.set(0); 1222 } 1223 } 1224 } 1225 1226 ensureBootCompleted(); 1227 } break; 1228 case SHOW_NOT_RESPONDING_MSG: { 1229 synchronized (ActivityManagerService.this) { 1230 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1231 ProcessRecord proc = (ProcessRecord)data.get("app"); 1232 if (proc != null && proc.anrDialog != null) { 1233 Slog.e(TAG, "App already has anr dialog: " + proc); 1234 return; 1235 } 1236 1237 Intent intent = new Intent("android.intent.action.ANR"); 1238 if (!mProcessesReady) { 1239 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1240 | Intent.FLAG_RECEIVER_FOREGROUND); 1241 } 1242 broadcastIntentLocked(null, null, intent, 1243 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1244 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1245 1246 if (mShowDialogs) { 1247 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1248 mContext, proc, (ActivityRecord)data.get("activity"), 1249 msg.arg1 != 0); 1250 d.show(); 1251 proc.anrDialog = d; 1252 } else { 1253 // Just kill the app if there is no dialog to be shown. 1254 killAppAtUsersRequest(proc, null); 1255 } 1256 } 1257 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1261 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1262 synchronized (ActivityManagerService.this) { 1263 ProcessRecord proc = (ProcessRecord) data.get("app"); 1264 if (proc == null) { 1265 Slog.e(TAG, "App not found when showing strict mode dialog."); 1266 break; 1267 } 1268 if (proc.crashDialog != null) { 1269 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1270 return; 1271 } 1272 AppErrorResult res = (AppErrorResult) data.get("result"); 1273 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1274 Dialog d = new StrictModeViolationDialog(mContext, 1275 ActivityManagerService.this, res, proc); 1276 d.show(); 1277 proc.crashDialog = d; 1278 } else { 1279 // The device is asleep, so just pretend that the user 1280 // saw a crash dialog and hit "force quit". 1281 res.set(0); 1282 } 1283 } 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_FACTORY_ERROR_MSG: { 1287 Dialog d = new FactoryErrorDialog( 1288 mContext, msg.getData().getCharSequence("msg")); 1289 d.show(); 1290 ensureBootCompleted(); 1291 } break; 1292 case UPDATE_CONFIGURATION_MSG: { 1293 final ContentResolver resolver = mContext.getContentResolver(); 1294 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1295 } break; 1296 case GC_BACKGROUND_PROCESSES_MSG: { 1297 synchronized (ActivityManagerService.this) { 1298 performAppGcsIfAppropriateLocked(); 1299 } 1300 } break; 1301 case WAIT_FOR_DEBUGGER_MSG: { 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord app = (ProcessRecord)msg.obj; 1304 if (msg.arg1 != 0) { 1305 if (!app.waitedForDebugger) { 1306 Dialog d = new AppWaitingForDebuggerDialog( 1307 ActivityManagerService.this, 1308 mContext, app); 1309 app.waitDialog = d; 1310 app.waitedForDebugger = true; 1311 d.show(); 1312 } 1313 } else { 1314 if (app.waitDialog != null) { 1315 app.waitDialog.dismiss(); 1316 app.waitDialog = null; 1317 } 1318 } 1319 } 1320 } break; 1321 case SERVICE_TIMEOUT_MSG: { 1322 if (mDidDexOpt) { 1323 mDidDexOpt = false; 1324 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1325 nmsg.obj = msg.obj; 1326 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1327 return; 1328 } 1329 mServices.serviceTimeout((ProcessRecord)msg.obj); 1330 } break; 1331 case UPDATE_TIME_ZONE: { 1332 synchronized (ActivityManagerService.this) { 1333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1334 ProcessRecord r = mLruProcesses.get(i); 1335 if (r.thread != null) { 1336 try { 1337 r.thread.updateTimeZone(); 1338 } catch (RemoteException ex) { 1339 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1340 } 1341 } 1342 } 1343 } 1344 } break; 1345 case CLEAR_DNS_CACHE_MSG: { 1346 synchronized (ActivityManagerService.this) { 1347 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1348 ProcessRecord r = mLruProcesses.get(i); 1349 if (r.thread != null) { 1350 try { 1351 r.thread.clearDnsCache(); 1352 } catch (RemoteException ex) { 1353 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1354 } 1355 } 1356 } 1357 } 1358 } break; 1359 case UPDATE_HTTP_PROXY_MSG: { 1360 ProxyInfo proxy = (ProxyInfo)msg.obj; 1361 String host = ""; 1362 String port = ""; 1363 String exclList = ""; 1364 Uri pacFileUrl = Uri.EMPTY; 1365 if (proxy != null) { 1366 host = proxy.getHost(); 1367 port = Integer.toString(proxy.getPort()); 1368 exclList = proxy.getExclusionListAsString(); 1369 pacFileUrl = proxy.getPacFileUrl(); 1370 } 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update http proxy for: " + 1379 r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case SHOW_UID_ERROR_MSG: { 1386 String title = "System UIDs Inconsistent"; 1387 String text = "UIDs on the system are inconsistent, you need to wipe your" 1388 + " data partition or your device will be unstable."; 1389 Log.e(TAG, title + ": " + text); 1390 if (mShowDialogs) { 1391 // XXX This is a temporary dialog, no need to localize. 1392 AlertDialog d = new BaseErrorDialog(mContext); 1393 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1394 d.setCancelable(false); 1395 d.setTitle(title); 1396 d.setMessage(text); 1397 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1398 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1399 mUidAlert = d; 1400 d.show(); 1401 } 1402 } break; 1403 case IM_FEELING_LUCKY_MSG: { 1404 if (mUidAlert != null) { 1405 mUidAlert.dismiss(); 1406 mUidAlert = null; 1407 } 1408 } break; 1409 case PROC_START_TIMEOUT_MSG: { 1410 if (mDidDexOpt) { 1411 mDidDexOpt = false; 1412 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1413 nmsg.obj = msg.obj; 1414 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1415 return; 1416 } 1417 ProcessRecord app = (ProcessRecord)msg.obj; 1418 synchronized (ActivityManagerService.this) { 1419 processStartTimedOutLocked(app); 1420 } 1421 } break; 1422 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1423 synchronized (ActivityManagerService.this) { 1424 doPendingActivityLaunchesLocked(true); 1425 } 1426 } break; 1427 case KILL_APPLICATION_MSG: { 1428 synchronized (ActivityManagerService.this) { 1429 int appid = msg.arg1; 1430 boolean restart = (msg.arg2 == 1); 1431 Bundle bundle = (Bundle)msg.obj; 1432 String pkg = bundle.getString("pkg"); 1433 String reason = bundle.getString("reason"); 1434 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1435 false, UserHandle.USER_ALL, reason); 1436 } 1437 } break; 1438 case FINALIZE_PENDING_INTENT_MSG: { 1439 ((PendingIntentRecord)msg.obj).completeFinalize(); 1440 } break; 1441 case POST_HEAVY_NOTIFICATION_MSG: { 1442 INotificationManager inm = NotificationManager.getService(); 1443 if (inm == null) { 1444 return; 1445 } 1446 1447 ActivityRecord root = (ActivityRecord)msg.obj; 1448 ProcessRecord process = root.app; 1449 if (process == null) { 1450 return; 1451 } 1452 1453 try { 1454 Context context = mContext.createPackageContext(process.info.packageName, 0); 1455 String text = mContext.getString(R.string.heavy_weight_notification, 1456 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1457 Notification notification = new Notification(); 1458 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1459 notification.when = 0; 1460 notification.flags = Notification.FLAG_ONGOING_EVENT; 1461 notification.tickerText = text; 1462 notification.defaults = 0; // please be quiet 1463 notification.sound = null; 1464 notification.vibrate = null; 1465 notification.setLatestEventInfo(context, text, 1466 mContext.getText(R.string.heavy_weight_notification_detail), 1467 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1468 PendingIntent.FLAG_CANCEL_CURRENT, null, 1469 new UserHandle(root.userId))); 1470 1471 try { 1472 int[] outId = new int[1]; 1473 inm.enqueueNotificationWithTag("android", "android", null, 1474 R.string.heavy_weight_notification, 1475 notification, outId, root.userId); 1476 } catch (RuntimeException e) { 1477 Slog.w(ActivityManagerService.TAG, 1478 "Error showing notification for heavy-weight app", e); 1479 } catch (RemoteException e) { 1480 } 1481 } catch (NameNotFoundException e) { 1482 Slog.w(TAG, "Unable to create context for heavy notification", e); 1483 } 1484 } break; 1485 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1486 INotificationManager inm = NotificationManager.getService(); 1487 if (inm == null) { 1488 return; 1489 } 1490 try { 1491 inm.cancelNotificationWithTag("android", null, 1492 R.string.heavy_weight_notification, msg.arg1); 1493 } catch (RuntimeException e) { 1494 Slog.w(ActivityManagerService.TAG, 1495 "Error canceling notification for service", e); 1496 } catch (RemoteException e) { 1497 } 1498 } break; 1499 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1500 synchronized (ActivityManagerService.this) { 1501 checkExcessivePowerUsageLocked(true); 1502 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1503 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1504 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1505 } 1506 } break; 1507 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1508 synchronized (ActivityManagerService.this) { 1509 ActivityRecord ar = (ActivityRecord)msg.obj; 1510 if (mCompatModeDialog != null) { 1511 if (mCompatModeDialog.mAppInfo.packageName.equals( 1512 ar.info.applicationInfo.packageName)) { 1513 return; 1514 } 1515 mCompatModeDialog.dismiss(); 1516 mCompatModeDialog = null; 1517 } 1518 if (ar != null && false) { 1519 if (mCompatModePackages.getPackageAskCompatModeLocked( 1520 ar.packageName)) { 1521 int mode = mCompatModePackages.computeCompatModeLocked( 1522 ar.info.applicationInfo); 1523 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1524 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1525 mCompatModeDialog = new CompatModeDialog( 1526 ActivityManagerService.this, mContext, 1527 ar.info.applicationInfo); 1528 mCompatModeDialog.show(); 1529 } 1530 } 1531 } 1532 } 1533 break; 1534 } 1535 case DISPATCH_PROCESSES_CHANGED: { 1536 dispatchProcessesChanged(); 1537 break; 1538 } 1539 case DISPATCH_PROCESS_DIED: { 1540 final int pid = msg.arg1; 1541 final int uid = msg.arg2; 1542 dispatchProcessDied(pid, uid); 1543 break; 1544 } 1545 case REPORT_MEM_USAGE_MSG: { 1546 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1547 Thread thread = new Thread() { 1548 @Override public void run() { 1549 final SparseArray<ProcessMemInfo> infoMap 1550 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1551 for (int i=0, N=memInfos.size(); i<N; i++) { 1552 ProcessMemInfo mi = memInfos.get(i); 1553 infoMap.put(mi.pid, mi); 1554 } 1555 updateCpuStatsNow(); 1556 synchronized (mProcessCpuThread) { 1557 final int N = mProcessCpuTracker.countStats(); 1558 for (int i=0; i<N; i++) { 1559 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1560 if (st.vsize > 0) { 1561 long pss = Debug.getPss(st.pid, null); 1562 if (pss > 0) { 1563 if (infoMap.indexOfKey(st.pid) < 0) { 1564 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1565 ProcessList.NATIVE_ADJ, -1, "native", null); 1566 mi.pss = pss; 1567 memInfos.add(mi); 1568 } 1569 } 1570 } 1571 } 1572 } 1573 1574 long totalPss = 0; 1575 for (int i=0, N=memInfos.size(); i<N; i++) { 1576 ProcessMemInfo mi = memInfos.get(i); 1577 if (mi.pss == 0) { 1578 mi.pss = Debug.getPss(mi.pid, null); 1579 } 1580 totalPss += mi.pss; 1581 } 1582 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1583 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1584 if (lhs.oomAdj != rhs.oomAdj) { 1585 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1586 } 1587 if (lhs.pss != rhs.pss) { 1588 return lhs.pss < rhs.pss ? 1 : -1; 1589 } 1590 return 0; 1591 } 1592 }); 1593 1594 StringBuilder tag = new StringBuilder(128); 1595 StringBuilder stack = new StringBuilder(128); 1596 tag.append("Low on memory -- "); 1597 appendMemBucket(tag, totalPss, "total", false); 1598 appendMemBucket(stack, totalPss, "total", true); 1599 1600 StringBuilder logBuilder = new StringBuilder(1024); 1601 logBuilder.append("Low on memory:\n"); 1602 1603 boolean firstLine = true; 1604 int lastOomAdj = Integer.MIN_VALUE; 1605 for (int i=0, N=memInfos.size(); i<N; i++) { 1606 ProcessMemInfo mi = memInfos.get(i); 1607 1608 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1609 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1610 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1611 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1612 if (lastOomAdj != mi.oomAdj) { 1613 lastOomAdj = mi.oomAdj; 1614 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1615 tag.append(" / "); 1616 } 1617 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1618 if (firstLine) { 1619 stack.append(":"); 1620 firstLine = false; 1621 } 1622 stack.append("\n\t at "); 1623 } else { 1624 stack.append("$"); 1625 } 1626 } else { 1627 tag.append(" "); 1628 stack.append("$"); 1629 } 1630 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1631 appendMemBucket(tag, mi.pss, mi.name, false); 1632 } 1633 appendMemBucket(stack, mi.pss, mi.name, true); 1634 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1635 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1636 stack.append("("); 1637 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1638 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1639 stack.append(DUMP_MEM_OOM_LABEL[k]); 1640 stack.append(":"); 1641 stack.append(DUMP_MEM_OOM_ADJ[k]); 1642 } 1643 } 1644 stack.append(")"); 1645 } 1646 } 1647 1648 logBuilder.append(" "); 1649 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1650 logBuilder.append(' '); 1651 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1652 logBuilder.append(' '); 1653 ProcessList.appendRamKb(logBuilder, mi.pss); 1654 logBuilder.append(" kB: "); 1655 logBuilder.append(mi.name); 1656 logBuilder.append(" ("); 1657 logBuilder.append(mi.pid); 1658 logBuilder.append(") "); 1659 logBuilder.append(mi.adjType); 1660 logBuilder.append('\n'); 1661 if (mi.adjReason != null) { 1662 logBuilder.append(" "); 1663 logBuilder.append(mi.adjReason); 1664 logBuilder.append('\n'); 1665 } 1666 } 1667 1668 logBuilder.append(" "); 1669 ProcessList.appendRamKb(logBuilder, totalPss); 1670 logBuilder.append(" kB: TOTAL\n"); 1671 1672 long[] infos = new long[Debug.MEMINFO_COUNT]; 1673 Debug.getMemInfo(infos); 1674 logBuilder.append(" MemInfo: "); 1675 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1676 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1677 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1678 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1679 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1680 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1681 logBuilder.append(" ZRAM: "); 1682 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1683 logBuilder.append(" kB RAM, "); 1684 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1685 logBuilder.append(" kB swap total, "); 1686 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1687 logBuilder.append(" kB swap free\n"); 1688 } 1689 Slog.i(TAG, logBuilder.toString()); 1690 1691 StringBuilder dropBuilder = new StringBuilder(1024); 1692 /* 1693 StringWriter oomSw = new StringWriter(); 1694 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1695 StringWriter catSw = new StringWriter(); 1696 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1697 String[] emptyArgs = new String[] { }; 1698 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1699 oomPw.flush(); 1700 String oomString = oomSw.toString(); 1701 */ 1702 dropBuilder.append(stack); 1703 dropBuilder.append('\n'); 1704 dropBuilder.append('\n'); 1705 dropBuilder.append(logBuilder); 1706 dropBuilder.append('\n'); 1707 /* 1708 dropBuilder.append(oomString); 1709 dropBuilder.append('\n'); 1710 */ 1711 StringWriter catSw = new StringWriter(); 1712 synchronized (ActivityManagerService.this) { 1713 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1714 String[] emptyArgs = new String[] { }; 1715 catPw.println(); 1716 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1717 catPw.println(); 1718 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1719 false, false, null); 1720 catPw.println(); 1721 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1722 catPw.flush(); 1723 } 1724 dropBuilder.append(catSw.toString()); 1725 addErrorToDropBox("lowmem", null, "system_server", null, 1726 null, tag.toString(), dropBuilder.toString(), null, null); 1727 //Slog.i(TAG, "Sent to dropbox:"); 1728 //Slog.i(TAG, dropBuilder.toString()); 1729 synchronized (ActivityManagerService.this) { 1730 long now = SystemClock.uptimeMillis(); 1731 if (mLastMemUsageReportTime < now) { 1732 mLastMemUsageReportTime = now; 1733 } 1734 } 1735 } 1736 }; 1737 thread.start(); 1738 break; 1739 } 1740 case REPORT_USER_SWITCH_MSG: { 1741 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1742 break; 1743 } 1744 case CONTINUE_USER_SWITCH_MSG: { 1745 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1746 break; 1747 } 1748 case USER_SWITCH_TIMEOUT_MSG: { 1749 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1750 break; 1751 } 1752 case IMMERSIVE_MODE_LOCK_MSG: { 1753 final boolean nextState = (msg.arg1 != 0); 1754 if (mUpdateLock.isHeld() != nextState) { 1755 if (DEBUG_IMMERSIVE) { 1756 final ActivityRecord r = (ActivityRecord) msg.obj; 1757 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1758 } 1759 if (nextState) { 1760 mUpdateLock.acquire(); 1761 } else { 1762 mUpdateLock.release(); 1763 } 1764 } 1765 break; 1766 } 1767 case PERSIST_URI_GRANTS_MSG: { 1768 writeGrantedUriPermissions(); 1769 break; 1770 } 1771 case REQUEST_ALL_PSS_MSG: { 1772 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1773 break; 1774 } 1775 case START_PROFILES_MSG: { 1776 synchronized (ActivityManagerService.this) { 1777 startProfilesLocked(); 1778 } 1779 break; 1780 } 1781 case UPDATE_TIME: { 1782 synchronized (ActivityManagerService.this) { 1783 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1784 ProcessRecord r = mLruProcesses.get(i); 1785 if (r.thread != null) { 1786 try { 1787 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1788 } catch (RemoteException ex) { 1789 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1790 } 1791 } 1792 } 1793 } 1794 break; 1795 } 1796 case SYSTEM_USER_START_MSG: { 1797 mSystemServiceManager.startUser(msg.arg1); 1798 break; 1799 } 1800 case SYSTEM_USER_CURRENT_MSG: { 1801 mSystemServiceManager.switchUser(msg.arg1); 1802 break; 1803 } 1804 } 1805 } 1806 }; 1807 1808 static final int COLLECT_PSS_BG_MSG = 1; 1809 1810 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1811 @Override 1812 public void handleMessage(Message msg) { 1813 switch (msg.what) { 1814 case COLLECT_PSS_BG_MSG: { 1815 long start = SystemClock.uptimeMillis(); 1816 MemInfoReader memInfo = null; 1817 synchronized (ActivityManagerService.this) { 1818 if (mFullPssPending) { 1819 mFullPssPending = false; 1820 memInfo = new MemInfoReader(); 1821 } 1822 } 1823 if (memInfo != null) { 1824 updateCpuStatsNow(); 1825 long nativeTotalPss = 0; 1826 synchronized (mProcessCpuThread) { 1827 final int N = mProcessCpuTracker.countStats(); 1828 for (int j=0; j<N; j++) { 1829 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1830 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1831 // This is definitely an application process; skip it. 1832 continue; 1833 } 1834 synchronized (mPidsSelfLocked) { 1835 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1836 // This is one of our own processes; skip it. 1837 continue; 1838 } 1839 } 1840 nativeTotalPss += Debug.getPss(st.pid, null); 1841 } 1842 } 1843 memInfo.readMemInfo(); 1844 synchronized (this) { 1845 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1846 + (SystemClock.uptimeMillis()-start) + "ms"); 1847 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1848 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1849 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1850 +memInfo.getSlabSizeKb(), 1851 nativeTotalPss); 1852 } 1853 } 1854 1855 int i=0, num=0; 1856 long[] tmp = new long[1]; 1857 do { 1858 ProcessRecord proc; 1859 int procState; 1860 int pid; 1861 synchronized (ActivityManagerService.this) { 1862 if (i >= mPendingPssProcesses.size()) { 1863 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1864 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1865 mPendingPssProcesses.clear(); 1866 return; 1867 } 1868 proc = mPendingPssProcesses.get(i); 1869 procState = proc.pssProcState; 1870 if (proc.thread != null && procState == proc.setProcState) { 1871 pid = proc.pid; 1872 } else { 1873 proc = null; 1874 pid = 0; 1875 } 1876 i++; 1877 } 1878 if (proc != null) { 1879 long pss = Debug.getPss(pid, tmp); 1880 synchronized (ActivityManagerService.this) { 1881 if (proc.thread != null && proc.setProcState == procState 1882 && proc.pid == pid) { 1883 num++; 1884 proc.lastPssTime = SystemClock.uptimeMillis(); 1885 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1886 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1887 + ": " + pss + " lastPss=" + proc.lastPss 1888 + " state=" + ProcessList.makeProcStateString(procState)); 1889 if (proc.initialIdlePss == 0) { 1890 proc.initialIdlePss = pss; 1891 } 1892 proc.lastPss = pss; 1893 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1894 proc.lastCachedPss = pss; 1895 } 1896 } 1897 } 1898 } 1899 } while (true); 1900 } 1901 } 1902 } 1903 }; 1904 1905 /** 1906 * Monitor for package changes and update our internal state. 1907 */ 1908 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1909 @Override 1910 public void onPackageRemoved(String packageName, int uid) { 1911 // Remove all tasks with activities in the specified package from the list of recent tasks 1912 synchronized (ActivityManagerService.this) { 1913 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1914 TaskRecord tr = mRecentTasks.get(i); 1915 ComponentName cn = tr.intent.getComponent(); 1916 if (cn != null && cn.getPackageName().equals(packageName)) { 1917 // If the package name matches, remove the task and kill the process 1918 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1919 } 1920 } 1921 } 1922 } 1923 1924 @Override 1925 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1926 onPackageModified(packageName); 1927 return true; 1928 } 1929 1930 @Override 1931 public void onPackageModified(String packageName) { 1932 final PackageManager pm = mContext.getPackageManager(); 1933 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1934 new ArrayList<Pair<Intent, Integer>>(); 1935 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1936 // Copy the list of recent tasks so that we don't hold onto the lock on 1937 // ActivityManagerService for long periods while checking if components exist. 1938 synchronized (ActivityManagerService.this) { 1939 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1940 TaskRecord tr = mRecentTasks.get(i); 1941 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1942 } 1943 } 1944 // Check the recent tasks and filter out all tasks with components that no longer exist. 1945 Intent tmpI = new Intent(); 1946 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1947 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1948 ComponentName cn = p.first.getComponent(); 1949 if (cn != null && cn.getPackageName().equals(packageName)) { 1950 try { 1951 // Add the task to the list to remove if the component no longer exists 1952 tmpI.setComponent(cn); 1953 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1954 tasksToRemove.add(p.second); 1955 } 1956 } catch (Exception e) {} 1957 } 1958 } 1959 // Prune all the tasks with removed components from the list of recent tasks 1960 synchronized (ActivityManagerService.this) { 1961 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1962 // Remove the task but don't kill the process (since other components in that 1963 // package may still be running and in the background) 1964 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1965 } 1966 } 1967 } 1968 1969 @Override 1970 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1971 // Force stop the specified packages 1972 if (packages != null) { 1973 for (String pkg : packages) { 1974 synchronized (ActivityManagerService.this) { 1975 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1976 "finished booting")) { 1977 return true; 1978 } 1979 } 1980 } 1981 } 1982 return false; 1983 } 1984 }; 1985 1986 public void setSystemProcess() { 1987 try { 1988 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1989 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1990 ServiceManager.addService("meminfo", new MemBinder(this)); 1991 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1992 ServiceManager.addService("dbinfo", new DbBinder(this)); 1993 if (MONITOR_CPU_USAGE) { 1994 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1995 } 1996 ServiceManager.addService("permission", new PermissionController(this)); 1997 1998 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1999 "android", STOCK_PM_FLAGS); 2000 mSystemThread.installSystemApplicationInfo(info); 2001 2002 synchronized (this) { 2003 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2004 app.persistent = true; 2005 app.pid = MY_PID; 2006 app.maxAdj = ProcessList.SYSTEM_ADJ; 2007 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2008 mProcessNames.put(app.processName, app.uid, app); 2009 synchronized (mPidsSelfLocked) { 2010 mPidsSelfLocked.put(app.pid, app); 2011 } 2012 updateLruProcessLocked(app, false, null); 2013 updateOomAdjLocked(); 2014 } 2015 } catch (PackageManager.NameNotFoundException e) { 2016 throw new RuntimeException( 2017 "Unable to find android system package", e); 2018 } 2019 } 2020 2021 public void setWindowManager(WindowManagerService wm) { 2022 mWindowManager = wm; 2023 mStackSupervisor.setWindowManager(wm); 2024 } 2025 2026 public void startObservingNativeCrashes() { 2027 final NativeCrashListener ncl = new NativeCrashListener(this); 2028 ncl.start(); 2029 } 2030 2031 public IAppOpsService getAppOpsService() { 2032 return mAppOpsService; 2033 } 2034 2035 static class MemBinder extends Binder { 2036 ActivityManagerService mActivityManagerService; 2037 MemBinder(ActivityManagerService activityManagerService) { 2038 mActivityManagerService = activityManagerService; 2039 } 2040 2041 @Override 2042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2043 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2044 != PackageManager.PERMISSION_GRANTED) { 2045 pw.println("Permission Denial: can't dump meminfo from from pid=" 2046 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2047 + " without permission " + android.Manifest.permission.DUMP); 2048 return; 2049 } 2050 2051 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2052 } 2053 } 2054 2055 static class GraphicsBinder extends Binder { 2056 ActivityManagerService mActivityManagerService; 2057 GraphicsBinder(ActivityManagerService activityManagerService) { 2058 mActivityManagerService = activityManagerService; 2059 } 2060 2061 @Override 2062 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2063 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2064 != PackageManager.PERMISSION_GRANTED) { 2065 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2066 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2067 + " without permission " + android.Manifest.permission.DUMP); 2068 return; 2069 } 2070 2071 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2072 } 2073 } 2074 2075 static class DbBinder extends Binder { 2076 ActivityManagerService mActivityManagerService; 2077 DbBinder(ActivityManagerService activityManagerService) { 2078 mActivityManagerService = activityManagerService; 2079 } 2080 2081 @Override 2082 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2083 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2084 != PackageManager.PERMISSION_GRANTED) { 2085 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2086 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2087 + " without permission " + android.Manifest.permission.DUMP); 2088 return; 2089 } 2090 2091 mActivityManagerService.dumpDbInfo(fd, pw, args); 2092 } 2093 } 2094 2095 static class CpuBinder extends Binder { 2096 ActivityManagerService mActivityManagerService; 2097 CpuBinder(ActivityManagerService activityManagerService) { 2098 mActivityManagerService = activityManagerService; 2099 } 2100 2101 @Override 2102 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2103 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2104 != PackageManager.PERMISSION_GRANTED) { 2105 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2106 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2107 + " without permission " + android.Manifest.permission.DUMP); 2108 return; 2109 } 2110 2111 synchronized (mActivityManagerService.mProcessCpuThread) { 2112 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2113 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2114 SystemClock.uptimeMillis())); 2115 } 2116 } 2117 } 2118 2119 public static final class Lifecycle extends SystemService { 2120 private final ActivityManagerService mService; 2121 2122 public Lifecycle(Context context) { 2123 super(context); 2124 mService = new ActivityManagerService(context); 2125 } 2126 2127 @Override 2128 public void onStart() { 2129 mService.start(); 2130 } 2131 2132 public ActivityManagerService getService() { 2133 return mService; 2134 } 2135 } 2136 2137 // Note: This method is invoked on the main thread but may need to attach various 2138 // handlers to other threads. So take care to be explicit about the looper. 2139 public ActivityManagerService(Context systemContext) { 2140 mContext = systemContext; 2141 mFactoryTest = FactoryTest.getMode(); 2142 mSystemThread = ActivityThread.currentActivityThread(); 2143 2144 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2145 2146 mHandlerThread = new ServiceThread(TAG, 2147 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2148 mHandlerThread.start(); 2149 mHandler = new MainHandler(mHandlerThread.getLooper()); 2150 2151 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2152 "foreground", BROADCAST_FG_TIMEOUT, false); 2153 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2154 "background", BROADCAST_BG_TIMEOUT, true); 2155 mBroadcastQueues[0] = mFgBroadcastQueue; 2156 mBroadcastQueues[1] = mBgBroadcastQueue; 2157 2158 mServices = new ActiveServices(this); 2159 mProviderMap = new ProviderMap(this); 2160 2161 // TODO: Move creation of battery stats service outside of activity manager service. 2162 File dataDir = Environment.getDataDirectory(); 2163 File systemDir = new File(dataDir, "system"); 2164 systemDir.mkdirs(); 2165 mBatteryStatsService = new BatteryStatsService(new File( 2166 systemDir, "batterystats.bin").toString(), mHandler); 2167 mBatteryStatsService.getActiveStatistics().readLocked(); 2168 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2169 mOnBattery = DEBUG_POWER ? true 2170 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2171 mBatteryStatsService.getActiveStatistics().setCallback(this); 2172 2173 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2174 2175 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2176 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2177 2178 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2179 2180 // User 0 is the first and only user that runs at boot. 2181 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2182 mUserLru.add(Integer.valueOf(0)); 2183 updateStartedUserArrayLocked(); 2184 2185 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2186 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2187 2188 mConfiguration.setToDefaults(); 2189 mConfiguration.setLocale(Locale.getDefault()); 2190 2191 mConfigurationSeq = mConfiguration.seq = 1; 2192 mProcessCpuTracker.init(); 2193 2194 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2195 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2196 mStackSupervisor = new ActivityStackSupervisor(this); 2197 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2198 2199 mProcessCpuThread = new Thread("CpuTracker") { 2200 @Override 2201 public void run() { 2202 while (true) { 2203 try { 2204 try { 2205 synchronized(this) { 2206 final long now = SystemClock.uptimeMillis(); 2207 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2208 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2209 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2210 // + ", write delay=" + nextWriteDelay); 2211 if (nextWriteDelay < nextCpuDelay) { 2212 nextCpuDelay = nextWriteDelay; 2213 } 2214 if (nextCpuDelay > 0) { 2215 mProcessCpuMutexFree.set(true); 2216 this.wait(nextCpuDelay); 2217 } 2218 } 2219 } catch (InterruptedException e) { 2220 } 2221 updateCpuStatsNow(); 2222 } catch (Exception e) { 2223 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2224 } 2225 } 2226 } 2227 }; 2228 2229 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2230 2231 Watchdog.getInstance().addMonitor(this); 2232 Watchdog.getInstance().addThread(mHandler); 2233 } 2234 2235 public void setSystemServiceManager(SystemServiceManager mgr) { 2236 mSystemServiceManager = mgr; 2237 } 2238 2239 private void start() { 2240 mProcessCpuThread.start(); 2241 2242 mBatteryStatsService.publish(mContext); 2243 mUsageStatsService.publish(mContext); 2244 mAppOpsService.publish(mContext); 2245 Slog.d("AppOps", "AppOpsService published"); 2246 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2247 } 2248 2249 public void initPowerManagement() { 2250 mStackSupervisor.initPowerManagement(); 2251 mBatteryStatsService.initPowerManagement(); 2252 } 2253 2254 @Override 2255 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2256 throws RemoteException { 2257 if (code == SYSPROPS_TRANSACTION) { 2258 // We need to tell all apps about the system property change. 2259 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2260 synchronized(this) { 2261 final int NP = mProcessNames.getMap().size(); 2262 for (int ip=0; ip<NP; ip++) { 2263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2264 final int NA = apps.size(); 2265 for (int ia=0; ia<NA; ia++) { 2266 ProcessRecord app = apps.valueAt(ia); 2267 if (app.thread != null) { 2268 procs.add(app.thread.asBinder()); 2269 } 2270 } 2271 } 2272 } 2273 2274 int N = procs.size(); 2275 for (int i=0; i<N; i++) { 2276 Parcel data2 = Parcel.obtain(); 2277 try { 2278 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2279 } catch (RemoteException e) { 2280 } 2281 data2.recycle(); 2282 } 2283 } 2284 try { 2285 return super.onTransact(code, data, reply, flags); 2286 } catch (RuntimeException e) { 2287 // The activity manager only throws security exceptions, so let's 2288 // log all others. 2289 if (!(e instanceof SecurityException)) { 2290 Slog.wtf(TAG, "Activity Manager Crash", e); 2291 } 2292 throw e; 2293 } 2294 } 2295 2296 void updateCpuStats() { 2297 final long now = SystemClock.uptimeMillis(); 2298 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2299 return; 2300 } 2301 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2302 synchronized (mProcessCpuThread) { 2303 mProcessCpuThread.notify(); 2304 } 2305 } 2306 } 2307 2308 void updateCpuStatsNow() { 2309 synchronized (mProcessCpuThread) { 2310 mProcessCpuMutexFree.set(false); 2311 final long now = SystemClock.uptimeMillis(); 2312 boolean haveNewCpuStats = false; 2313 2314 if (MONITOR_CPU_USAGE && 2315 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2316 mLastCpuTime.set(now); 2317 haveNewCpuStats = true; 2318 mProcessCpuTracker.update(); 2319 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2320 //Slog.i(TAG, "Total CPU usage: " 2321 // + mProcessCpu.getTotalCpuPercent() + "%"); 2322 2323 // Slog the cpu usage if the property is set. 2324 if ("true".equals(SystemProperties.get("events.cpu"))) { 2325 int user = mProcessCpuTracker.getLastUserTime(); 2326 int system = mProcessCpuTracker.getLastSystemTime(); 2327 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2328 int irq = mProcessCpuTracker.getLastIrqTime(); 2329 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2330 int idle = mProcessCpuTracker.getLastIdleTime(); 2331 2332 int total = user + system + iowait + irq + softIrq + idle; 2333 if (total == 0) total = 1; 2334 2335 EventLog.writeEvent(EventLogTags.CPU, 2336 ((user+system+iowait+irq+softIrq) * 100) / total, 2337 (user * 100) / total, 2338 (system * 100) / total, 2339 (iowait * 100) / total, 2340 (irq * 100) / total, 2341 (softIrq * 100) / total); 2342 } 2343 } 2344 2345 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2346 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2347 synchronized(bstats) { 2348 synchronized(mPidsSelfLocked) { 2349 if (haveNewCpuStats) { 2350 if (mOnBattery) { 2351 int perc = bstats.startAddingCpuLocked(); 2352 int totalUTime = 0; 2353 int totalSTime = 0; 2354 final int N = mProcessCpuTracker.countStats(); 2355 for (int i=0; i<N; i++) { 2356 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2357 if (!st.working) { 2358 continue; 2359 } 2360 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2361 int otherUTime = (st.rel_utime*perc)/100; 2362 int otherSTime = (st.rel_stime*perc)/100; 2363 totalUTime += otherUTime; 2364 totalSTime += otherSTime; 2365 if (pr != null) { 2366 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2367 if (ps == null || !ps.isActive()) { 2368 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2369 pr.info.uid, pr.processName); 2370 } 2371 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2372 st.rel_stime-otherSTime); 2373 ps.addSpeedStepTimes(cpuSpeedTimes); 2374 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2375 } else { 2376 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2377 if (ps == null || !ps.isActive()) { 2378 st.batteryStats = ps = bstats.getProcessStatsLocked( 2379 bstats.mapUid(st.uid), st.name); 2380 } 2381 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2382 st.rel_stime-otherSTime); 2383 ps.addSpeedStepTimes(cpuSpeedTimes); 2384 } 2385 } 2386 bstats.finishAddingCpuLocked(perc, totalUTime, 2387 totalSTime, cpuSpeedTimes); 2388 } 2389 } 2390 } 2391 2392 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2393 mLastWriteTime = now; 2394 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2395 } 2396 } 2397 } 2398 } 2399 2400 @Override 2401 public void batteryNeedsCpuUpdate() { 2402 updateCpuStatsNow(); 2403 } 2404 2405 @Override 2406 public void batteryPowerChanged(boolean onBattery) { 2407 // When plugging in, update the CPU stats first before changing 2408 // the plug state. 2409 updateCpuStatsNow(); 2410 synchronized (this) { 2411 synchronized(mPidsSelfLocked) { 2412 mOnBattery = DEBUG_POWER ? true : onBattery; 2413 } 2414 } 2415 } 2416 2417 /** 2418 * Initialize the application bind args. These are passed to each 2419 * process when the bindApplication() IPC is sent to the process. They're 2420 * lazily setup to make sure the services are running when they're asked for. 2421 */ 2422 private HashMap<String, IBinder> getCommonServicesLocked() { 2423 if (mAppBindArgs == null) { 2424 mAppBindArgs = new HashMap<String, IBinder>(); 2425 2426 // Setup the application init args 2427 mAppBindArgs.put("package", ServiceManager.getService("package")); 2428 mAppBindArgs.put("window", ServiceManager.getService("window")); 2429 mAppBindArgs.put(Context.ALARM_SERVICE, 2430 ServiceManager.getService(Context.ALARM_SERVICE)); 2431 } 2432 return mAppBindArgs; 2433 } 2434 2435 final void setFocusedActivityLocked(ActivityRecord r) { 2436 if (mFocusedActivity != r) { 2437 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2438 mFocusedActivity = r; 2439 if (r.task != null && r.task.voiceInteractor != null) { 2440 startRunningVoiceLocked(); 2441 } else { 2442 finishRunningVoiceLocked(); 2443 } 2444 mStackSupervisor.setFocusedStack(r); 2445 if (r != null) { 2446 mWindowManager.setFocusedApp(r.appToken, true); 2447 } 2448 applyUpdateLockStateLocked(r); 2449 } 2450 } 2451 2452 final void clearFocusedActivity(ActivityRecord r) { 2453 if (mFocusedActivity == r) { 2454 mFocusedActivity = null; 2455 } 2456 } 2457 2458 @Override 2459 public void setFocusedStack(int stackId) { 2460 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2461 synchronized (ActivityManagerService.this) { 2462 ActivityStack stack = mStackSupervisor.getStack(stackId); 2463 if (stack != null) { 2464 ActivityRecord r = stack.topRunningActivityLocked(null); 2465 if (r != null) { 2466 setFocusedActivityLocked(r); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void notifyActivityDrawn(IBinder token) { 2474 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2475 synchronized (this) { 2476 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2477 if (r != null) { 2478 r.task.stack.notifyActivityDrawnLocked(r); 2479 } 2480 } 2481 } 2482 2483 final void applyUpdateLockStateLocked(ActivityRecord r) { 2484 // Modifications to the UpdateLock state are done on our handler, outside 2485 // the activity manager's locks. The new state is determined based on the 2486 // state *now* of the relevant activity record. The object is passed to 2487 // the handler solely for logging detail, not to be consulted/modified. 2488 final boolean nextState = r != null && r.immersive; 2489 mHandler.sendMessage( 2490 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2491 } 2492 2493 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2494 Message msg = Message.obtain(); 2495 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2496 msg.obj = r.task.askedCompatMode ? null : r; 2497 mHandler.sendMessage(msg); 2498 } 2499 2500 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2501 String what, Object obj, ProcessRecord srcApp) { 2502 app.lastActivityTime = now; 2503 2504 if (app.activities.size() > 0) { 2505 // Don't want to touch dependent processes that are hosting activities. 2506 return index; 2507 } 2508 2509 int lrui = mLruProcesses.lastIndexOf(app); 2510 if (lrui < 0) { 2511 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2512 + what + " " + obj + " from " + srcApp); 2513 return index; 2514 } 2515 2516 if (lrui >= index) { 2517 // Don't want to cause this to move dependent processes *back* in the 2518 // list as if they were less frequently used. 2519 return index; 2520 } 2521 2522 if (lrui >= mLruProcessActivityStart) { 2523 // Don't want to touch dependent processes that are hosting activities. 2524 return index; 2525 } 2526 2527 mLruProcesses.remove(lrui); 2528 if (index > 0) { 2529 index--; 2530 } 2531 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2532 + " in LRU list: " + app); 2533 mLruProcesses.add(index, app); 2534 return index; 2535 } 2536 2537 final void removeLruProcessLocked(ProcessRecord app) { 2538 int lrui = mLruProcesses.lastIndexOf(app); 2539 if (lrui >= 0) { 2540 if (lrui <= mLruProcessActivityStart) { 2541 mLruProcessActivityStart--; 2542 } 2543 if (lrui <= mLruProcessServiceStart) { 2544 mLruProcessServiceStart--; 2545 } 2546 mLruProcesses.remove(lrui); 2547 } 2548 } 2549 2550 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2551 ProcessRecord client) { 2552 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2553 || app.treatLikeActivity; 2554 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2555 if (!activityChange && hasActivity) { 2556 // The process has activities, so we are only allowing activity-based adjustments 2557 // to move it. It should be kept in the front of the list with other 2558 // processes that have activities, and we don't want those to change their 2559 // order except due to activity operations. 2560 return; 2561 } 2562 2563 mLruSeq++; 2564 final long now = SystemClock.uptimeMillis(); 2565 app.lastActivityTime = now; 2566 2567 // First a quick reject: if the app is already at the position we will 2568 // put it, then there is nothing to do. 2569 if (hasActivity) { 2570 final int N = mLruProcesses.size(); 2571 if (N > 0 && mLruProcesses.get(N-1) == app) { 2572 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2573 return; 2574 } 2575 } else { 2576 if (mLruProcessServiceStart > 0 2577 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2579 return; 2580 } 2581 } 2582 2583 int lrui = mLruProcesses.lastIndexOf(app); 2584 2585 if (app.persistent && lrui >= 0) { 2586 // We don't care about the position of persistent processes, as long as 2587 // they are in the list. 2588 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2589 return; 2590 } 2591 2592 /* In progress: compute new position first, so we can avoid doing work 2593 if the process is not actually going to move. Not yet working. 2594 int addIndex; 2595 int nextIndex; 2596 boolean inActivity = false, inService = false; 2597 if (hasActivity) { 2598 // Process has activities, put it at the very tipsy-top. 2599 addIndex = mLruProcesses.size(); 2600 nextIndex = mLruProcessServiceStart; 2601 inActivity = true; 2602 } else if (hasService) { 2603 // Process has services, put it at the top of the service list. 2604 addIndex = mLruProcessActivityStart; 2605 nextIndex = mLruProcessServiceStart; 2606 inActivity = true; 2607 inService = true; 2608 } else { 2609 // Process not otherwise of interest, it goes to the top of the non-service area. 2610 addIndex = mLruProcessServiceStart; 2611 if (client != null) { 2612 int clientIndex = mLruProcesses.lastIndexOf(client); 2613 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2614 + app); 2615 if (clientIndex >= 0 && addIndex > clientIndex) { 2616 addIndex = clientIndex; 2617 } 2618 } 2619 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2620 } 2621 2622 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2623 + mLruProcessActivityStart + "): " + app); 2624 */ 2625 2626 if (lrui >= 0) { 2627 if (lrui < mLruProcessActivityStart) { 2628 mLruProcessActivityStart--; 2629 } 2630 if (lrui < mLruProcessServiceStart) { 2631 mLruProcessServiceStart--; 2632 } 2633 /* 2634 if (addIndex > lrui) { 2635 addIndex--; 2636 } 2637 if (nextIndex > lrui) { 2638 nextIndex--; 2639 } 2640 */ 2641 mLruProcesses.remove(lrui); 2642 } 2643 2644 /* 2645 mLruProcesses.add(addIndex, app); 2646 if (inActivity) { 2647 mLruProcessActivityStart++; 2648 } 2649 if (inService) { 2650 mLruProcessActivityStart++; 2651 } 2652 */ 2653 2654 int nextIndex; 2655 if (hasActivity) { 2656 final int N = mLruProcesses.size(); 2657 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2658 // Process doesn't have activities, but has clients with 2659 // activities... move it up, but one below the top (the top 2660 // should always have a real activity). 2661 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2662 mLruProcesses.add(N-1, app); 2663 // To keep it from spamming the LRU list (by making a bunch of clients), 2664 // we will push down any other entries owned by the app. 2665 final int uid = app.info.uid; 2666 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2667 ProcessRecord subProc = mLruProcesses.get(i); 2668 if (subProc.info.uid == uid) { 2669 // We want to push this one down the list. If the process after 2670 // it is for the same uid, however, don't do so, because we don't 2671 // want them internally to be re-ordered. 2672 if (mLruProcesses.get(i-1).info.uid != uid) { 2673 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2674 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2675 ProcessRecord tmp = mLruProcesses.get(i); 2676 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2677 mLruProcesses.set(i-1, tmp); 2678 i--; 2679 } 2680 } else { 2681 // A gap, we can stop here. 2682 break; 2683 } 2684 } 2685 } else { 2686 // Process has activities, put it at the very tipsy-top. 2687 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2688 mLruProcesses.add(app); 2689 } 2690 nextIndex = mLruProcessServiceStart; 2691 } else if (hasService) { 2692 // Process has services, put it at the top of the service list. 2693 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2694 mLruProcesses.add(mLruProcessActivityStart, app); 2695 nextIndex = mLruProcessServiceStart; 2696 mLruProcessActivityStart++; 2697 } else { 2698 // Process not otherwise of interest, it goes to the top of the non-service area. 2699 int index = mLruProcessServiceStart; 2700 if (client != null) { 2701 // If there is a client, don't allow the process to be moved up higher 2702 // in the list than that client. 2703 int clientIndex = mLruProcesses.lastIndexOf(client); 2704 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2705 + " when updating " + app); 2706 if (clientIndex <= lrui) { 2707 // Don't allow the client index restriction to push it down farther in the 2708 // list than it already is. 2709 clientIndex = lrui; 2710 } 2711 if (clientIndex >= 0 && index > clientIndex) { 2712 index = clientIndex; 2713 } 2714 } 2715 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2716 mLruProcesses.add(index, app); 2717 nextIndex = index-1; 2718 mLruProcessActivityStart++; 2719 mLruProcessServiceStart++; 2720 } 2721 2722 // If the app is currently using a content provider or service, 2723 // bump those processes as well. 2724 for (int j=app.connections.size()-1; j>=0; j--) { 2725 ConnectionRecord cr = app.connections.valueAt(j); 2726 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2727 && cr.binding.service.app != null 2728 && cr.binding.service.app.lruSeq != mLruSeq 2729 && !cr.binding.service.app.persistent) { 2730 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2731 "service connection", cr, app); 2732 } 2733 } 2734 for (int j=app.conProviders.size()-1; j>=0; j--) { 2735 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2736 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2737 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2738 "provider reference", cpr, app); 2739 } 2740 } 2741 } 2742 2743 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2744 if (uid == Process.SYSTEM_UID) { 2745 // The system gets to run in any process. If there are multiple 2746 // processes with the same uid, just pick the first (this 2747 // should never happen). 2748 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2749 if (procs == null) return null; 2750 final int N = procs.size(); 2751 for (int i = 0; i < N; i++) { 2752 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2753 } 2754 } 2755 ProcessRecord proc = mProcessNames.get(processName, uid); 2756 if (false && proc != null && !keepIfLarge 2757 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2758 && proc.lastCachedPss >= 4000) { 2759 // Turn this condition on to cause killing to happen regularly, for testing. 2760 if (proc.baseProcessTracker != null) { 2761 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2762 } 2763 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2764 + "k from cached"); 2765 } else if (proc != null && !keepIfLarge 2766 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2767 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2768 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2769 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2770 if (proc.baseProcessTracker != null) { 2771 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2772 } 2773 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2774 + "k from cached"); 2775 } 2776 } 2777 return proc; 2778 } 2779 2780 void ensurePackageDexOpt(String packageName) { 2781 IPackageManager pm = AppGlobals.getPackageManager(); 2782 try { 2783 if (pm.performDexOpt(packageName)) { 2784 mDidDexOpt = true; 2785 } 2786 } catch (RemoteException e) { 2787 } 2788 } 2789 2790 boolean isNextTransitionForward() { 2791 int transit = mWindowManager.getPendingAppTransition(); 2792 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2793 || transit == AppTransition.TRANSIT_TASK_OPEN 2794 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2795 } 2796 2797 final ProcessRecord startProcessLocked(String processName, 2798 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2799 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2800 boolean isolated, boolean keepIfLarge) { 2801 ProcessRecord app; 2802 if (!isolated) { 2803 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2804 } else { 2805 // If this is an isolated process, it can't re-use an existing process. 2806 app = null; 2807 } 2808 // We don't have to do anything more if: 2809 // (1) There is an existing application record; and 2810 // (2) The caller doesn't think it is dead, OR there is no thread 2811 // object attached to it so we know it couldn't have crashed; and 2812 // (3) There is a pid assigned to it, so it is either starting or 2813 // already running. 2814 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2815 + " app=" + app + " knownToBeDead=" + knownToBeDead 2816 + " thread=" + (app != null ? app.thread : null) 2817 + " pid=" + (app != null ? app.pid : -1)); 2818 if (app != null && app.pid > 0) { 2819 if (!knownToBeDead || app.thread == null) { 2820 // We already have the app running, or are waiting for it to 2821 // come up (we have a pid but not yet its thread), so keep it. 2822 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2823 // If this is a new package in the process, add the package to the list 2824 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2825 return app; 2826 } 2827 2828 // An application record is attached to a previous process, 2829 // clean it up now. 2830 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2831 handleAppDiedLocked(app, true, true); 2832 } 2833 2834 String hostingNameStr = hostingName != null 2835 ? hostingName.flattenToShortString() : null; 2836 2837 if (!isolated) { 2838 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2839 // If we are in the background, then check to see if this process 2840 // is bad. If so, we will just silently fail. 2841 if (mBadProcesses.get(info.processName, info.uid) != null) { 2842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2843 + "/" + info.processName); 2844 return null; 2845 } 2846 } else { 2847 // When the user is explicitly starting a process, then clear its 2848 // crash count so that we won't make it bad until they see at 2849 // least one crash dialog again, and make the process good again 2850 // if it had been bad. 2851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2852 + "/" + info.processName); 2853 mProcessCrashTimes.remove(info.processName, info.uid); 2854 if (mBadProcesses.get(info.processName, info.uid) != null) { 2855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2856 UserHandle.getUserId(info.uid), info.uid, 2857 info.processName); 2858 mBadProcesses.remove(info.processName, info.uid); 2859 if (app != null) { 2860 app.bad = false; 2861 } 2862 } 2863 } 2864 } 2865 2866 if (app == null) { 2867 app = newProcessRecordLocked(info, processName, isolated); 2868 if (app == null) { 2869 Slog.w(TAG, "Failed making new process record for " 2870 + processName + "/" + info.uid + " isolated=" + isolated); 2871 return null; 2872 } 2873 mProcessNames.put(processName, app.uid, app); 2874 if (isolated) { 2875 mIsolatedProcesses.put(app.uid, app); 2876 } 2877 } else { 2878 // If this is a new package in the process, add the package to the list 2879 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2880 } 2881 2882 // If the system is not ready yet, then hold off on starting this 2883 // process until it is. 2884 if (!mProcessesReady 2885 && !isAllowedWhileBooting(info) 2886 && !allowWhileBooting) { 2887 if (!mProcessesOnHold.contains(app)) { 2888 mProcessesOnHold.add(app); 2889 } 2890 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2891 return app; 2892 } 2893 2894 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2895 return (app.pid != 0) ? app : null; 2896 } 2897 2898 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2899 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2900 } 2901 2902 private final void startProcessLocked(ProcessRecord app, 2903 String hostingType, String hostingNameStr, String abiOverride) { 2904 if (app.pid > 0 && app.pid != MY_PID) { 2905 synchronized (mPidsSelfLocked) { 2906 mPidsSelfLocked.remove(app.pid); 2907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2908 } 2909 app.setPid(0); 2910 } 2911 2912 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2913 "startProcessLocked removing on hold: " + app); 2914 mProcessesOnHold.remove(app); 2915 2916 updateCpuStats(); 2917 2918 try { 2919 int uid = app.uid; 2920 2921 int[] gids = null; 2922 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2923 if (!app.isolated) { 2924 int[] permGids = null; 2925 try { 2926 final PackageManager pm = mContext.getPackageManager(); 2927 permGids = pm.getPackageGids(app.info.packageName); 2928 2929 if (Environment.isExternalStorageEmulated()) { 2930 if (pm.checkPermission( 2931 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2932 app.info.packageName) == PERMISSION_GRANTED) { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2934 } else { 2935 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2936 } 2937 } 2938 } catch (PackageManager.NameNotFoundException e) { 2939 Slog.w(TAG, "Unable to retrieve gids", e); 2940 } 2941 2942 /* 2943 * Add shared application and profile GIDs so applications can share some 2944 * resources like shared libraries and access user-wide resources 2945 */ 2946 if (permGids == null) { 2947 gids = new int[2]; 2948 } else { 2949 gids = new int[permGids.length + 2]; 2950 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2951 } 2952 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2953 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2954 } 2955 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2956 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2957 && mTopComponent != null 2958 && app.processName.equals(mTopComponent.getPackageName())) { 2959 uid = 0; 2960 } 2961 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2962 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2963 uid = 0; 2964 } 2965 } 2966 int debugFlags = 0; 2967 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2968 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2969 // Also turn on CheckJNI for debuggable apps. It's quite 2970 // awkward to turn on otherwise. 2971 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2972 } 2973 // Run the app in safe mode if its manifest requests so or the 2974 // system is booted in safe mode. 2975 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2976 mSafeMode == true) { 2977 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2978 } 2979 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2980 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2981 } 2982 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2983 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2984 } 2985 if ("1".equals(SystemProperties.get("debug.assert"))) { 2986 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2987 } 2988 2989 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2990 if (requiredAbi == null) { 2991 requiredAbi = Build.SUPPORTED_ABIS[0]; 2992 } 2993 2994 // Start the process. It will either succeed and return a result containing 2995 // the PID of the new process, or else throw a RuntimeException. 2996 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2997 app.processName, uid, uid, gids, debugFlags, mountExternal, 2998 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2999 3000 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 3001 synchronized (bs) { 3002 if (bs.isOnBattery()) { 3003 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 3004 } 3005 } 3006 3007 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3008 UserHandle.getUserId(uid), startResult.pid, uid, 3009 app.processName, hostingType, 3010 hostingNameStr != null ? hostingNameStr : ""); 3011 3012 if (app.persistent) { 3013 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3014 } 3015 3016 StringBuilder buf = mStringBuilder; 3017 buf.setLength(0); 3018 buf.append("Start proc "); 3019 buf.append(app.processName); 3020 buf.append(" for "); 3021 buf.append(hostingType); 3022 if (hostingNameStr != null) { 3023 buf.append(" "); 3024 buf.append(hostingNameStr); 3025 } 3026 buf.append(": pid="); 3027 buf.append(startResult.pid); 3028 buf.append(" uid="); 3029 buf.append(uid); 3030 buf.append(" gids={"); 3031 if (gids != null) { 3032 for (int gi=0; gi<gids.length; gi++) { 3033 if (gi != 0) buf.append(", "); 3034 buf.append(gids[gi]); 3035 3036 } 3037 } 3038 buf.append("}"); 3039 if (requiredAbi != null) { 3040 buf.append(" abi="); 3041 buf.append(requiredAbi); 3042 } 3043 Slog.i(TAG, buf.toString()); 3044 app.setPid(startResult.pid); 3045 app.usingWrapper = startResult.usingWrapper; 3046 app.removed = false; 3047 app.killedByAm = false; 3048 synchronized (mPidsSelfLocked) { 3049 this.mPidsSelfLocked.put(startResult.pid, app); 3050 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3051 msg.obj = app; 3052 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3053 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3054 } 3055 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3056 app.processName, app.info.uid); 3057 if (app.isolated) { 3058 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3059 } 3060 } catch (RuntimeException e) { 3061 // XXX do better error recovery. 3062 app.setPid(0); 3063 Slog.e(TAG, "Failure starting process " + app.processName, e); 3064 } 3065 } 3066 3067 void updateUsageStats(ActivityRecord component, boolean resumed) { 3068 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3069 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3070 if (resumed) { 3071 mUsageStatsService.noteResumeComponent(component.realActivity); 3072 synchronized (stats) { 3073 stats.noteActivityResumedLocked(component.app.uid); 3074 } 3075 } else { 3076 mUsageStatsService.notePauseComponent(component.realActivity); 3077 synchronized (stats) { 3078 stats.noteActivityPausedLocked(component.app.uid); 3079 } 3080 } 3081 } 3082 3083 Intent getHomeIntent() { 3084 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3085 intent.setComponent(mTopComponent); 3086 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3087 intent.addCategory(Intent.CATEGORY_HOME); 3088 } 3089 return intent; 3090 } 3091 3092 boolean startHomeActivityLocked(int userId) { 3093 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3094 && mTopAction == null) { 3095 // We are running in factory test mode, but unable to find 3096 // the factory test app, so just sit around displaying the 3097 // error message and don't try to start anything. 3098 return false; 3099 } 3100 Intent intent = getHomeIntent(); 3101 ActivityInfo aInfo = 3102 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3103 if (aInfo != null) { 3104 intent.setComponent(new ComponentName( 3105 aInfo.applicationInfo.packageName, aInfo.name)); 3106 // Don't do this if the home app is currently being 3107 // instrumented. 3108 aInfo = new ActivityInfo(aInfo); 3109 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3110 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3111 aInfo.applicationInfo.uid, true); 3112 if (app == null || app.instrumentationClass == null) { 3113 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3114 mStackSupervisor.startHomeActivity(intent, aInfo); 3115 } 3116 } 3117 3118 return true; 3119 } 3120 3121 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3122 ActivityInfo ai = null; 3123 ComponentName comp = intent.getComponent(); 3124 try { 3125 if (comp != null) { 3126 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3127 } else { 3128 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3129 intent, 3130 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3131 flags, userId); 3132 3133 if (info != null) { 3134 ai = info.activityInfo; 3135 } 3136 } 3137 } catch (RemoteException e) { 3138 // ignore 3139 } 3140 3141 return ai; 3142 } 3143 3144 /** 3145 * Starts the "new version setup screen" if appropriate. 3146 */ 3147 void startSetupActivityLocked() { 3148 // Only do this once per boot. 3149 if (mCheckedForSetup) { 3150 return; 3151 } 3152 3153 // We will show this screen if the current one is a different 3154 // version than the last one shown, and we are not running in 3155 // low-level factory test mode. 3156 final ContentResolver resolver = mContext.getContentResolver(); 3157 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3158 Settings.Global.getInt(resolver, 3159 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3160 mCheckedForSetup = true; 3161 3162 // See if we should be showing the platform update setup UI. 3163 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3164 List<ResolveInfo> ris = mContext.getPackageManager() 3165 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3166 3167 // We don't allow third party apps to replace this. 3168 ResolveInfo ri = null; 3169 for (int i=0; ris != null && i<ris.size(); i++) { 3170 if ((ris.get(i).activityInfo.applicationInfo.flags 3171 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3172 ri = ris.get(i); 3173 break; 3174 } 3175 } 3176 3177 if (ri != null) { 3178 String vers = ri.activityInfo.metaData != null 3179 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3180 : null; 3181 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3182 vers = ri.activityInfo.applicationInfo.metaData.getString( 3183 Intent.METADATA_SETUP_VERSION); 3184 } 3185 String lastVers = Settings.Secure.getString( 3186 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3187 if (vers != null && !vers.equals(lastVers)) { 3188 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3189 intent.setComponent(new ComponentName( 3190 ri.activityInfo.packageName, ri.activityInfo.name)); 3191 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3192 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3193 } 3194 } 3195 } 3196 } 3197 3198 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3199 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3200 } 3201 3202 void enforceNotIsolatedCaller(String caller) { 3203 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3204 throw new SecurityException("Isolated process not allowed to call " + caller); 3205 } 3206 } 3207 3208 @Override 3209 public int getFrontActivityScreenCompatMode() { 3210 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3211 synchronized (this) { 3212 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3213 } 3214 } 3215 3216 @Override 3217 public void setFrontActivityScreenCompatMode(int mode) { 3218 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3219 "setFrontActivityScreenCompatMode"); 3220 synchronized (this) { 3221 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3222 } 3223 } 3224 3225 @Override 3226 public int getPackageScreenCompatMode(String packageName) { 3227 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3228 synchronized (this) { 3229 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3230 } 3231 } 3232 3233 @Override 3234 public void setPackageScreenCompatMode(String packageName, int mode) { 3235 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3236 "setPackageScreenCompatMode"); 3237 synchronized (this) { 3238 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3239 } 3240 } 3241 3242 @Override 3243 public boolean getPackageAskScreenCompat(String packageName) { 3244 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3245 synchronized (this) { 3246 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3247 } 3248 } 3249 3250 @Override 3251 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3252 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3253 "setPackageAskScreenCompat"); 3254 synchronized (this) { 3255 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3256 } 3257 } 3258 3259 private void dispatchProcessesChanged() { 3260 int N; 3261 synchronized (this) { 3262 N = mPendingProcessChanges.size(); 3263 if (mActiveProcessChanges.length < N) { 3264 mActiveProcessChanges = new ProcessChangeItem[N]; 3265 } 3266 mPendingProcessChanges.toArray(mActiveProcessChanges); 3267 mAvailProcessChanges.addAll(mPendingProcessChanges); 3268 mPendingProcessChanges.clear(); 3269 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3270 } 3271 3272 int i = mProcessObservers.beginBroadcast(); 3273 while (i > 0) { 3274 i--; 3275 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3276 if (observer != null) { 3277 try { 3278 for (int j=0; j<N; j++) { 3279 ProcessChangeItem item = mActiveProcessChanges[j]; 3280 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3282 + item.pid + " uid=" + item.uid + ": " 3283 + item.foregroundActivities); 3284 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3285 item.foregroundActivities); 3286 } 3287 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3289 + item.pid + " uid=" + item.uid + ": " + item.processState); 3290 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3291 } 3292 } 3293 } catch (RemoteException e) { 3294 } 3295 } 3296 } 3297 mProcessObservers.finishBroadcast(); 3298 } 3299 3300 private void dispatchProcessDied(int pid, int uid) { 3301 int i = mProcessObservers.beginBroadcast(); 3302 while (i > 0) { 3303 i--; 3304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3305 if (observer != null) { 3306 try { 3307 observer.onProcessDied(pid, uid); 3308 } catch (RemoteException e) { 3309 } 3310 } 3311 } 3312 mProcessObservers.finishBroadcast(); 3313 } 3314 3315 final void doPendingActivityLaunchesLocked(boolean doResume) { 3316 final int N = mPendingActivityLaunches.size(); 3317 if (N <= 0) { 3318 return; 3319 } 3320 for (int i=0; i<N; i++) { 3321 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3322 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3323 doResume && i == (N-1), null); 3324 } 3325 mPendingActivityLaunches.clear(); 3326 } 3327 3328 @Override 3329 public final int startActivity(IApplicationThread caller, String callingPackage, 3330 Intent intent, String resolvedType, IBinder resultTo, 3331 String resultWho, int requestCode, int startFlags, 3332 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3333 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3334 resultWho, requestCode, 3335 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3336 } 3337 3338 @Override 3339 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3340 Intent intent, String resolvedType, IBinder resultTo, 3341 String resultWho, int requestCode, int startFlags, 3342 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3343 enforceNotIsolatedCaller("startActivity"); 3344 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3345 false, true, "startActivity", null); 3346 // TODO: Switch to user app stacks here. 3347 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3348 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3349 null, null, options, userId, null); 3350 } 3351 3352 @Override 3353 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, 3355 String resultWho, int requestCode, int startFlags, String profileFile, 3356 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3357 enforceNotIsolatedCaller("startActivityAndWait"); 3358 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3359 false, true, "startActivityAndWait", null); 3360 WaitResult res = new WaitResult(); 3361 // TODO: Switch to user app stacks here. 3362 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3363 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3364 res, null, options, UserHandle.getCallingUserId(), null); 3365 return res; 3366 } 3367 3368 @Override 3369 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3370 Intent intent, String resolvedType, IBinder resultTo, 3371 String resultWho, int requestCode, int startFlags, Configuration config, 3372 Bundle options, int userId) { 3373 enforceNotIsolatedCaller("startActivityWithConfig"); 3374 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3375 false, true, "startActivityWithConfig", null); 3376 // TODO: Switch to user app stacks here. 3377 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3378 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3379 null, null, null, config, options, userId, null); 3380 return ret; 3381 } 3382 3383 @Override 3384 public int startActivityIntentSender(IApplicationThread caller, 3385 IntentSender intent, Intent fillInIntent, String resolvedType, 3386 IBinder resultTo, String resultWho, int requestCode, 3387 int flagsMask, int flagsValues, Bundle options) { 3388 enforceNotIsolatedCaller("startActivityIntentSender"); 3389 // Refuse possible leaked file descriptors 3390 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3391 throw new IllegalArgumentException("File descriptors passed in Intent"); 3392 } 3393 3394 IIntentSender sender = intent.getTarget(); 3395 if (!(sender instanceof PendingIntentRecord)) { 3396 throw new IllegalArgumentException("Bad PendingIntent object"); 3397 } 3398 3399 PendingIntentRecord pir = (PendingIntentRecord)sender; 3400 3401 synchronized (this) { 3402 // If this is coming from the currently resumed activity, it is 3403 // effectively saying that app switches are allowed at this point. 3404 final ActivityStack stack = getFocusedStack(); 3405 if (stack.mResumedActivity != null && 3406 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3407 mAppSwitchesAllowedTime = 0; 3408 } 3409 } 3410 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3411 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3412 return ret; 3413 } 3414 3415 @Override 3416 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3417 Intent intent, String resolvedType, IVoiceInteractionSession session, 3418 IVoiceInteractor interactor, int startFlags, String profileFile, 3419 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3420 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3421 != PackageManager.PERMISSION_GRANTED) { 3422 String msg = "Permission Denial: startVoiceActivity() from pid=" 3423 + Binder.getCallingPid() 3424 + ", uid=" + Binder.getCallingUid() 3425 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3426 Slog.w(TAG, msg); 3427 throw new SecurityException(msg); 3428 } 3429 if (session == null || interactor == null) { 3430 throw new NullPointerException("null session or interactor"); 3431 } 3432 userId = handleIncomingUser(callingPid, callingUid, userId, 3433 false, true, "startVoiceActivity", null); 3434 // TODO: Switch to user app stacks here. 3435 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3436 resolvedType, session, interactor, null, null, 0, startFlags, 3437 profileFile, profileFd, null, null, options, userId, null); 3438 } 3439 3440 @Override 3441 public boolean startNextMatchingActivity(IBinder callingActivity, 3442 Intent intent, Bundle options) { 3443 // Refuse possible leaked file descriptors 3444 if (intent != null && intent.hasFileDescriptors() == true) { 3445 throw new IllegalArgumentException("File descriptors passed in Intent"); 3446 } 3447 3448 synchronized (this) { 3449 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3450 if (r == null) { 3451 ActivityOptions.abort(options); 3452 return false; 3453 } 3454 if (r.app == null || r.app.thread == null) { 3455 // The caller is not running... d'oh! 3456 ActivityOptions.abort(options); 3457 return false; 3458 } 3459 intent = new Intent(intent); 3460 // The caller is not allowed to change the data. 3461 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3462 // And we are resetting to find the next component... 3463 intent.setComponent(null); 3464 3465 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3466 3467 ActivityInfo aInfo = null; 3468 try { 3469 List<ResolveInfo> resolves = 3470 AppGlobals.getPackageManager().queryIntentActivities( 3471 intent, r.resolvedType, 3472 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3473 UserHandle.getCallingUserId()); 3474 3475 // Look for the original activity in the list... 3476 final int N = resolves != null ? resolves.size() : 0; 3477 for (int i=0; i<N; i++) { 3478 ResolveInfo rInfo = resolves.get(i); 3479 if (rInfo.activityInfo.packageName.equals(r.packageName) 3480 && rInfo.activityInfo.name.equals(r.info.name)) { 3481 // We found the current one... the next matching is 3482 // after it. 3483 i++; 3484 if (i<N) { 3485 aInfo = resolves.get(i).activityInfo; 3486 } 3487 if (debug) { 3488 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3489 + "/" + r.info.name); 3490 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3491 + "/" + aInfo.name); 3492 } 3493 break; 3494 } 3495 } 3496 } catch (RemoteException e) { 3497 } 3498 3499 if (aInfo == null) { 3500 // Nobody who is next! 3501 ActivityOptions.abort(options); 3502 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3503 return false; 3504 } 3505 3506 intent.setComponent(new ComponentName( 3507 aInfo.applicationInfo.packageName, aInfo.name)); 3508 intent.setFlags(intent.getFlags()&~( 3509 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3510 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3511 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3512 Intent.FLAG_ACTIVITY_NEW_TASK)); 3513 3514 // Okay now we need to start the new activity, replacing the 3515 // currently running activity. This is a little tricky because 3516 // we want to start the new one as if the current one is finished, 3517 // but not finish the current one first so that there is no flicker. 3518 // And thus... 3519 final boolean wasFinishing = r.finishing; 3520 r.finishing = true; 3521 3522 // Propagate reply information over to the new activity. 3523 final ActivityRecord resultTo = r.resultTo; 3524 final String resultWho = r.resultWho; 3525 final int requestCode = r.requestCode; 3526 r.resultTo = null; 3527 if (resultTo != null) { 3528 resultTo.removeResultsLocked(r, resultWho, requestCode); 3529 } 3530 3531 final long origId = Binder.clearCallingIdentity(); 3532 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3533 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3534 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3535 options, false, null, null); 3536 Binder.restoreCallingIdentity(origId); 3537 3538 r.finishing = wasFinishing; 3539 if (res != ActivityManager.START_SUCCESS) { 3540 return false; 3541 } 3542 return true; 3543 } 3544 } 3545 3546 final int startActivityInPackage(int uid, String callingPackage, 3547 Intent intent, String resolvedType, IBinder resultTo, 3548 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3549 IActivityContainer container) { 3550 3551 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3552 false, true, "startActivityInPackage", null); 3553 3554 // TODO: Switch to user app stacks here. 3555 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3556 null, null, resultTo, resultWho, requestCode, startFlags, 3557 null, null, null, null, options, userId, container); 3558 return ret; 3559 } 3560 3561 @Override 3562 public final int startActivities(IApplicationThread caller, String callingPackage, 3563 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3564 int userId) { 3565 enforceNotIsolatedCaller("startActivities"); 3566 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3567 false, true, "startActivity", null); 3568 // TODO: Switch to user app stacks here. 3569 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3570 resolvedTypes, resultTo, options, userId); 3571 return ret; 3572 } 3573 3574 final int startActivitiesInPackage(int uid, String callingPackage, 3575 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3576 Bundle options, int userId) { 3577 3578 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3579 false, true, "startActivityInPackage", null); 3580 // TODO: Switch to user app stacks here. 3581 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3582 resultTo, options, userId); 3583 return ret; 3584 } 3585 3586 final void addRecentTaskLocked(TaskRecord task) { 3587 int N = mRecentTasks.size(); 3588 // Quick case: check if the top-most recent task is the same. 3589 if (N > 0 && mRecentTasks.get(0) == task) { 3590 return; 3591 } 3592 // Another quick case: never add voice sessions. 3593 if (task.voiceSession != null) { 3594 return; 3595 } 3596 // Remove any existing entries that are the same kind of task. 3597 final Intent intent = task.intent; 3598 final boolean document = intent != null && intent.isDocument(); 3599 final ComponentName comp = intent.getComponent(); 3600 3601 int maxRecents = task.maxRecents - 1; 3602 for (int i=0; i<N; i++) { 3603 TaskRecord tr = mRecentTasks.get(i); 3604 if (task != tr) { 3605 if (task.userId != tr.userId) { 3606 continue; 3607 } 3608 if (i > MAX_RECENT_BITMAPS) { 3609 tr.freeLastThumbnail(); 3610 } 3611 final Intent trIntent = tr.intent; 3612 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3613 (intent == null || !intent.filterEquals(trIntent))) { 3614 continue; 3615 } 3616 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3617 if (document && trIsDocument) { 3618 // These are the same document activity (not necessarily the same doc). 3619 if (maxRecents > 0) { 3620 --maxRecents; 3621 continue; 3622 } 3623 // Hit the maximum number of documents for this task. Fall through 3624 // and remove this document from recents. 3625 } else if (document || trIsDocument) { 3626 // Only one of these is a document. Not the droid we're looking for. 3627 continue; 3628 } 3629 } 3630 3631 // Either task and tr are the same or, their affinities match or their intents match 3632 // and neither of them is a document, or they are documents using the same activity 3633 // and their maxRecents has been reached. 3634 tr.disposeThumbnail(); 3635 mRecentTasks.remove(i); 3636 i--; 3637 N--; 3638 if (task.intent == null) { 3639 // If the new recent task we are adding is not fully 3640 // specified, then replace it with the existing recent task. 3641 task = tr; 3642 } 3643 mTaskPersister.notify(tr, false); 3644 } 3645 if (N >= MAX_RECENT_TASKS) { 3646 mRecentTasks.remove(N-1).disposeThumbnail(); 3647 } 3648 mRecentTasks.add(0, task); 3649 } 3650 3651 @Override 3652 public void reportActivityFullyDrawn(IBinder token) { 3653 synchronized (this) { 3654 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3655 if (r == null) { 3656 return; 3657 } 3658 r.reportFullyDrawnLocked(); 3659 } 3660 } 3661 3662 @Override 3663 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3664 synchronized (this) { 3665 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3666 if (r == null) { 3667 return; 3668 } 3669 final long origId = Binder.clearCallingIdentity(); 3670 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3671 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3672 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3673 if (config != null) { 3674 r.frozenBeforeDestroy = true; 3675 if (!updateConfigurationLocked(config, r, false, false)) { 3676 mStackSupervisor.resumeTopActivitiesLocked(); 3677 } 3678 } 3679 Binder.restoreCallingIdentity(origId); 3680 } 3681 } 3682 3683 @Override 3684 public int getRequestedOrientation(IBinder token) { 3685 synchronized (this) { 3686 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3687 if (r == null) { 3688 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3689 } 3690 return mWindowManager.getAppOrientation(r.appToken); 3691 } 3692 } 3693 3694 /** 3695 * This is the internal entry point for handling Activity.finish(). 3696 * 3697 * @param token The Binder token referencing the Activity we want to finish. 3698 * @param resultCode Result code, if any, from this Activity. 3699 * @param resultData Result data (Intent), if any, from this Activity. 3700 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3701 * the root Activity in the task. 3702 * 3703 * @return Returns true if the activity successfully finished, or false if it is still running. 3704 */ 3705 @Override 3706 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3707 boolean finishTask) { 3708 // Refuse possible leaked file descriptors 3709 if (resultData != null && resultData.hasFileDescriptors() == true) { 3710 throw new IllegalArgumentException("File descriptors passed in Intent"); 3711 } 3712 3713 synchronized(this) { 3714 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3715 if (r == null) { 3716 return true; 3717 } 3718 // Keep track of the root activity of the task before we finish it 3719 TaskRecord tr = r.task; 3720 ActivityRecord rootR = tr.getRootActivity(); 3721 // Do not allow task to finish in Lock Task mode. 3722 if (tr == mStackSupervisor.mLockTaskModeTask) { 3723 if (rootR == r) { 3724 mStackSupervisor.showLockTaskToast(); 3725 return false; 3726 } 3727 } 3728 if (mController != null) { 3729 // Find the first activity that is not finishing. 3730 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3731 if (next != null) { 3732 // ask watcher if this is allowed 3733 boolean resumeOK = true; 3734 try { 3735 resumeOK = mController.activityResuming(next.packageName); 3736 } catch (RemoteException e) { 3737 mController = null; 3738 Watchdog.getInstance().setActivityController(null); 3739 } 3740 3741 if (!resumeOK) { 3742 return false; 3743 } 3744 } 3745 } 3746 final long origId = Binder.clearCallingIdentity(); 3747 try { 3748 boolean res; 3749 if (finishTask && r == rootR) { 3750 // If requested, remove the task that is associated to this activity only if it 3751 // was the root activity in the task. The result code and data is ignored because 3752 // we don't support returning them across task boundaries. 3753 res = removeTaskByIdLocked(tr.taskId, 0); 3754 } else { 3755 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3756 resultData, "app-request", true); 3757 } 3758 return res; 3759 } finally { 3760 Binder.restoreCallingIdentity(origId); 3761 } 3762 } 3763 } 3764 3765 @Override 3766 public final void finishHeavyWeightApp() { 3767 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3768 != PackageManager.PERMISSION_GRANTED) { 3769 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3770 + Binder.getCallingPid() 3771 + ", uid=" + Binder.getCallingUid() 3772 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3773 Slog.w(TAG, msg); 3774 throw new SecurityException(msg); 3775 } 3776 3777 synchronized(this) { 3778 if (mHeavyWeightProcess == null) { 3779 return; 3780 } 3781 3782 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3783 mHeavyWeightProcess.activities); 3784 for (int i=0; i<activities.size(); i++) { 3785 ActivityRecord r = activities.get(i); 3786 if (!r.finishing) { 3787 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3788 null, "finish-heavy", true); 3789 } 3790 } 3791 3792 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3793 mHeavyWeightProcess.userId, 0)); 3794 mHeavyWeightProcess = null; 3795 } 3796 } 3797 3798 @Override 3799 public void crashApplication(int uid, int initialPid, String packageName, 3800 String message) { 3801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3802 != PackageManager.PERMISSION_GRANTED) { 3803 String msg = "Permission Denial: crashApplication() from pid=" 3804 + Binder.getCallingPid() 3805 + ", uid=" + Binder.getCallingUid() 3806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3807 Slog.w(TAG, msg); 3808 throw new SecurityException(msg); 3809 } 3810 3811 synchronized(this) { 3812 ProcessRecord proc = null; 3813 3814 // Figure out which process to kill. We don't trust that initialPid 3815 // still has any relation to current pids, so must scan through the 3816 // list. 3817 synchronized (mPidsSelfLocked) { 3818 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3819 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3820 if (p.uid != uid) { 3821 continue; 3822 } 3823 if (p.pid == initialPid) { 3824 proc = p; 3825 break; 3826 } 3827 if (p.pkgList.containsKey(packageName)) { 3828 proc = p; 3829 } 3830 } 3831 } 3832 3833 if (proc == null) { 3834 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3835 + " initialPid=" + initialPid 3836 + " packageName=" + packageName); 3837 return; 3838 } 3839 3840 if (proc.thread != null) { 3841 if (proc.pid == Process.myPid()) { 3842 Log.w(TAG, "crashApplication: trying to crash self!"); 3843 return; 3844 } 3845 long ident = Binder.clearCallingIdentity(); 3846 try { 3847 proc.thread.scheduleCrash(message); 3848 } catch (RemoteException e) { 3849 } 3850 Binder.restoreCallingIdentity(ident); 3851 } 3852 } 3853 } 3854 3855 @Override 3856 public final void finishSubActivity(IBinder token, String resultWho, 3857 int requestCode) { 3858 synchronized(this) { 3859 final long origId = Binder.clearCallingIdentity(); 3860 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3861 if (r != null) { 3862 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3863 } 3864 Binder.restoreCallingIdentity(origId); 3865 } 3866 } 3867 3868 @Override 3869 public boolean finishActivityAffinity(IBinder token) { 3870 synchronized(this) { 3871 final long origId = Binder.clearCallingIdentity(); 3872 try { 3873 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3874 3875 ActivityRecord rootR = r.task.getRootActivity(); 3876 // Do not allow task to finish in Lock Task mode. 3877 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3878 if (rootR == r) { 3879 mStackSupervisor.showLockTaskToast(); 3880 return false; 3881 } 3882 } 3883 boolean res = false; 3884 if (r != null) { 3885 res = r.task.stack.finishActivityAffinityLocked(r); 3886 } 3887 return res; 3888 } finally { 3889 Binder.restoreCallingIdentity(origId); 3890 } 3891 } 3892 } 3893 3894 @Override 3895 public void finishVoiceTask(IVoiceInteractionSession session) { 3896 synchronized(this) { 3897 final long origId = Binder.clearCallingIdentity(); 3898 try { 3899 mStackSupervisor.finishVoiceTask(session); 3900 } finally { 3901 Binder.restoreCallingIdentity(origId); 3902 } 3903 } 3904 3905 } 3906 3907 @Override 3908 public boolean willActivityBeVisible(IBinder token) { 3909 synchronized(this) { 3910 ActivityStack stack = ActivityRecord.getStackLocked(token); 3911 if (stack != null) { 3912 return stack.willActivityBeVisibleLocked(token); 3913 } 3914 return false; 3915 } 3916 } 3917 3918 @Override 3919 public void overridePendingTransition(IBinder token, String packageName, 3920 int enterAnim, int exitAnim) { 3921 synchronized(this) { 3922 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3923 if (self == null) { 3924 return; 3925 } 3926 3927 final long origId = Binder.clearCallingIdentity(); 3928 3929 if (self.state == ActivityState.RESUMED 3930 || self.state == ActivityState.PAUSING) { 3931 mWindowManager.overridePendingAppTransition(packageName, 3932 enterAnim, exitAnim, null); 3933 } 3934 3935 Binder.restoreCallingIdentity(origId); 3936 } 3937 } 3938 3939 /** 3940 * Main function for removing an existing process from the activity manager 3941 * as a result of that process going away. Clears out all connections 3942 * to the process. 3943 */ 3944 private final void handleAppDiedLocked(ProcessRecord app, 3945 boolean restarting, boolean allowRestart) { 3946 int pid = app.pid; 3947 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3948 if (!restarting) { 3949 removeLruProcessLocked(app); 3950 if (pid > 0) { 3951 ProcessList.remove(pid); 3952 } 3953 } 3954 3955 if (mProfileProc == app) { 3956 clearProfilerLocked(); 3957 } 3958 3959 // Remove this application's activities from active lists. 3960 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3961 3962 app.activities.clear(); 3963 3964 if (app.instrumentationClass != null) { 3965 Slog.w(TAG, "Crash of app " + app.processName 3966 + " running instrumentation " + app.instrumentationClass); 3967 Bundle info = new Bundle(); 3968 info.putString("shortMsg", "Process crashed."); 3969 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3970 } 3971 3972 if (!restarting) { 3973 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3974 // If there was nothing to resume, and we are not already 3975 // restarting this process, but there is a visible activity that 3976 // is hosted by the process... then make sure all visible 3977 // activities are running, taking care of restarting this 3978 // process. 3979 if (hasVisibleActivities) { 3980 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3981 } 3982 } 3983 } 3984 } 3985 3986 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3987 IBinder threadBinder = thread.asBinder(); 3988 // Find the application record. 3989 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3990 ProcessRecord rec = mLruProcesses.get(i); 3991 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3992 return i; 3993 } 3994 } 3995 return -1; 3996 } 3997 3998 final ProcessRecord getRecordForAppLocked( 3999 IApplicationThread thread) { 4000 if (thread == null) { 4001 return null; 4002 } 4003 4004 int appIndex = getLRURecordIndexForAppLocked(thread); 4005 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4006 } 4007 4008 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4009 // If there are no longer any background processes running, 4010 // and the app that died was not running instrumentation, 4011 // then tell everyone we are now low on memory. 4012 boolean haveBg = false; 4013 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4014 ProcessRecord rec = mLruProcesses.get(i); 4015 if (rec.thread != null 4016 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4017 haveBg = true; 4018 break; 4019 } 4020 } 4021 4022 if (!haveBg) { 4023 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4024 if (doReport) { 4025 long now = SystemClock.uptimeMillis(); 4026 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4027 doReport = false; 4028 } else { 4029 mLastMemUsageReportTime = now; 4030 } 4031 } 4032 final ArrayList<ProcessMemInfo> memInfos 4033 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4034 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4035 long now = SystemClock.uptimeMillis(); 4036 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4037 ProcessRecord rec = mLruProcesses.get(i); 4038 if (rec == dyingProc || rec.thread == null) { 4039 continue; 4040 } 4041 if (doReport) { 4042 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4043 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4044 } 4045 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4046 // The low memory report is overriding any current 4047 // state for a GC request. Make sure to do 4048 // heavy/important/visible/foreground processes first. 4049 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4050 rec.lastRequestedGc = 0; 4051 } else { 4052 rec.lastRequestedGc = rec.lastLowMemory; 4053 } 4054 rec.reportLowMemory = true; 4055 rec.lastLowMemory = now; 4056 mProcessesToGc.remove(rec); 4057 addProcessToGcListLocked(rec); 4058 } 4059 } 4060 if (doReport) { 4061 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4062 mHandler.sendMessage(msg); 4063 } 4064 scheduleAppGcsLocked(); 4065 } 4066 } 4067 4068 final void appDiedLocked(ProcessRecord app, int pid, 4069 IApplicationThread thread) { 4070 4071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4072 synchronized (stats) { 4073 stats.noteProcessDiedLocked(app.info.uid, pid); 4074 } 4075 4076 // Clean up already done if the process has been re-started. 4077 if (app.pid == pid && app.thread != null && 4078 app.thread.asBinder() == thread.asBinder()) { 4079 boolean doLowMem = app.instrumentationClass == null; 4080 boolean doOomAdj = doLowMem; 4081 if (!app.killedByAm) { 4082 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4083 + ") has died."); 4084 mAllowLowerMemLevel = true; 4085 } else { 4086 // Note that we always want to do oom adj to update our state with the 4087 // new number of procs. 4088 mAllowLowerMemLevel = false; 4089 doLowMem = false; 4090 } 4091 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4092 if (DEBUG_CLEANUP) Slog.v( 4093 TAG, "Dying app: " + app + ", pid: " + pid 4094 + ", thread: " + thread.asBinder()); 4095 handleAppDiedLocked(app, false, true); 4096 4097 if (doOomAdj) { 4098 updateOomAdjLocked(); 4099 } 4100 if (doLowMem) { 4101 doLowMemReportIfNeededLocked(app); 4102 } 4103 } else if (app.pid != pid) { 4104 // A new process has already been started. 4105 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4106 + ") has died and restarted (pid " + app.pid + ")."); 4107 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4108 } else if (DEBUG_PROCESSES) { 4109 Slog.d(TAG, "Received spurious death notification for thread " 4110 + thread.asBinder()); 4111 } 4112 } 4113 4114 /** 4115 * If a stack trace dump file is configured, dump process stack traces. 4116 * @param clearTraces causes the dump file to be erased prior to the new 4117 * traces being written, if true; when false, the new traces will be 4118 * appended to any existing file content. 4119 * @param firstPids of dalvik VM processes to dump stack traces for first 4120 * @param lastPids of dalvik VM processes to dump stack traces for last 4121 * @param nativeProcs optional list of native process names to dump stack crawls 4122 * @return file containing stack traces, or null if no dump file is configured 4123 */ 4124 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4125 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4126 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4127 if (tracesPath == null || tracesPath.length() == 0) { 4128 return null; 4129 } 4130 4131 File tracesFile = new File(tracesPath); 4132 try { 4133 File tracesDir = tracesFile.getParentFile(); 4134 if (!tracesDir.exists()) { 4135 tracesFile.mkdirs(); 4136 if (!SELinux.restorecon(tracesDir)) { 4137 return null; 4138 } 4139 } 4140 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4141 4142 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4143 tracesFile.createNewFile(); 4144 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4145 } catch (IOException e) { 4146 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4147 return null; 4148 } 4149 4150 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4151 return tracesFile; 4152 } 4153 4154 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4155 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4156 // Use a FileObserver to detect when traces finish writing. 4157 // The order of traces is considered important to maintain for legibility. 4158 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4159 @Override 4160 public synchronized void onEvent(int event, String path) { notify(); } 4161 }; 4162 4163 try { 4164 observer.startWatching(); 4165 4166 // First collect all of the stacks of the most important pids. 4167 if (firstPids != null) { 4168 try { 4169 int num = firstPids.size(); 4170 for (int i = 0; i < num; i++) { 4171 synchronized (observer) { 4172 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4173 observer.wait(200); // Wait for write-close, give up after 200msec 4174 } 4175 } 4176 } catch (InterruptedException e) { 4177 Log.wtf(TAG, e); 4178 } 4179 } 4180 4181 // Next collect the stacks of the native pids 4182 if (nativeProcs != null) { 4183 int[] pids = Process.getPidsForCommands(nativeProcs); 4184 if (pids != null) { 4185 for (int pid : pids) { 4186 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4187 } 4188 } 4189 } 4190 4191 // Lastly, measure CPU usage. 4192 if (processCpuTracker != null) { 4193 processCpuTracker.init(); 4194 System.gc(); 4195 processCpuTracker.update(); 4196 try { 4197 synchronized (processCpuTracker) { 4198 processCpuTracker.wait(500); // measure over 1/2 second. 4199 } 4200 } catch (InterruptedException e) { 4201 } 4202 processCpuTracker.update(); 4203 4204 // We'll take the stack crawls of just the top apps using CPU. 4205 final int N = processCpuTracker.countWorkingStats(); 4206 int numProcs = 0; 4207 for (int i=0; i<N && numProcs<5; i++) { 4208 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4209 if (lastPids.indexOfKey(stats.pid) >= 0) { 4210 numProcs++; 4211 try { 4212 synchronized (observer) { 4213 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4214 observer.wait(200); // Wait for write-close, give up after 200msec 4215 } 4216 } catch (InterruptedException e) { 4217 Log.wtf(TAG, e); 4218 } 4219 4220 } 4221 } 4222 } 4223 } finally { 4224 observer.stopWatching(); 4225 } 4226 } 4227 4228 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4229 if (true || IS_USER_BUILD) { 4230 return; 4231 } 4232 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4233 if (tracesPath == null || tracesPath.length() == 0) { 4234 return; 4235 } 4236 4237 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4238 StrictMode.allowThreadDiskWrites(); 4239 try { 4240 final File tracesFile = new File(tracesPath); 4241 final File tracesDir = tracesFile.getParentFile(); 4242 final File tracesTmp = new File(tracesDir, "__tmp__"); 4243 try { 4244 if (!tracesDir.exists()) { 4245 tracesFile.mkdirs(); 4246 if (!SELinux.restorecon(tracesDir.getPath())) { 4247 return; 4248 } 4249 } 4250 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4251 4252 if (tracesFile.exists()) { 4253 tracesTmp.delete(); 4254 tracesFile.renameTo(tracesTmp); 4255 } 4256 StringBuilder sb = new StringBuilder(); 4257 Time tobj = new Time(); 4258 tobj.set(System.currentTimeMillis()); 4259 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4260 sb.append(": "); 4261 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4262 sb.append(" since "); 4263 sb.append(msg); 4264 FileOutputStream fos = new FileOutputStream(tracesFile); 4265 fos.write(sb.toString().getBytes()); 4266 if (app == null) { 4267 fos.write("\n*** No application process!".getBytes()); 4268 } 4269 fos.close(); 4270 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4271 } catch (IOException e) { 4272 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4273 return; 4274 } 4275 4276 if (app != null) { 4277 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4278 firstPids.add(app.pid); 4279 dumpStackTraces(tracesPath, firstPids, null, null, null); 4280 } 4281 4282 File lastTracesFile = null; 4283 File curTracesFile = null; 4284 for (int i=9; i>=0; i--) { 4285 String name = String.format(Locale.US, "slow%02d.txt", i); 4286 curTracesFile = new File(tracesDir, name); 4287 if (curTracesFile.exists()) { 4288 if (lastTracesFile != null) { 4289 curTracesFile.renameTo(lastTracesFile); 4290 } else { 4291 curTracesFile.delete(); 4292 } 4293 } 4294 lastTracesFile = curTracesFile; 4295 } 4296 tracesFile.renameTo(curTracesFile); 4297 if (tracesTmp.exists()) { 4298 tracesTmp.renameTo(tracesFile); 4299 } 4300 } finally { 4301 StrictMode.setThreadPolicy(oldPolicy); 4302 } 4303 } 4304 4305 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4306 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4307 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4308 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4309 4310 if (mController != null) { 4311 try { 4312 // 0 == continue, -1 = kill process immediately 4313 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4314 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4315 } catch (RemoteException e) { 4316 mController = null; 4317 Watchdog.getInstance().setActivityController(null); 4318 } 4319 } 4320 4321 long anrTime = SystemClock.uptimeMillis(); 4322 if (MONITOR_CPU_USAGE) { 4323 updateCpuStatsNow(); 4324 } 4325 4326 synchronized (this) { 4327 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4328 if (mShuttingDown) { 4329 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4330 return; 4331 } else if (app.notResponding) { 4332 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4333 return; 4334 } else if (app.crashing) { 4335 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4336 return; 4337 } 4338 4339 // In case we come through here for the same app before completing 4340 // this one, mark as anring now so we will bail out. 4341 app.notResponding = true; 4342 4343 // Log the ANR to the event log. 4344 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4345 app.processName, app.info.flags, annotation); 4346 4347 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4348 firstPids.add(app.pid); 4349 4350 int parentPid = app.pid; 4351 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4352 if (parentPid != app.pid) firstPids.add(parentPid); 4353 4354 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4355 4356 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4357 ProcessRecord r = mLruProcesses.get(i); 4358 if (r != null && r.thread != null) { 4359 int pid = r.pid; 4360 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4361 if (r.persistent) { 4362 firstPids.add(pid); 4363 } else { 4364 lastPids.put(pid, Boolean.TRUE); 4365 } 4366 } 4367 } 4368 } 4369 } 4370 4371 // Log the ANR to the main log. 4372 StringBuilder info = new StringBuilder(); 4373 info.setLength(0); 4374 info.append("ANR in ").append(app.processName); 4375 if (activity != null && activity.shortComponentName != null) { 4376 info.append(" (").append(activity.shortComponentName).append(")"); 4377 } 4378 info.append("\n"); 4379 info.append("PID: ").append(app.pid).append("\n"); 4380 if (annotation != null) { 4381 info.append("Reason: ").append(annotation).append("\n"); 4382 } 4383 if (parent != null && parent != activity) { 4384 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4385 } 4386 4387 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4388 4389 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4390 NATIVE_STACKS_OF_INTEREST); 4391 4392 String cpuInfo = null; 4393 if (MONITOR_CPU_USAGE) { 4394 updateCpuStatsNow(); 4395 synchronized (mProcessCpuThread) { 4396 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4397 } 4398 info.append(processCpuTracker.printCurrentLoad()); 4399 info.append(cpuInfo); 4400 } 4401 4402 info.append(processCpuTracker.printCurrentState(anrTime)); 4403 4404 Slog.e(TAG, info.toString()); 4405 if (tracesFile == null) { 4406 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4407 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4408 } 4409 4410 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4411 cpuInfo, tracesFile, null); 4412 4413 if (mController != null) { 4414 try { 4415 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4416 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4417 if (res != 0) { 4418 if (res < 0 && app.pid != MY_PID) { 4419 Process.killProcess(app.pid); 4420 } else { 4421 synchronized (this) { 4422 mServices.scheduleServiceTimeoutLocked(app); 4423 } 4424 } 4425 return; 4426 } 4427 } catch (RemoteException e) { 4428 mController = null; 4429 Watchdog.getInstance().setActivityController(null); 4430 } 4431 } 4432 4433 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4434 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4435 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4436 4437 synchronized (this) { 4438 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4439 killUnneededProcessLocked(app, "background ANR"); 4440 return; 4441 } 4442 4443 // Set the app's notResponding state, and look up the errorReportReceiver 4444 makeAppNotRespondingLocked(app, 4445 activity != null ? activity.shortComponentName : null, 4446 annotation != null ? "ANR " + annotation : "ANR", 4447 info.toString()); 4448 4449 // Bring up the infamous App Not Responding dialog 4450 Message msg = Message.obtain(); 4451 HashMap<String, Object> map = new HashMap<String, Object>(); 4452 msg.what = SHOW_NOT_RESPONDING_MSG; 4453 msg.obj = map; 4454 msg.arg1 = aboveSystem ? 1 : 0; 4455 map.put("app", app); 4456 if (activity != null) { 4457 map.put("activity", activity); 4458 } 4459 4460 mHandler.sendMessage(msg); 4461 } 4462 } 4463 4464 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4465 if (!mLaunchWarningShown) { 4466 mLaunchWarningShown = true; 4467 mHandler.post(new Runnable() { 4468 @Override 4469 public void run() { 4470 synchronized (ActivityManagerService.this) { 4471 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4472 d.show(); 4473 mHandler.postDelayed(new Runnable() { 4474 @Override 4475 public void run() { 4476 synchronized (ActivityManagerService.this) { 4477 d.dismiss(); 4478 mLaunchWarningShown = false; 4479 } 4480 } 4481 }, 4000); 4482 } 4483 } 4484 }); 4485 } 4486 } 4487 4488 @Override 4489 public boolean clearApplicationUserData(final String packageName, 4490 final IPackageDataObserver observer, int userId) { 4491 enforceNotIsolatedCaller("clearApplicationUserData"); 4492 int uid = Binder.getCallingUid(); 4493 int pid = Binder.getCallingPid(); 4494 userId = handleIncomingUser(pid, uid, 4495 userId, false, true, "clearApplicationUserData", null); 4496 long callingId = Binder.clearCallingIdentity(); 4497 try { 4498 IPackageManager pm = AppGlobals.getPackageManager(); 4499 int pkgUid = -1; 4500 synchronized(this) { 4501 try { 4502 pkgUid = pm.getPackageUid(packageName, userId); 4503 } catch (RemoteException e) { 4504 } 4505 if (pkgUid == -1) { 4506 Slog.w(TAG, "Invalid packageName: " + packageName); 4507 if (observer != null) { 4508 try { 4509 observer.onRemoveCompleted(packageName, false); 4510 } catch (RemoteException e) { 4511 Slog.i(TAG, "Observer no longer exists."); 4512 } 4513 } 4514 return false; 4515 } 4516 if (uid == pkgUid || checkComponentPermission( 4517 android.Manifest.permission.CLEAR_APP_USER_DATA, 4518 pid, uid, -1, true) 4519 == PackageManager.PERMISSION_GRANTED) { 4520 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4521 } else { 4522 throw new SecurityException("PID " + pid + " does not have permission " 4523 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4524 + " of package " + packageName); 4525 } 4526 } 4527 4528 try { 4529 // Clear application user data 4530 pm.clearApplicationUserData(packageName, observer, userId); 4531 4532 // Remove all permissions granted from/to this package 4533 removeUriPermissionsForPackageLocked(packageName, userId, true); 4534 4535 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4536 Uri.fromParts("package", packageName, null)); 4537 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4538 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4539 null, null, 0, null, null, null, false, false, userId); 4540 } catch (RemoteException e) { 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 return true; 4546 } 4547 4548 @Override 4549 public void killBackgroundProcesses(final String packageName, int userId) { 4550 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4551 != PackageManager.PERMISSION_GRANTED && 4552 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4553 != PackageManager.PERMISSION_GRANTED) { 4554 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4555 + Binder.getCallingPid() 4556 + ", uid=" + Binder.getCallingUid() 4557 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4558 Slog.w(TAG, msg); 4559 throw new SecurityException(msg); 4560 } 4561 4562 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4563 userId, true, true, "killBackgroundProcesses", null); 4564 long callingId = Binder.clearCallingIdentity(); 4565 try { 4566 IPackageManager pm = AppGlobals.getPackageManager(); 4567 synchronized(this) { 4568 int appId = -1; 4569 try { 4570 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4571 } catch (RemoteException e) { 4572 } 4573 if (appId == -1) { 4574 Slog.w(TAG, "Invalid packageName: " + packageName); 4575 return; 4576 } 4577 killPackageProcessesLocked(packageName, appId, userId, 4578 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4579 } 4580 } finally { 4581 Binder.restoreCallingIdentity(callingId); 4582 } 4583 } 4584 4585 @Override 4586 public void killAllBackgroundProcesses() { 4587 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4588 != PackageManager.PERMISSION_GRANTED) { 4589 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4590 + Binder.getCallingPid() 4591 + ", uid=" + Binder.getCallingUid() 4592 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4593 Slog.w(TAG, msg); 4594 throw new SecurityException(msg); 4595 } 4596 4597 long callingId = Binder.clearCallingIdentity(); 4598 try { 4599 synchronized(this) { 4600 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4601 final int NP = mProcessNames.getMap().size(); 4602 for (int ip=0; ip<NP; ip++) { 4603 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4604 final int NA = apps.size(); 4605 for (int ia=0; ia<NA; ia++) { 4606 ProcessRecord app = apps.valueAt(ia); 4607 if (app.persistent) { 4608 // we don't kill persistent processes 4609 continue; 4610 } 4611 if (app.removed) { 4612 procs.add(app); 4613 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4614 app.removed = true; 4615 procs.add(app); 4616 } 4617 } 4618 } 4619 4620 int N = procs.size(); 4621 for (int i=0; i<N; i++) { 4622 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4623 } 4624 mAllowLowerMemLevel = true; 4625 updateOomAdjLocked(); 4626 doLowMemReportIfNeededLocked(null); 4627 } 4628 } finally { 4629 Binder.restoreCallingIdentity(callingId); 4630 } 4631 } 4632 4633 @Override 4634 public void forceStopPackage(final String packageName, int userId) { 4635 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4636 != PackageManager.PERMISSION_GRANTED) { 4637 String msg = "Permission Denial: forceStopPackage() from pid=" 4638 + Binder.getCallingPid() 4639 + ", uid=" + Binder.getCallingUid() 4640 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4641 Slog.w(TAG, msg); 4642 throw new SecurityException(msg); 4643 } 4644 final int callingPid = Binder.getCallingPid(); 4645 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4646 userId, true, true, "forceStopPackage", null); 4647 long callingId = Binder.clearCallingIdentity(); 4648 try { 4649 IPackageManager pm = AppGlobals.getPackageManager(); 4650 synchronized(this) { 4651 int[] users = userId == UserHandle.USER_ALL 4652 ? getUsersLocked() : new int[] { userId }; 4653 for (int user : users) { 4654 int pkgUid = -1; 4655 try { 4656 pkgUid = pm.getPackageUid(packageName, user); 4657 } catch (RemoteException e) { 4658 } 4659 if (pkgUid == -1) { 4660 Slog.w(TAG, "Invalid packageName: " + packageName); 4661 continue; 4662 } 4663 try { 4664 pm.setPackageStoppedState(packageName, true, user); 4665 } catch (RemoteException e) { 4666 } catch (IllegalArgumentException e) { 4667 Slog.w(TAG, "Failed trying to unstop package " 4668 + packageName + ": " + e); 4669 } 4670 if (isUserRunningLocked(user, false)) { 4671 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4672 } 4673 } 4674 } 4675 } finally { 4676 Binder.restoreCallingIdentity(callingId); 4677 } 4678 } 4679 4680 /* 4681 * The pkg name and app id have to be specified. 4682 */ 4683 @Override 4684 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4685 if (pkg == null) { 4686 return; 4687 } 4688 // Make sure the uid is valid. 4689 if (appid < 0) { 4690 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4691 return; 4692 } 4693 int callerUid = Binder.getCallingUid(); 4694 // Only the system server can kill an application 4695 if (callerUid == Process.SYSTEM_UID) { 4696 // Post an aysnc message to kill the application 4697 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4698 msg.arg1 = appid; 4699 msg.arg2 = 0; 4700 Bundle bundle = new Bundle(); 4701 bundle.putString("pkg", pkg); 4702 bundle.putString("reason", reason); 4703 msg.obj = bundle; 4704 mHandler.sendMessage(msg); 4705 } else { 4706 throw new SecurityException(callerUid + " cannot kill pkg: " + 4707 pkg); 4708 } 4709 } 4710 4711 @Override 4712 public void closeSystemDialogs(String reason) { 4713 enforceNotIsolatedCaller("closeSystemDialogs"); 4714 4715 final int pid = Binder.getCallingPid(); 4716 final int uid = Binder.getCallingUid(); 4717 final long origId = Binder.clearCallingIdentity(); 4718 try { 4719 synchronized (this) { 4720 // Only allow this from foreground processes, so that background 4721 // applications can't abuse it to prevent system UI from being shown. 4722 if (uid >= Process.FIRST_APPLICATION_UID) { 4723 ProcessRecord proc; 4724 synchronized (mPidsSelfLocked) { 4725 proc = mPidsSelfLocked.get(pid); 4726 } 4727 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4728 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4729 + " from background process " + proc); 4730 return; 4731 } 4732 } 4733 closeSystemDialogsLocked(reason); 4734 } 4735 } finally { 4736 Binder.restoreCallingIdentity(origId); 4737 } 4738 } 4739 4740 void closeSystemDialogsLocked(String reason) { 4741 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4742 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4743 | Intent.FLAG_RECEIVER_FOREGROUND); 4744 if (reason != null) { 4745 intent.putExtra("reason", reason); 4746 } 4747 mWindowManager.closeSystemDialogs(reason); 4748 4749 mStackSupervisor.closeSystemDialogsLocked(); 4750 4751 broadcastIntentLocked(null, null, intent, null, 4752 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4753 Process.SYSTEM_UID, UserHandle.USER_ALL); 4754 } 4755 4756 @Override 4757 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4758 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4759 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4760 for (int i=pids.length-1; i>=0; i--) { 4761 ProcessRecord proc; 4762 int oomAdj; 4763 synchronized (this) { 4764 synchronized (mPidsSelfLocked) { 4765 proc = mPidsSelfLocked.get(pids[i]); 4766 oomAdj = proc != null ? proc.setAdj : 0; 4767 } 4768 } 4769 infos[i] = new Debug.MemoryInfo(); 4770 Debug.getMemoryInfo(pids[i], infos[i]); 4771 if (proc != null) { 4772 synchronized (this) { 4773 if (proc.thread != null && proc.setAdj == oomAdj) { 4774 // Record this for posterity if the process has been stable. 4775 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4776 infos[i].getTotalUss(), false, proc.pkgList); 4777 } 4778 } 4779 } 4780 } 4781 return infos; 4782 } 4783 4784 @Override 4785 public long[] getProcessPss(int[] pids) { 4786 enforceNotIsolatedCaller("getProcessPss"); 4787 long[] pss = new long[pids.length]; 4788 for (int i=pids.length-1; i>=0; i--) { 4789 ProcessRecord proc; 4790 int oomAdj; 4791 synchronized (this) { 4792 synchronized (mPidsSelfLocked) { 4793 proc = mPidsSelfLocked.get(pids[i]); 4794 oomAdj = proc != null ? proc.setAdj : 0; 4795 } 4796 } 4797 long[] tmpUss = new long[1]; 4798 pss[i] = Debug.getPss(pids[i], tmpUss); 4799 if (proc != null) { 4800 synchronized (this) { 4801 if (proc.thread != null && proc.setAdj == oomAdj) { 4802 // Record this for posterity if the process has been stable. 4803 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4804 } 4805 } 4806 } 4807 } 4808 return pss; 4809 } 4810 4811 @Override 4812 public void killApplicationProcess(String processName, int uid) { 4813 if (processName == null) { 4814 return; 4815 } 4816 4817 int callerUid = Binder.getCallingUid(); 4818 // Only the system server can kill an application 4819 if (callerUid == Process.SYSTEM_UID) { 4820 synchronized (this) { 4821 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4822 if (app != null && app.thread != null) { 4823 try { 4824 app.thread.scheduleSuicide(); 4825 } catch (RemoteException e) { 4826 // If the other end already died, then our work here is done. 4827 } 4828 } else { 4829 Slog.w(TAG, "Process/uid not found attempting kill of " 4830 + processName + " / " + uid); 4831 } 4832 } 4833 } else { 4834 throw new SecurityException(callerUid + " cannot kill app process: " + 4835 processName); 4836 } 4837 } 4838 4839 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4840 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4841 false, true, false, false, UserHandle.getUserId(uid), reason); 4842 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4843 Uri.fromParts("package", packageName, null)); 4844 if (!mProcessesReady) { 4845 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4846 | Intent.FLAG_RECEIVER_FOREGROUND); 4847 } 4848 intent.putExtra(Intent.EXTRA_UID, uid); 4849 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4850 broadcastIntentLocked(null, null, intent, 4851 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4852 false, false, 4853 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4854 } 4855 4856 private void forceStopUserLocked(int userId, String reason) { 4857 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4858 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4859 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4860 | Intent.FLAG_RECEIVER_FOREGROUND); 4861 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4862 broadcastIntentLocked(null, null, intent, 4863 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4864 false, false, 4865 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4866 } 4867 4868 private final boolean killPackageProcessesLocked(String packageName, int appId, 4869 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4870 boolean doit, boolean evenPersistent, String reason) { 4871 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4872 4873 // Remove all processes this package may have touched: all with the 4874 // same UID (except for the system or root user), and all whose name 4875 // matches the package name. 4876 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4877 final int NP = mProcessNames.getMap().size(); 4878 for (int ip=0; ip<NP; ip++) { 4879 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4880 final int NA = apps.size(); 4881 for (int ia=0; ia<NA; ia++) { 4882 ProcessRecord app = apps.valueAt(ia); 4883 if (app.persistent && !evenPersistent) { 4884 // we don't kill persistent processes 4885 continue; 4886 } 4887 if (app.removed) { 4888 if (doit) { 4889 procs.add(app); 4890 } 4891 continue; 4892 } 4893 4894 // Skip process if it doesn't meet our oom adj requirement. 4895 if (app.setAdj < minOomAdj) { 4896 continue; 4897 } 4898 4899 // If no package is specified, we call all processes under the 4900 // give user id. 4901 if (packageName == null) { 4902 if (app.userId != userId) { 4903 continue; 4904 } 4905 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4906 continue; 4907 } 4908 // Package has been specified, we want to hit all processes 4909 // that match it. We need to qualify this by the processes 4910 // that are running under the specified app and user ID. 4911 } else { 4912 if (UserHandle.getAppId(app.uid) != appId) { 4913 continue; 4914 } 4915 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4916 continue; 4917 } 4918 if (!app.pkgList.containsKey(packageName)) { 4919 continue; 4920 } 4921 } 4922 4923 // Process has passed all conditions, kill it! 4924 if (!doit) { 4925 return true; 4926 } 4927 app.removed = true; 4928 procs.add(app); 4929 } 4930 } 4931 4932 int N = procs.size(); 4933 for (int i=0; i<N; i++) { 4934 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4935 } 4936 updateOomAdjLocked(); 4937 return N > 0; 4938 } 4939 4940 private final boolean forceStopPackageLocked(String name, int appId, 4941 boolean callerWillRestart, boolean purgeCache, boolean doit, 4942 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4943 int i; 4944 int N; 4945 4946 if (userId == UserHandle.USER_ALL && name == null) { 4947 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4948 } 4949 4950 if (appId < 0 && name != null) { 4951 try { 4952 appId = UserHandle.getAppId( 4953 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4954 } catch (RemoteException e) { 4955 } 4956 } 4957 4958 if (doit) { 4959 if (name != null) { 4960 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4961 + " user=" + userId + ": " + reason); 4962 } else { 4963 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4964 } 4965 4966 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4967 for (int ip=pmap.size()-1; ip>=0; ip--) { 4968 SparseArray<Long> ba = pmap.valueAt(ip); 4969 for (i=ba.size()-1; i>=0; i--) { 4970 boolean remove = false; 4971 final int entUid = ba.keyAt(i); 4972 if (name != null) { 4973 if (userId == UserHandle.USER_ALL) { 4974 if (UserHandle.getAppId(entUid) == appId) { 4975 remove = true; 4976 } 4977 } else { 4978 if (entUid == UserHandle.getUid(userId, appId)) { 4979 remove = true; 4980 } 4981 } 4982 } else if (UserHandle.getUserId(entUid) == userId) { 4983 remove = true; 4984 } 4985 if (remove) { 4986 ba.removeAt(i); 4987 } 4988 } 4989 if (ba.size() == 0) { 4990 pmap.removeAt(ip); 4991 } 4992 } 4993 } 4994 4995 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4996 -100, callerWillRestart, true, doit, evenPersistent, 4997 name == null ? ("stop user " + userId) : ("stop " + name)); 4998 4999 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5000 if (!doit) { 5001 return true; 5002 } 5003 didSomething = true; 5004 } 5005 5006 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5007 if (!doit) { 5008 return true; 5009 } 5010 didSomething = true; 5011 } 5012 5013 if (name == null) { 5014 // Remove all sticky broadcasts from this user. 5015 mStickyBroadcasts.remove(userId); 5016 } 5017 5018 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5019 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5020 userId, providers)) { 5021 if (!doit) { 5022 return true; 5023 } 5024 didSomething = true; 5025 } 5026 N = providers.size(); 5027 for (i=0; i<N; i++) { 5028 removeDyingProviderLocked(null, providers.get(i), true); 5029 } 5030 5031 // Remove transient permissions granted from/to this package/user 5032 removeUriPermissionsForPackageLocked(name, userId, false); 5033 5034 if (name == null || uninstalling) { 5035 // Remove pending intents. For now we only do this when force 5036 // stopping users, because we have some problems when doing this 5037 // for packages -- app widgets are not currently cleaned up for 5038 // such packages, so they can be left with bad pending intents. 5039 if (mIntentSenderRecords.size() > 0) { 5040 Iterator<WeakReference<PendingIntentRecord>> it 5041 = mIntentSenderRecords.values().iterator(); 5042 while (it.hasNext()) { 5043 WeakReference<PendingIntentRecord> wpir = it.next(); 5044 if (wpir == null) { 5045 it.remove(); 5046 continue; 5047 } 5048 PendingIntentRecord pir = wpir.get(); 5049 if (pir == null) { 5050 it.remove(); 5051 continue; 5052 } 5053 if (name == null) { 5054 // Stopping user, remove all objects for the user. 5055 if (pir.key.userId != userId) { 5056 // Not the same user, skip it. 5057 continue; 5058 } 5059 } else { 5060 if (UserHandle.getAppId(pir.uid) != appId) { 5061 // Different app id, skip it. 5062 continue; 5063 } 5064 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5065 // Different user, skip it. 5066 continue; 5067 } 5068 if (!pir.key.packageName.equals(name)) { 5069 // Different package, skip it. 5070 continue; 5071 } 5072 } 5073 if (!doit) { 5074 return true; 5075 } 5076 didSomething = true; 5077 it.remove(); 5078 pir.canceled = true; 5079 if (pir.key.activity != null) { 5080 pir.key.activity.pendingResults.remove(pir.ref); 5081 } 5082 } 5083 } 5084 } 5085 5086 if (doit) { 5087 if (purgeCache && name != null) { 5088 AttributeCache ac = AttributeCache.instance(); 5089 if (ac != null) { 5090 ac.removePackage(name); 5091 } 5092 } 5093 if (mBooted) { 5094 mStackSupervisor.resumeTopActivitiesLocked(); 5095 mStackSupervisor.scheduleIdleLocked(); 5096 } 5097 } 5098 5099 return didSomething; 5100 } 5101 5102 private final boolean removeProcessLocked(ProcessRecord app, 5103 boolean callerWillRestart, boolean allowRestart, String reason) { 5104 final String name = app.processName; 5105 final int uid = app.uid; 5106 if (DEBUG_PROCESSES) Slog.d( 5107 TAG, "Force removing proc " + app.toShortString() + " (" + name 5108 + "/" + uid + ")"); 5109 5110 mProcessNames.remove(name, uid); 5111 mIsolatedProcesses.remove(app.uid); 5112 if (mHeavyWeightProcess == app) { 5113 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5114 mHeavyWeightProcess.userId, 0)); 5115 mHeavyWeightProcess = null; 5116 } 5117 boolean needRestart = false; 5118 if (app.pid > 0 && app.pid != MY_PID) { 5119 int pid = app.pid; 5120 synchronized (mPidsSelfLocked) { 5121 mPidsSelfLocked.remove(pid); 5122 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5123 } 5124 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5125 app.processName, app.info.uid); 5126 if (app.isolated) { 5127 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5128 } 5129 killUnneededProcessLocked(app, reason); 5130 handleAppDiedLocked(app, true, allowRestart); 5131 removeLruProcessLocked(app); 5132 5133 if (app.persistent && !app.isolated) { 5134 if (!callerWillRestart) { 5135 addAppLocked(app.info, false, null /* ABI override */); 5136 } else { 5137 needRestart = true; 5138 } 5139 } 5140 } else { 5141 mRemovedProcesses.add(app); 5142 } 5143 5144 return needRestart; 5145 } 5146 5147 private final void processStartTimedOutLocked(ProcessRecord app) { 5148 final int pid = app.pid; 5149 boolean gone = false; 5150 synchronized (mPidsSelfLocked) { 5151 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5152 if (knownApp != null && knownApp.thread == null) { 5153 mPidsSelfLocked.remove(pid); 5154 gone = true; 5155 } 5156 } 5157 5158 if (gone) { 5159 Slog.w(TAG, "Process " + app + " failed to attach"); 5160 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5161 pid, app.uid, app.processName); 5162 mProcessNames.remove(app.processName, app.uid); 5163 mIsolatedProcesses.remove(app.uid); 5164 if (mHeavyWeightProcess == app) { 5165 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5166 mHeavyWeightProcess.userId, 0)); 5167 mHeavyWeightProcess = null; 5168 } 5169 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5170 app.processName, app.info.uid); 5171 if (app.isolated) { 5172 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5173 } 5174 // Take care of any launching providers waiting for this process. 5175 checkAppInLaunchingProvidersLocked(app, true); 5176 // Take care of any services that are waiting for the process. 5177 mServices.processStartTimedOutLocked(app); 5178 killUnneededProcessLocked(app, "start timeout"); 5179 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5180 Slog.w(TAG, "Unattached app died before backup, skipping"); 5181 try { 5182 IBackupManager bm = IBackupManager.Stub.asInterface( 5183 ServiceManager.getService(Context.BACKUP_SERVICE)); 5184 bm.agentDisconnected(app.info.packageName); 5185 } catch (RemoteException e) { 5186 // Can't happen; the backup manager is local 5187 } 5188 } 5189 if (isPendingBroadcastProcessLocked(pid)) { 5190 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5191 skipPendingBroadcastLocked(pid); 5192 } 5193 } else { 5194 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5195 } 5196 } 5197 5198 private final boolean attachApplicationLocked(IApplicationThread thread, 5199 int pid) { 5200 5201 // Find the application record that is being attached... either via 5202 // the pid if we are running in multiple processes, or just pull the 5203 // next app record if we are emulating process with anonymous threads. 5204 ProcessRecord app; 5205 if (pid != MY_PID && pid >= 0) { 5206 synchronized (mPidsSelfLocked) { 5207 app = mPidsSelfLocked.get(pid); 5208 } 5209 } else { 5210 app = null; 5211 } 5212 5213 if (app == null) { 5214 Slog.w(TAG, "No pending application record for pid " + pid 5215 + " (IApplicationThread " + thread + "); dropping process"); 5216 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5217 if (pid > 0 && pid != MY_PID) { 5218 Process.killProcessQuiet(pid); 5219 } else { 5220 try { 5221 thread.scheduleExit(); 5222 } catch (Exception e) { 5223 // Ignore exceptions. 5224 } 5225 } 5226 return false; 5227 } 5228 5229 // If this application record is still attached to a previous 5230 // process, clean it up now. 5231 if (app.thread != null) { 5232 handleAppDiedLocked(app, true, true); 5233 } 5234 5235 // Tell the process all about itself. 5236 5237 if (localLOGV) Slog.v( 5238 TAG, "Binding process pid " + pid + " to record " + app); 5239 5240 final String processName = app.processName; 5241 try { 5242 AppDeathRecipient adr = new AppDeathRecipient( 5243 app, pid, thread); 5244 thread.asBinder().linkToDeath(adr, 0); 5245 app.deathRecipient = adr; 5246 } catch (RemoteException e) { 5247 app.resetPackageList(mProcessStats); 5248 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5249 return false; 5250 } 5251 5252 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5253 5254 app.makeActive(thread, mProcessStats); 5255 app.curAdj = app.setAdj = -100; 5256 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5257 app.forcingToForeground = null; 5258 updateProcessForegroundLocked(app, false, false); 5259 app.hasShownUi = false; 5260 app.debugging = false; 5261 app.cached = false; 5262 5263 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5264 5265 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5266 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5267 5268 if (!normalMode) { 5269 Slog.i(TAG, "Launching preboot mode app: " + app); 5270 } 5271 5272 if (localLOGV) Slog.v( 5273 TAG, "New app record " + app 5274 + " thread=" + thread.asBinder() + " pid=" + pid); 5275 try { 5276 int testMode = IApplicationThread.DEBUG_OFF; 5277 if (mDebugApp != null && mDebugApp.equals(processName)) { 5278 testMode = mWaitForDebugger 5279 ? IApplicationThread.DEBUG_WAIT 5280 : IApplicationThread.DEBUG_ON; 5281 app.debugging = true; 5282 if (mDebugTransient) { 5283 mDebugApp = mOrigDebugApp; 5284 mWaitForDebugger = mOrigWaitForDebugger; 5285 } 5286 } 5287 String profileFile = app.instrumentationProfileFile; 5288 ParcelFileDescriptor profileFd = null; 5289 boolean profileAutoStop = false; 5290 if (mProfileApp != null && mProfileApp.equals(processName)) { 5291 mProfileProc = app; 5292 profileFile = mProfileFile; 5293 profileFd = mProfileFd; 5294 profileAutoStop = mAutoStopProfiler; 5295 } 5296 boolean enableOpenGlTrace = false; 5297 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5298 enableOpenGlTrace = true; 5299 mOpenGlTraceApp = null; 5300 } 5301 5302 // If the app is being launched for restore or full backup, set it up specially 5303 boolean isRestrictedBackupMode = false; 5304 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5305 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5306 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5307 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5308 } 5309 5310 ensurePackageDexOpt(app.instrumentationInfo != null 5311 ? app.instrumentationInfo.packageName 5312 : app.info.packageName); 5313 if (app.instrumentationClass != null) { 5314 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5315 } 5316 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5317 + processName + " with config " + mConfiguration); 5318 ApplicationInfo appInfo = app.instrumentationInfo != null 5319 ? app.instrumentationInfo : app.info; 5320 app.compat = compatibilityInfoForPackageLocked(appInfo); 5321 if (profileFd != null) { 5322 profileFd = profileFd.dup(); 5323 } 5324 thread.bindApplication(processName, appInfo, providers, 5325 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5326 app.instrumentationArguments, app.instrumentationWatcher, 5327 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5328 isRestrictedBackupMode || !normalMode, app.persistent, 5329 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5330 mCoreSettingsObserver.getCoreSettingsLocked()); 5331 updateLruProcessLocked(app, false, null); 5332 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5333 } catch (Exception e) { 5334 // todo: Yikes! What should we do? For now we will try to 5335 // start another process, but that could easily get us in 5336 // an infinite loop of restarting processes... 5337 Slog.w(TAG, "Exception thrown during bind!", e); 5338 5339 app.resetPackageList(mProcessStats); 5340 app.unlinkDeathRecipient(); 5341 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5342 return false; 5343 } 5344 5345 // Remove this record from the list of starting applications. 5346 mPersistentStartingProcesses.remove(app); 5347 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5348 "Attach application locked removing on hold: " + app); 5349 mProcessesOnHold.remove(app); 5350 5351 boolean badApp = false; 5352 boolean didSomething = false; 5353 5354 // See if the top visible activity is waiting to run in this process... 5355 if (normalMode) { 5356 try { 5357 if (mStackSupervisor.attachApplicationLocked(app)) { 5358 didSomething = true; 5359 } 5360 } catch (Exception e) { 5361 badApp = true; 5362 } 5363 } 5364 5365 // Find any services that should be running in this process... 5366 if (!badApp) { 5367 try { 5368 didSomething |= mServices.attachApplicationLocked(app, processName); 5369 } catch (Exception e) { 5370 badApp = true; 5371 } 5372 } 5373 5374 // Check if a next-broadcast receiver is in this process... 5375 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5376 try { 5377 didSomething |= sendPendingBroadcastsLocked(app); 5378 } catch (Exception e) { 5379 // If the app died trying to launch the receiver we declare it 'bad' 5380 badApp = true; 5381 } 5382 } 5383 5384 // Check whether the next backup agent is in this process... 5385 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5386 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5387 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5388 try { 5389 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5390 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5391 mBackupTarget.backupMode); 5392 } catch (Exception e) { 5393 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5394 e.printStackTrace(); 5395 } 5396 } 5397 5398 if (badApp) { 5399 // todo: Also need to kill application to deal with all 5400 // kinds of exceptions. 5401 handleAppDiedLocked(app, false, true); 5402 return false; 5403 } 5404 5405 if (!didSomething) { 5406 updateOomAdjLocked(); 5407 } 5408 5409 return true; 5410 } 5411 5412 @Override 5413 public final void attachApplication(IApplicationThread thread) { 5414 synchronized (this) { 5415 int callingPid = Binder.getCallingPid(); 5416 final long origId = Binder.clearCallingIdentity(); 5417 attachApplicationLocked(thread, callingPid); 5418 Binder.restoreCallingIdentity(origId); 5419 } 5420 } 5421 5422 @Override 5423 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5424 final long origId = Binder.clearCallingIdentity(); 5425 synchronized (this) { 5426 ActivityStack stack = ActivityRecord.getStackLocked(token); 5427 if (stack != null) { 5428 ActivityRecord r = 5429 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5430 if (stopProfiling) { 5431 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5432 try { 5433 mProfileFd.close(); 5434 } catch (IOException e) { 5435 } 5436 clearProfilerLocked(); 5437 } 5438 } 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 void enableScreenAfterBoot() { 5445 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5446 SystemClock.uptimeMillis()); 5447 mWindowManager.enableScreenAfterBoot(); 5448 5449 synchronized (this) { 5450 updateEventDispatchingLocked(); 5451 } 5452 } 5453 5454 @Override 5455 public void showBootMessage(final CharSequence msg, final boolean always) { 5456 enforceNotIsolatedCaller("showBootMessage"); 5457 mWindowManager.showBootMessage(msg, always); 5458 } 5459 5460 @Override 5461 public void dismissKeyguardOnNextActivity() { 5462 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5463 final long token = Binder.clearCallingIdentity(); 5464 try { 5465 synchronized (this) { 5466 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5467 if (mLockScreenShown) { 5468 mLockScreenShown = false; 5469 comeOutOfSleepIfNeededLocked(); 5470 } 5471 mStackSupervisor.setDismissKeyguard(true); 5472 } 5473 } finally { 5474 Binder.restoreCallingIdentity(token); 5475 } 5476 } 5477 5478 final void finishBooting() { 5479 // Register receivers to handle package update events 5480 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5481 5482 synchronized (this) { 5483 // Ensure that any processes we had put on hold are now started 5484 // up. 5485 final int NP = mProcessesOnHold.size(); 5486 if (NP > 0) { 5487 ArrayList<ProcessRecord> procs = 5488 new ArrayList<ProcessRecord>(mProcessesOnHold); 5489 for (int ip=0; ip<NP; ip++) { 5490 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5491 + procs.get(ip)); 5492 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5493 } 5494 } 5495 5496 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5497 // Start looking for apps that are abusing wake locks. 5498 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5499 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5500 // Tell anyone interested that we are done booting! 5501 SystemProperties.set("sys.boot_completed", "1"); 5502 SystemProperties.set("dev.bootcomplete", "1"); 5503 for (int i=0; i<mStartedUsers.size(); i++) { 5504 UserStartedState uss = mStartedUsers.valueAt(i); 5505 if (uss.mState == UserStartedState.STATE_BOOTING) { 5506 uss.mState = UserStartedState.STATE_RUNNING; 5507 final int userId = mStartedUsers.keyAt(i); 5508 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5509 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5510 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5511 broadcastIntentLocked(null, null, intent, null, 5512 new IIntentReceiver.Stub() { 5513 @Override 5514 public void performReceive(Intent intent, int resultCode, 5515 String data, Bundle extras, boolean ordered, 5516 boolean sticky, int sendingUser) { 5517 synchronized (ActivityManagerService.this) { 5518 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5519 true, false); 5520 } 5521 } 5522 }, 5523 0, null, null, 5524 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5525 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5526 userId); 5527 } 5528 } 5529 scheduleStartProfilesLocked(); 5530 } 5531 } 5532 } 5533 5534 final void ensureBootCompleted() { 5535 boolean booting; 5536 boolean enableScreen; 5537 synchronized (this) { 5538 booting = mBooting; 5539 mBooting = false; 5540 enableScreen = !mBooted; 5541 mBooted = true; 5542 } 5543 5544 if (booting) { 5545 finishBooting(); 5546 } 5547 5548 if (enableScreen) { 5549 enableScreenAfterBoot(); 5550 } 5551 } 5552 5553 @Override 5554 public final void activityResumed(IBinder token) { 5555 final long origId = Binder.clearCallingIdentity(); 5556 synchronized(this) { 5557 ActivityStack stack = ActivityRecord.getStackLocked(token); 5558 if (stack != null) { 5559 ActivityRecord.activityResumedLocked(token); 5560 } 5561 } 5562 Binder.restoreCallingIdentity(origId); 5563 } 5564 5565 @Override 5566 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5567 final long origId = Binder.clearCallingIdentity(); 5568 synchronized(this) { 5569 ActivityStack stack = ActivityRecord.getStackLocked(token); 5570 if (stack != null) { 5571 stack.activityPausedLocked(token, false, persistentState); 5572 } 5573 } 5574 Binder.restoreCallingIdentity(origId); 5575 } 5576 5577 @Override 5578 public final void activityStopped(IBinder token, Bundle icicle, 5579 PersistableBundle persistentState, CharSequence description) { 5580 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5581 5582 // Refuse possible leaked file descriptors 5583 if (icicle != null && icicle.hasFileDescriptors()) { 5584 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5585 } 5586 5587 final long origId = Binder.clearCallingIdentity(); 5588 5589 synchronized (this) { 5590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5591 if (r != null) { 5592 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5593 } 5594 } 5595 5596 trimApplications(); 5597 5598 Binder.restoreCallingIdentity(origId); 5599 } 5600 5601 @Override 5602 public final void activityDestroyed(IBinder token) { 5603 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5604 synchronized (this) { 5605 ActivityStack stack = ActivityRecord.getStackLocked(token); 5606 if (stack != null) { 5607 stack.activityDestroyedLocked(token); 5608 } 5609 } 5610 } 5611 5612 @Override 5613 public String getCallingPackage(IBinder token) { 5614 synchronized (this) { 5615 ActivityRecord r = getCallingRecordLocked(token); 5616 return r != null ? r.info.packageName : null; 5617 } 5618 } 5619 5620 @Override 5621 public ComponentName getCallingActivity(IBinder token) { 5622 synchronized (this) { 5623 ActivityRecord r = getCallingRecordLocked(token); 5624 return r != null ? r.intent.getComponent() : null; 5625 } 5626 } 5627 5628 private ActivityRecord getCallingRecordLocked(IBinder token) { 5629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5630 if (r == null) { 5631 return null; 5632 } 5633 return r.resultTo; 5634 } 5635 5636 @Override 5637 public ComponentName getActivityClassForToken(IBinder token) { 5638 synchronized(this) { 5639 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5640 if (r == null) { 5641 return null; 5642 } 5643 return r.intent.getComponent(); 5644 } 5645 } 5646 5647 @Override 5648 public String getPackageForToken(IBinder token) { 5649 synchronized(this) { 5650 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5651 if (r == null) { 5652 return null; 5653 } 5654 return r.packageName; 5655 } 5656 } 5657 5658 @Override 5659 public IIntentSender getIntentSender(int type, 5660 String packageName, IBinder token, String resultWho, 5661 int requestCode, Intent[] intents, String[] resolvedTypes, 5662 int flags, Bundle options, int userId) { 5663 enforceNotIsolatedCaller("getIntentSender"); 5664 // Refuse possible leaked file descriptors 5665 if (intents != null) { 5666 if (intents.length < 1) { 5667 throw new IllegalArgumentException("Intents array length must be >= 1"); 5668 } 5669 for (int i=0; i<intents.length; i++) { 5670 Intent intent = intents[i]; 5671 if (intent != null) { 5672 if (intent.hasFileDescriptors()) { 5673 throw new IllegalArgumentException("File descriptors passed in Intent"); 5674 } 5675 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5676 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5677 throw new IllegalArgumentException( 5678 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5679 } 5680 intents[i] = new Intent(intent); 5681 } 5682 } 5683 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5684 throw new IllegalArgumentException( 5685 "Intent array length does not match resolvedTypes length"); 5686 } 5687 } 5688 if (options != null) { 5689 if (options.hasFileDescriptors()) { 5690 throw new IllegalArgumentException("File descriptors passed in options"); 5691 } 5692 } 5693 5694 synchronized(this) { 5695 int callingUid = Binder.getCallingUid(); 5696 int origUserId = userId; 5697 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5698 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5699 "getIntentSender", null); 5700 if (origUserId == UserHandle.USER_CURRENT) { 5701 // We don't want to evaluate this until the pending intent is 5702 // actually executed. However, we do want to always do the 5703 // security checking for it above. 5704 userId = UserHandle.USER_CURRENT; 5705 } 5706 try { 5707 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5708 int uid = AppGlobals.getPackageManager() 5709 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5710 if (!UserHandle.isSameApp(callingUid, uid)) { 5711 String msg = "Permission Denial: getIntentSender() from pid=" 5712 + Binder.getCallingPid() 5713 + ", uid=" + Binder.getCallingUid() 5714 + ", (need uid=" + uid + ")" 5715 + " is not allowed to send as package " + packageName; 5716 Slog.w(TAG, msg); 5717 throw new SecurityException(msg); 5718 } 5719 } 5720 5721 return getIntentSenderLocked(type, packageName, callingUid, userId, 5722 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5723 5724 } catch (RemoteException e) { 5725 throw new SecurityException(e); 5726 } 5727 } 5728 } 5729 5730 IIntentSender getIntentSenderLocked(int type, String packageName, 5731 int callingUid, int userId, IBinder token, String resultWho, 5732 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5733 Bundle options) { 5734 if (DEBUG_MU) 5735 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5736 ActivityRecord activity = null; 5737 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5738 activity = ActivityRecord.isInStackLocked(token); 5739 if (activity == null) { 5740 return null; 5741 } 5742 if (activity.finishing) { 5743 return null; 5744 } 5745 } 5746 5747 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5748 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5749 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5750 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5751 |PendingIntent.FLAG_UPDATE_CURRENT); 5752 5753 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5754 type, packageName, activity, resultWho, 5755 requestCode, intents, resolvedTypes, flags, options, userId); 5756 WeakReference<PendingIntentRecord> ref; 5757 ref = mIntentSenderRecords.get(key); 5758 PendingIntentRecord rec = ref != null ? ref.get() : null; 5759 if (rec != null) { 5760 if (!cancelCurrent) { 5761 if (updateCurrent) { 5762 if (rec.key.requestIntent != null) { 5763 rec.key.requestIntent.replaceExtras(intents != null ? 5764 intents[intents.length - 1] : null); 5765 } 5766 if (intents != null) { 5767 intents[intents.length-1] = rec.key.requestIntent; 5768 rec.key.allIntents = intents; 5769 rec.key.allResolvedTypes = resolvedTypes; 5770 } else { 5771 rec.key.allIntents = null; 5772 rec.key.allResolvedTypes = null; 5773 } 5774 } 5775 return rec; 5776 } 5777 rec.canceled = true; 5778 mIntentSenderRecords.remove(key); 5779 } 5780 if (noCreate) { 5781 return rec; 5782 } 5783 rec = new PendingIntentRecord(this, key, callingUid); 5784 mIntentSenderRecords.put(key, rec.ref); 5785 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5786 if (activity.pendingResults == null) { 5787 activity.pendingResults 5788 = new HashSet<WeakReference<PendingIntentRecord>>(); 5789 } 5790 activity.pendingResults.add(rec.ref); 5791 } 5792 return rec; 5793 } 5794 5795 @Override 5796 public void cancelIntentSender(IIntentSender sender) { 5797 if (!(sender instanceof PendingIntentRecord)) { 5798 return; 5799 } 5800 synchronized(this) { 5801 PendingIntentRecord rec = (PendingIntentRecord)sender; 5802 try { 5803 int uid = AppGlobals.getPackageManager() 5804 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5805 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5806 String msg = "Permission Denial: cancelIntentSender() from pid=" 5807 + Binder.getCallingPid() 5808 + ", uid=" + Binder.getCallingUid() 5809 + " is not allowed to cancel packges " 5810 + rec.key.packageName; 5811 Slog.w(TAG, msg); 5812 throw new SecurityException(msg); 5813 } 5814 } catch (RemoteException e) { 5815 throw new SecurityException(e); 5816 } 5817 cancelIntentSenderLocked(rec, true); 5818 } 5819 } 5820 5821 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5822 rec.canceled = true; 5823 mIntentSenderRecords.remove(rec.key); 5824 if (cleanActivity && rec.key.activity != null) { 5825 rec.key.activity.pendingResults.remove(rec.ref); 5826 } 5827 } 5828 5829 @Override 5830 public String getPackageForIntentSender(IIntentSender pendingResult) { 5831 if (!(pendingResult instanceof PendingIntentRecord)) { 5832 return null; 5833 } 5834 try { 5835 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5836 return res.key.packageName; 5837 } catch (ClassCastException e) { 5838 } 5839 return null; 5840 } 5841 5842 @Override 5843 public int getUidForIntentSender(IIntentSender sender) { 5844 if (sender instanceof PendingIntentRecord) { 5845 try { 5846 PendingIntentRecord res = (PendingIntentRecord)sender; 5847 return res.uid; 5848 } catch (ClassCastException e) { 5849 } 5850 } 5851 return -1; 5852 } 5853 5854 @Override 5855 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5856 if (!(pendingResult instanceof PendingIntentRecord)) { 5857 return false; 5858 } 5859 try { 5860 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5861 if (res.key.allIntents == null) { 5862 return false; 5863 } 5864 for (int i=0; i<res.key.allIntents.length; i++) { 5865 Intent intent = res.key.allIntents[i]; 5866 if (intent.getPackage() != null && intent.getComponent() != null) { 5867 return false; 5868 } 5869 } 5870 return true; 5871 } catch (ClassCastException e) { 5872 } 5873 return false; 5874 } 5875 5876 @Override 5877 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5878 if (!(pendingResult instanceof PendingIntentRecord)) { 5879 return false; 5880 } 5881 try { 5882 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5883 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5884 return true; 5885 } 5886 return false; 5887 } catch (ClassCastException e) { 5888 } 5889 return false; 5890 } 5891 5892 @Override 5893 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5894 if (!(pendingResult instanceof PendingIntentRecord)) { 5895 return null; 5896 } 5897 try { 5898 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5899 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5900 } catch (ClassCastException e) { 5901 } 5902 return null; 5903 } 5904 5905 @Override 5906 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5907 if (!(pendingResult instanceof PendingIntentRecord)) { 5908 return null; 5909 } 5910 try { 5911 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5912 Intent intent = res.key.requestIntent; 5913 if (intent != null) { 5914 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5915 || res.lastTagPrefix.equals(prefix))) { 5916 return res.lastTag; 5917 } 5918 res.lastTagPrefix = prefix; 5919 StringBuilder sb = new StringBuilder(128); 5920 if (prefix != null) { 5921 sb.append(prefix); 5922 } 5923 if (intent.getAction() != null) { 5924 sb.append(intent.getAction()); 5925 } else if (intent.getComponent() != null) { 5926 intent.getComponent().appendShortString(sb); 5927 } else { 5928 sb.append("?"); 5929 } 5930 return res.lastTag = sb.toString(); 5931 } 5932 } catch (ClassCastException e) { 5933 } 5934 return null; 5935 } 5936 5937 @Override 5938 public void setProcessLimit(int max) { 5939 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5940 "setProcessLimit()"); 5941 synchronized (this) { 5942 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5943 mProcessLimitOverride = max; 5944 } 5945 trimApplications(); 5946 } 5947 5948 @Override 5949 public int getProcessLimit() { 5950 synchronized (this) { 5951 return mProcessLimitOverride; 5952 } 5953 } 5954 5955 void foregroundTokenDied(ForegroundToken token) { 5956 synchronized (ActivityManagerService.this) { 5957 synchronized (mPidsSelfLocked) { 5958 ForegroundToken cur 5959 = mForegroundProcesses.get(token.pid); 5960 if (cur != token) { 5961 return; 5962 } 5963 mForegroundProcesses.remove(token.pid); 5964 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5965 if (pr == null) { 5966 return; 5967 } 5968 pr.forcingToForeground = null; 5969 updateProcessForegroundLocked(pr, false, false); 5970 } 5971 updateOomAdjLocked(); 5972 } 5973 } 5974 5975 @Override 5976 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5977 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5978 "setProcessForeground()"); 5979 synchronized(this) { 5980 boolean changed = false; 5981 5982 synchronized (mPidsSelfLocked) { 5983 ProcessRecord pr = mPidsSelfLocked.get(pid); 5984 if (pr == null && isForeground) { 5985 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5986 return; 5987 } 5988 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5989 if (oldToken != null) { 5990 oldToken.token.unlinkToDeath(oldToken, 0); 5991 mForegroundProcesses.remove(pid); 5992 if (pr != null) { 5993 pr.forcingToForeground = null; 5994 } 5995 changed = true; 5996 } 5997 if (isForeground && token != null) { 5998 ForegroundToken newToken = new ForegroundToken() { 5999 @Override 6000 public void binderDied() { 6001 foregroundTokenDied(this); 6002 } 6003 }; 6004 newToken.pid = pid; 6005 newToken.token = token; 6006 try { 6007 token.linkToDeath(newToken, 0); 6008 mForegroundProcesses.put(pid, newToken); 6009 pr.forcingToForeground = token; 6010 changed = true; 6011 } catch (RemoteException e) { 6012 // If the process died while doing this, we will later 6013 // do the cleanup with the process death link. 6014 } 6015 } 6016 } 6017 6018 if (changed) { 6019 updateOomAdjLocked(); 6020 } 6021 } 6022 } 6023 6024 // ========================================================= 6025 // PERMISSIONS 6026 // ========================================================= 6027 6028 static class PermissionController extends IPermissionController.Stub { 6029 ActivityManagerService mActivityManagerService; 6030 PermissionController(ActivityManagerService activityManagerService) { 6031 mActivityManagerService = activityManagerService; 6032 } 6033 6034 @Override 6035 public boolean checkPermission(String permission, int pid, int uid) { 6036 return mActivityManagerService.checkPermission(permission, pid, 6037 uid) == PackageManager.PERMISSION_GRANTED; 6038 } 6039 } 6040 6041 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6042 @Override 6043 public int checkComponentPermission(String permission, int pid, int uid, 6044 int owningUid, boolean exported) { 6045 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6046 owningUid, exported); 6047 } 6048 6049 @Override 6050 public Object getAMSLock() { 6051 return ActivityManagerService.this; 6052 } 6053 } 6054 6055 /** 6056 * This can be called with or without the global lock held. 6057 */ 6058 int checkComponentPermission(String permission, int pid, int uid, 6059 int owningUid, boolean exported) { 6060 // We might be performing an operation on behalf of an indirect binder 6061 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6062 // client identity accordingly before proceeding. 6063 Identity tlsIdentity = sCallerIdentity.get(); 6064 if (tlsIdentity != null) { 6065 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6066 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6067 uid = tlsIdentity.uid; 6068 pid = tlsIdentity.pid; 6069 } 6070 6071 if (pid == MY_PID) { 6072 return PackageManager.PERMISSION_GRANTED; 6073 } 6074 6075 return ActivityManager.checkComponentPermission(permission, uid, 6076 owningUid, exported); 6077 } 6078 6079 /** 6080 * As the only public entry point for permissions checking, this method 6081 * can enforce the semantic that requesting a check on a null global 6082 * permission is automatically denied. (Internally a null permission 6083 * string is used when calling {@link #checkComponentPermission} in cases 6084 * when only uid-based security is needed.) 6085 * 6086 * This can be called with or without the global lock held. 6087 */ 6088 @Override 6089 public int checkPermission(String permission, int pid, int uid) { 6090 if (permission == null) { 6091 return PackageManager.PERMISSION_DENIED; 6092 } 6093 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6094 } 6095 6096 /** 6097 * Binder IPC calls go through the public entry point. 6098 * This can be called with or without the global lock held. 6099 */ 6100 int checkCallingPermission(String permission) { 6101 return checkPermission(permission, 6102 Binder.getCallingPid(), 6103 UserHandle.getAppId(Binder.getCallingUid())); 6104 } 6105 6106 /** 6107 * This can be called with or without the global lock held. 6108 */ 6109 void enforceCallingPermission(String permission, String func) { 6110 if (checkCallingPermission(permission) 6111 == PackageManager.PERMISSION_GRANTED) { 6112 return; 6113 } 6114 6115 String msg = "Permission Denial: " + func + " from pid=" 6116 + Binder.getCallingPid() 6117 + ", uid=" + Binder.getCallingUid() 6118 + " requires " + permission; 6119 Slog.w(TAG, msg); 6120 throw new SecurityException(msg); 6121 } 6122 6123 /** 6124 * Determine if UID is holding permissions required to access {@link Uri} in 6125 * the given {@link ProviderInfo}. Final permission checking is always done 6126 * in {@link ContentProvider}. 6127 */ 6128 private final boolean checkHoldingPermissionsLocked( 6129 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6130 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6131 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6132 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6133 return false; 6134 } 6135 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6136 } 6137 6138 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6139 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6140 if (pi.applicationInfo.uid == uid) { 6141 return true; 6142 } else if (!pi.exported) { 6143 return false; 6144 } 6145 6146 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6147 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6148 try { 6149 // check if target holds top-level <provider> permissions 6150 if (!readMet && pi.readPermission != null && considerUidPermissions 6151 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6152 readMet = true; 6153 } 6154 if (!writeMet && pi.writePermission != null && considerUidPermissions 6155 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6156 writeMet = true; 6157 } 6158 6159 // track if unprotected read/write is allowed; any denied 6160 // <path-permission> below removes this ability 6161 boolean allowDefaultRead = pi.readPermission == null; 6162 boolean allowDefaultWrite = pi.writePermission == null; 6163 6164 // check if target holds any <path-permission> that match uri 6165 final PathPermission[] pps = pi.pathPermissions; 6166 if (pps != null) { 6167 final String path = grantUri.uri.getPath(); 6168 int i = pps.length; 6169 while (i > 0 && (!readMet || !writeMet)) { 6170 i--; 6171 PathPermission pp = pps[i]; 6172 if (pp.match(path)) { 6173 if (!readMet) { 6174 final String pprperm = pp.getReadPermission(); 6175 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6176 + pprperm + " for " + pp.getPath() 6177 + ": match=" + pp.match(path) 6178 + " check=" + pm.checkUidPermission(pprperm, uid)); 6179 if (pprperm != null) { 6180 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6181 == PERMISSION_GRANTED) { 6182 readMet = true; 6183 } else { 6184 allowDefaultRead = false; 6185 } 6186 } 6187 } 6188 if (!writeMet) { 6189 final String ppwperm = pp.getWritePermission(); 6190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6191 + ppwperm + " for " + pp.getPath() 6192 + ": match=" + pp.match(path) 6193 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6194 if (ppwperm != null) { 6195 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6196 == PERMISSION_GRANTED) { 6197 writeMet = true; 6198 } else { 6199 allowDefaultWrite = false; 6200 } 6201 } 6202 } 6203 } 6204 } 6205 } 6206 6207 // grant unprotected <provider> read/write, if not blocked by 6208 // <path-permission> above 6209 if (allowDefaultRead) readMet = true; 6210 if (allowDefaultWrite) writeMet = true; 6211 6212 } catch (RemoteException e) { 6213 return false; 6214 } 6215 6216 return readMet && writeMet; 6217 } 6218 6219 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6220 ProviderInfo pi = null; 6221 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6222 if (cpr != null) { 6223 pi = cpr.info; 6224 } else { 6225 try { 6226 pi = AppGlobals.getPackageManager().resolveContentProvider( 6227 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6228 } catch (RemoteException ex) { 6229 } 6230 } 6231 return pi; 6232 } 6233 6234 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6235 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6236 if (targetUris != null) { 6237 return targetUris.get(grantUri); 6238 } 6239 return null; 6240 } 6241 6242 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6243 String targetPkg, int targetUid, GrantUri grantUri) { 6244 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6245 if (targetUris == null) { 6246 targetUris = Maps.newArrayMap(); 6247 mGrantedUriPermissions.put(targetUid, targetUris); 6248 } 6249 6250 UriPermission perm = targetUris.get(grantUri); 6251 if (perm == null) { 6252 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6253 targetUris.put(grantUri, perm); 6254 } 6255 6256 return perm; 6257 } 6258 6259 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6260 final int modeFlags) { 6261 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6262 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6263 : UriPermission.STRENGTH_OWNED; 6264 6265 // Root gets to do everything. 6266 if (uid == 0) { 6267 return true; 6268 } 6269 6270 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6271 if (perms == null) return false; 6272 6273 // First look for exact match 6274 final UriPermission exactPerm = perms.get(grantUri); 6275 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6276 return true; 6277 } 6278 6279 // No exact match, look for prefixes 6280 final int N = perms.size(); 6281 for (int i = 0; i < N; i++) { 6282 final UriPermission perm = perms.valueAt(i); 6283 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6284 && perm.getStrength(modeFlags) >= minStrength) { 6285 return true; 6286 } 6287 } 6288 6289 return false; 6290 } 6291 6292 @Override 6293 public int checkUriPermission(Uri uri, int pid, int uid, 6294 final int modeFlags, int userId) { 6295 enforceNotIsolatedCaller("checkUriPermission"); 6296 6297 // Another redirected-binder-call permissions check as in 6298 // {@link checkComponentPermission}. 6299 Identity tlsIdentity = sCallerIdentity.get(); 6300 if (tlsIdentity != null) { 6301 uid = tlsIdentity.uid; 6302 pid = tlsIdentity.pid; 6303 } 6304 6305 // Our own process gets to do everything. 6306 if (pid == MY_PID) { 6307 return PackageManager.PERMISSION_GRANTED; 6308 } 6309 synchronized (this) { 6310 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6311 ? PackageManager.PERMISSION_GRANTED 6312 : PackageManager.PERMISSION_DENIED; 6313 } 6314 } 6315 6316 /** 6317 * Check if the targetPkg can be granted permission to access uri by 6318 * the callingUid using the given modeFlags. Throws a security exception 6319 * if callingUid is not allowed to do this. Returns the uid of the target 6320 * if the URI permission grant should be performed; returns -1 if it is not 6321 * needed (for example targetPkg already has permission to access the URI). 6322 * If you already know the uid of the target, you can supply it in 6323 * lastTargetUid else set that to -1. 6324 */ 6325 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6326 final int modeFlags, int lastTargetUid) { 6327 if (!Intent.isAccessUriMode(modeFlags)) { 6328 return -1; 6329 } 6330 6331 if (targetPkg != null) { 6332 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6333 "Checking grant " + targetPkg + " permission to " + grantUri); 6334 } 6335 6336 final IPackageManager pm = AppGlobals.getPackageManager(); 6337 6338 // If this is not a content: uri, we can't do anything with it. 6339 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6340 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6341 "Can't grant URI permission for non-content URI: " + grantUri); 6342 return -1; 6343 } 6344 6345 final String authority = grantUri.uri.getAuthority(); 6346 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6347 if (pi == null) { 6348 Slog.w(TAG, "No content provider found for permission check: " + 6349 grantUri.uri.toSafeString()); 6350 return -1; 6351 } 6352 6353 int targetUid = lastTargetUid; 6354 if (targetUid < 0 && targetPkg != null) { 6355 try { 6356 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6357 if (targetUid < 0) { 6358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6359 "Can't grant URI permission no uid for: " + targetPkg); 6360 return -1; 6361 } 6362 } catch (RemoteException ex) { 6363 return -1; 6364 } 6365 } 6366 6367 if (targetUid >= 0) { 6368 // First... does the target actually need this permission? 6369 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6370 // No need to grant the target this permission. 6371 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6372 "Target " + targetPkg + " already has full permission to " + grantUri); 6373 return -1; 6374 } 6375 } else { 6376 // First... there is no target package, so can anyone access it? 6377 boolean allowed = pi.exported; 6378 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6379 if (pi.readPermission != null) { 6380 allowed = false; 6381 } 6382 } 6383 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6384 if (pi.writePermission != null) { 6385 allowed = false; 6386 } 6387 } 6388 if (allowed) { 6389 return -1; 6390 } 6391 } 6392 6393 /* There is a special cross user grant if: 6394 * - The target is on another user. 6395 * - Apps on the current user can access the uri without any uid permissions. 6396 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6397 * grant uri permissions. 6398 */ 6399 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6400 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6401 modeFlags, false /*without considering the uid permissions*/); 6402 6403 // Second... is the provider allowing granting of URI permissions? 6404 if (!specialCrossUserGrant) { 6405 if (!pi.grantUriPermissions) { 6406 throw new SecurityException("Provider " + pi.packageName 6407 + "/" + pi.name 6408 + " does not allow granting of Uri permissions (uri " 6409 + grantUri + ")"); 6410 } 6411 if (pi.uriPermissionPatterns != null) { 6412 final int N = pi.uriPermissionPatterns.length; 6413 boolean allowed = false; 6414 for (int i=0; i<N; i++) { 6415 if (pi.uriPermissionPatterns[i] != null 6416 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6417 allowed = true; 6418 break; 6419 } 6420 } 6421 if (!allowed) { 6422 throw new SecurityException("Provider " + pi.packageName 6423 + "/" + pi.name 6424 + " does not allow granting of permission to path of Uri " 6425 + grantUri); 6426 } 6427 } 6428 } 6429 6430 // Third... does the caller itself have permission to access 6431 // this uri? 6432 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6433 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6434 // Require they hold a strong enough Uri permission 6435 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6436 throw new SecurityException("Uid " + callingUid 6437 + " does not have permission to uri " + grantUri); 6438 } 6439 } 6440 } 6441 return targetUid; 6442 } 6443 6444 @Override 6445 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6446 final int modeFlags, int userId) { 6447 enforceNotIsolatedCaller("checkGrantUriPermission"); 6448 synchronized(this) { 6449 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6450 new GrantUri(userId, uri, false), modeFlags, -1); 6451 } 6452 } 6453 6454 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6455 final int modeFlags, UriPermissionOwner owner) { 6456 if (!Intent.isAccessUriMode(modeFlags)) { 6457 return; 6458 } 6459 6460 // So here we are: the caller has the assumed permission 6461 // to the uri, and the target doesn't. Let's now give this to 6462 // the target. 6463 6464 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6465 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6466 6467 final String authority = grantUri.uri.getAuthority(); 6468 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6469 if (pi == null) { 6470 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6471 return; 6472 } 6473 6474 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6475 grantUri.prefix = true; 6476 } 6477 final UriPermission perm = findOrCreateUriPermissionLocked( 6478 pi.packageName, targetPkg, targetUid, grantUri); 6479 perm.grantModes(modeFlags, owner); 6480 } 6481 6482 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6483 final int modeFlags, UriPermissionOwner owner) { 6484 if (targetPkg == null) { 6485 throw new NullPointerException("targetPkg"); 6486 } 6487 6488 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6489 -1); 6490 if (targetUid < 0) { 6491 return; 6492 } 6493 6494 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6495 owner); 6496 } 6497 6498 static class NeededUriGrants extends ArrayList<GrantUri> { 6499 final String targetPkg; 6500 final int targetUid; 6501 final int flags; 6502 6503 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6504 this.targetPkg = targetPkg; 6505 this.targetUid = targetUid; 6506 this.flags = flags; 6507 } 6508 } 6509 6510 /** 6511 * Like checkGrantUriPermissionLocked, but takes an Intent. 6512 */ 6513 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6514 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6515 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6516 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6517 + " clip=" + (intent != null ? intent.getClipData() : null) 6518 + " from " + intent + "; flags=0x" 6519 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6520 6521 if (targetPkg == null) { 6522 throw new NullPointerException("targetPkg"); 6523 } 6524 6525 if (intent == null) { 6526 return null; 6527 } 6528 Uri data = intent.getData(); 6529 ClipData clip = intent.getClipData(); 6530 if (data == null && clip == null) { 6531 return null; 6532 } 6533 final IPackageManager pm = AppGlobals.getPackageManager(); 6534 int targetUid; 6535 if (needed != null) { 6536 targetUid = needed.targetUid; 6537 } else { 6538 try { 6539 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6540 } catch (RemoteException ex) { 6541 return null; 6542 } 6543 if (targetUid < 0) { 6544 if (DEBUG_URI_PERMISSION) { 6545 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6546 + " on user " + targetUserId); 6547 } 6548 return null; 6549 } 6550 } 6551 if (data != null) { 6552 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6553 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6554 targetUid); 6555 if (targetUid > 0) { 6556 if (needed == null) { 6557 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6558 } 6559 needed.add(grantUri); 6560 } 6561 } 6562 if (clip != null) { 6563 for (int i=0; i<clip.getItemCount(); i++) { 6564 Uri uri = clip.getItemAt(i).getUri(); 6565 if (uri != null) { 6566 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6567 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6568 targetUid); 6569 if (targetUid > 0) { 6570 if (needed == null) { 6571 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6572 } 6573 needed.add(grantUri); 6574 } 6575 } else { 6576 Intent clipIntent = clip.getItemAt(i).getIntent(); 6577 if (clipIntent != null) { 6578 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6579 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6580 if (newNeeded != null) { 6581 needed = newNeeded; 6582 } 6583 } 6584 } 6585 } 6586 } 6587 6588 return needed; 6589 } 6590 6591 /** 6592 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6593 */ 6594 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6595 UriPermissionOwner owner) { 6596 if (needed != null) { 6597 for (int i=0; i<needed.size(); i++) { 6598 GrantUri grantUri = needed.get(i); 6599 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6600 grantUri, needed.flags, owner); 6601 } 6602 } 6603 } 6604 6605 void grantUriPermissionFromIntentLocked(int callingUid, 6606 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6607 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6608 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6609 if (needed == null) { 6610 return; 6611 } 6612 6613 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6614 } 6615 6616 @Override 6617 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6618 final int modeFlags, int userId) { 6619 enforceNotIsolatedCaller("grantUriPermission"); 6620 GrantUri grantUri = new GrantUri(userId, uri, false); 6621 synchronized(this) { 6622 final ProcessRecord r = getRecordForAppLocked(caller); 6623 if (r == null) { 6624 throw new SecurityException("Unable to find app for caller " 6625 + caller 6626 + " when granting permission to uri " + grantUri); 6627 } 6628 if (targetPkg == null) { 6629 throw new IllegalArgumentException("null target"); 6630 } 6631 if (grantUri == null) { 6632 throw new IllegalArgumentException("null uri"); 6633 } 6634 6635 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6636 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6637 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6638 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6639 6640 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6641 } 6642 } 6643 6644 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6645 if (perm.modeFlags == 0) { 6646 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6647 perm.targetUid); 6648 if (perms != null) { 6649 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6650 "Removing " + perm.targetUid + " permission to " + perm.uri); 6651 6652 perms.remove(perm.uri); 6653 if (perms.isEmpty()) { 6654 mGrantedUriPermissions.remove(perm.targetUid); 6655 } 6656 } 6657 } 6658 } 6659 6660 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6661 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6662 6663 final IPackageManager pm = AppGlobals.getPackageManager(); 6664 final String authority = grantUri.uri.getAuthority(); 6665 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6666 if (pi == null) { 6667 Slog.w(TAG, "No content provider found for permission revoke: " 6668 + grantUri.toSafeString()); 6669 return; 6670 } 6671 6672 // Does the caller have this permission on the URI? 6673 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6674 // Right now, if you are not the original owner of the permission, 6675 // you are not allowed to revoke it. 6676 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6677 throw new SecurityException("Uid " + callingUid 6678 + " does not have permission to uri " + grantUri); 6679 //} 6680 } 6681 6682 boolean persistChanged = false; 6683 6684 // Go through all of the permissions and remove any that match. 6685 int N = mGrantedUriPermissions.size(); 6686 for (int i = 0; i < N; i++) { 6687 final int targetUid = mGrantedUriPermissions.keyAt(i); 6688 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6689 6690 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6691 final UriPermission perm = it.next(); 6692 if (perm.uri.sourceUserId == grantUri.sourceUserId 6693 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6694 if (DEBUG_URI_PERMISSION) 6695 Slog.v(TAG, 6696 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6697 persistChanged |= perm.revokeModes( 6698 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6699 if (perm.modeFlags == 0) { 6700 it.remove(); 6701 } 6702 } 6703 } 6704 6705 if (perms.isEmpty()) { 6706 mGrantedUriPermissions.remove(targetUid); 6707 N--; 6708 i--; 6709 } 6710 } 6711 6712 if (persistChanged) { 6713 schedulePersistUriGrants(); 6714 } 6715 } 6716 6717 @Override 6718 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6719 int userId) { 6720 enforceNotIsolatedCaller("revokeUriPermission"); 6721 synchronized(this) { 6722 final ProcessRecord r = getRecordForAppLocked(caller); 6723 if (r == null) { 6724 throw new SecurityException("Unable to find app for caller " 6725 + caller 6726 + " when revoking permission to uri " + uri); 6727 } 6728 if (uri == null) { 6729 Slog.w(TAG, "revokeUriPermission: null uri"); 6730 return; 6731 } 6732 6733 if (!Intent.isAccessUriMode(modeFlags)) { 6734 return; 6735 } 6736 6737 final IPackageManager pm = AppGlobals.getPackageManager(); 6738 final String authority = uri.getAuthority(); 6739 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6740 if (pi == null) { 6741 Slog.w(TAG, "No content provider found for permission revoke: " 6742 + uri.toSafeString()); 6743 return; 6744 } 6745 6746 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6747 } 6748 } 6749 6750 /** 6751 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6752 * given package. 6753 * 6754 * @param packageName Package name to match, or {@code null} to apply to all 6755 * packages. 6756 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6757 * to all users. 6758 * @param persistable If persistable grants should be removed. 6759 */ 6760 private void removeUriPermissionsForPackageLocked( 6761 String packageName, int userHandle, boolean persistable) { 6762 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6763 throw new IllegalArgumentException("Must narrow by either package or user"); 6764 } 6765 6766 boolean persistChanged = false; 6767 6768 int N = mGrantedUriPermissions.size(); 6769 for (int i = 0; i < N; i++) { 6770 final int targetUid = mGrantedUriPermissions.keyAt(i); 6771 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6772 6773 // Only inspect grants matching user 6774 if (userHandle == UserHandle.USER_ALL 6775 || userHandle == UserHandle.getUserId(targetUid)) { 6776 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6777 final UriPermission perm = it.next(); 6778 6779 // Only inspect grants matching package 6780 if (packageName == null || perm.sourcePkg.equals(packageName) 6781 || perm.targetPkg.equals(packageName)) { 6782 persistChanged |= perm.revokeModes( 6783 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6784 6785 // Only remove when no modes remain; any persisted grants 6786 // will keep this alive. 6787 if (perm.modeFlags == 0) { 6788 it.remove(); 6789 } 6790 } 6791 } 6792 6793 if (perms.isEmpty()) { 6794 mGrantedUriPermissions.remove(targetUid); 6795 N--; 6796 i--; 6797 } 6798 } 6799 } 6800 6801 if (persistChanged) { 6802 schedulePersistUriGrants(); 6803 } 6804 } 6805 6806 @Override 6807 public IBinder newUriPermissionOwner(String name) { 6808 enforceNotIsolatedCaller("newUriPermissionOwner"); 6809 synchronized(this) { 6810 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6811 return owner.getExternalTokenLocked(); 6812 } 6813 } 6814 6815 @Override 6816 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6817 final int modeFlags, int userId) { 6818 synchronized(this) { 6819 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6820 if (owner == null) { 6821 throw new IllegalArgumentException("Unknown owner: " + token); 6822 } 6823 if (fromUid != Binder.getCallingUid()) { 6824 if (Binder.getCallingUid() != Process.myUid()) { 6825 // Only system code can grant URI permissions on behalf 6826 // of other users. 6827 throw new SecurityException("nice try"); 6828 } 6829 } 6830 if (targetPkg == null) { 6831 throw new IllegalArgumentException("null target"); 6832 } 6833 if (uri == null) { 6834 throw new IllegalArgumentException("null uri"); 6835 } 6836 6837 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6838 modeFlags, owner); 6839 } 6840 } 6841 6842 @Override 6843 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6844 synchronized(this) { 6845 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6846 if (owner == null) { 6847 throw new IllegalArgumentException("Unknown owner: " + token); 6848 } 6849 6850 if (uri == null) { 6851 owner.removeUriPermissionsLocked(mode); 6852 } else { 6853 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6854 } 6855 } 6856 } 6857 6858 private void schedulePersistUriGrants() { 6859 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6860 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6861 10 * DateUtils.SECOND_IN_MILLIS); 6862 } 6863 } 6864 6865 private void writeGrantedUriPermissions() { 6866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6867 6868 // Snapshot permissions so we can persist without lock 6869 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6870 synchronized (this) { 6871 final int size = mGrantedUriPermissions.size(); 6872 for (int i = 0; i < size; i++) { 6873 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6874 for (UriPermission perm : perms.values()) { 6875 if (perm.persistedModeFlags != 0) { 6876 persist.add(perm.snapshot()); 6877 } 6878 } 6879 } 6880 } 6881 6882 FileOutputStream fos = null; 6883 try { 6884 fos = mGrantFile.startWrite(); 6885 6886 XmlSerializer out = new FastXmlSerializer(); 6887 out.setOutput(fos, "utf-8"); 6888 out.startDocument(null, true); 6889 out.startTag(null, TAG_URI_GRANTS); 6890 for (UriPermission.Snapshot perm : persist) { 6891 out.startTag(null, TAG_URI_GRANT); 6892 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6893 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6894 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6895 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6896 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6897 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6898 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6899 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6900 out.endTag(null, TAG_URI_GRANT); 6901 } 6902 out.endTag(null, TAG_URI_GRANTS); 6903 out.endDocument(); 6904 6905 mGrantFile.finishWrite(fos); 6906 } catch (IOException e) { 6907 if (fos != null) { 6908 mGrantFile.failWrite(fos); 6909 } 6910 } 6911 } 6912 6913 private void readGrantedUriPermissionsLocked() { 6914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6915 6916 final long now = System.currentTimeMillis(); 6917 6918 FileInputStream fis = null; 6919 try { 6920 fis = mGrantFile.openRead(); 6921 final XmlPullParser in = Xml.newPullParser(); 6922 in.setInput(fis, null); 6923 6924 int type; 6925 while ((type = in.next()) != END_DOCUMENT) { 6926 final String tag = in.getName(); 6927 if (type == START_TAG) { 6928 if (TAG_URI_GRANT.equals(tag)) { 6929 final int sourceUserId; 6930 final int targetUserId; 6931 final int userHandle = readIntAttribute(in, 6932 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6933 if (userHandle != UserHandle.USER_NULL) { 6934 // For backwards compatibility. 6935 sourceUserId = userHandle; 6936 targetUserId = userHandle; 6937 } else { 6938 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6939 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6940 } 6941 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6942 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6943 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6944 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6945 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6946 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6947 6948 // Sanity check that provider still belongs to source package 6949 final ProviderInfo pi = getProviderInfoLocked( 6950 uri.getAuthority(), sourceUserId); 6951 if (pi != null && sourcePkg.equals(pi.packageName)) { 6952 int targetUid = -1; 6953 try { 6954 targetUid = AppGlobals.getPackageManager() 6955 .getPackageUid(targetPkg, targetUserId); 6956 } catch (RemoteException e) { 6957 } 6958 if (targetUid != -1) { 6959 final UriPermission perm = findOrCreateUriPermissionLocked( 6960 sourcePkg, targetPkg, targetUid, 6961 new GrantUri(sourceUserId, uri, prefix)); 6962 perm.initPersistedModes(modeFlags, createdTime); 6963 } 6964 } else { 6965 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6966 + " but instead found " + pi); 6967 } 6968 } 6969 } 6970 } 6971 } catch (FileNotFoundException e) { 6972 // Missing grants is okay 6973 } catch (IOException e) { 6974 Log.wtf(TAG, "Failed reading Uri grants", e); 6975 } catch (XmlPullParserException e) { 6976 Log.wtf(TAG, "Failed reading Uri grants", e); 6977 } finally { 6978 IoUtils.closeQuietly(fis); 6979 } 6980 } 6981 6982 @Override 6983 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6984 enforceNotIsolatedCaller("takePersistableUriPermission"); 6985 6986 Preconditions.checkFlagsArgument(modeFlags, 6987 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6988 6989 synchronized (this) { 6990 final int callingUid = Binder.getCallingUid(); 6991 boolean persistChanged = false; 6992 GrantUri grantUri = new GrantUri(userId, uri, false); 6993 6994 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6995 new GrantUri(userId, uri, false)); 6996 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6997 new GrantUri(userId, uri, true)); 6998 6999 final boolean exactValid = (exactPerm != null) 7000 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7001 final boolean prefixValid = (prefixPerm != null) 7002 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7003 7004 if (!(exactValid || prefixValid)) { 7005 throw new SecurityException("No persistable permission grants found for UID " 7006 + callingUid + " and Uri " + grantUri.toSafeString()); 7007 } 7008 7009 if (exactValid) { 7010 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7011 } 7012 if (prefixValid) { 7013 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7014 } 7015 7016 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7017 7018 if (persistChanged) { 7019 schedulePersistUriGrants(); 7020 } 7021 } 7022 } 7023 7024 @Override 7025 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7026 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7027 7028 Preconditions.checkFlagsArgument(modeFlags, 7029 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7030 7031 synchronized (this) { 7032 final int callingUid = Binder.getCallingUid(); 7033 boolean persistChanged = false; 7034 7035 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7036 new GrantUri(userId, uri, false)); 7037 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7038 new GrantUri(userId, uri, true)); 7039 if (exactPerm == null && prefixPerm == null) { 7040 throw new SecurityException("No permission grants found for UID " + callingUid 7041 + " and Uri " + uri.toSafeString()); 7042 } 7043 7044 if (exactPerm != null) { 7045 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7046 removeUriPermissionIfNeededLocked(exactPerm); 7047 } 7048 if (prefixPerm != null) { 7049 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7050 removeUriPermissionIfNeededLocked(prefixPerm); 7051 } 7052 7053 if (persistChanged) { 7054 schedulePersistUriGrants(); 7055 } 7056 } 7057 } 7058 7059 /** 7060 * Prune any older {@link UriPermission} for the given UID until outstanding 7061 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7062 * 7063 * @return if any mutations occured that require persisting. 7064 */ 7065 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7066 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7067 if (perms == null) return false; 7068 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7069 7070 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7071 for (UriPermission perm : perms.values()) { 7072 if (perm.persistedModeFlags != 0) { 7073 persisted.add(perm); 7074 } 7075 } 7076 7077 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7078 if (trimCount <= 0) return false; 7079 7080 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7081 for (int i = 0; i < trimCount; i++) { 7082 final UriPermission perm = persisted.get(i); 7083 7084 if (DEBUG_URI_PERMISSION) { 7085 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7086 } 7087 7088 perm.releasePersistableModes(~0); 7089 removeUriPermissionIfNeededLocked(perm); 7090 } 7091 7092 return true; 7093 } 7094 7095 @Override 7096 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7097 String packageName, boolean incoming) { 7098 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7099 Preconditions.checkNotNull(packageName, "packageName"); 7100 7101 final int callingUid = Binder.getCallingUid(); 7102 final IPackageManager pm = AppGlobals.getPackageManager(); 7103 try { 7104 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7105 if (packageUid != callingUid) { 7106 throw new SecurityException( 7107 "Package " + packageName + " does not belong to calling UID " + callingUid); 7108 } 7109 } catch (RemoteException e) { 7110 throw new SecurityException("Failed to verify package name ownership"); 7111 } 7112 7113 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7114 synchronized (this) { 7115 if (incoming) { 7116 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7117 callingUid); 7118 if (perms == null) { 7119 Slog.w(TAG, "No permission grants found for " + packageName); 7120 } else { 7121 for (UriPermission perm : perms.values()) { 7122 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7123 result.add(perm.buildPersistedPublicApiObject()); 7124 } 7125 } 7126 } 7127 } else { 7128 final int size = mGrantedUriPermissions.size(); 7129 for (int i = 0; i < size; i++) { 7130 final ArrayMap<GrantUri, UriPermission> perms = 7131 mGrantedUriPermissions.valueAt(i); 7132 for (UriPermission perm : perms.values()) { 7133 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7134 result.add(perm.buildPersistedPublicApiObject()); 7135 } 7136 } 7137 } 7138 } 7139 } 7140 return new ParceledListSlice<android.content.UriPermission>(result); 7141 } 7142 7143 @Override 7144 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7145 synchronized (this) { 7146 ProcessRecord app = 7147 who != null ? getRecordForAppLocked(who) : null; 7148 if (app == null) return; 7149 7150 Message msg = Message.obtain(); 7151 msg.what = WAIT_FOR_DEBUGGER_MSG; 7152 msg.obj = app; 7153 msg.arg1 = waiting ? 1 : 0; 7154 mHandler.sendMessage(msg); 7155 } 7156 } 7157 7158 @Override 7159 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7160 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7161 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7162 outInfo.availMem = Process.getFreeMemory(); 7163 outInfo.totalMem = Process.getTotalMemory(); 7164 outInfo.threshold = homeAppMem; 7165 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7166 outInfo.hiddenAppThreshold = cachedAppMem; 7167 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7168 ProcessList.SERVICE_ADJ); 7169 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7170 ProcessList.VISIBLE_APP_ADJ); 7171 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7172 ProcessList.FOREGROUND_APP_ADJ); 7173 } 7174 7175 // ========================================================= 7176 // TASK MANAGEMENT 7177 // ========================================================= 7178 7179 @Override 7180 public List<IAppTask> getAppTasks() { 7181 final PackageManager pm = mContext.getPackageManager(); 7182 int callingUid = Binder.getCallingUid(); 7183 long ident = Binder.clearCallingIdentity(); 7184 7185 // Compose the list of packages for this id to test against 7186 HashSet<String> packages = new HashSet<String>(); 7187 String[] uidPackages = pm.getPackagesForUid(callingUid); 7188 for (int i = 0; i < uidPackages.length; i++) { 7189 packages.add(uidPackages[i]); 7190 } 7191 7192 synchronized(this) { 7193 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7194 try { 7195 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7196 7197 final int N = mRecentTasks.size(); 7198 for (int i = 0; i < N; i++) { 7199 TaskRecord tr = mRecentTasks.get(i); 7200 // Skip tasks that are not created by the caller 7201 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7202 ActivityManager.RecentTaskInfo taskInfo = 7203 createRecentTaskInfoFromTaskRecord(tr); 7204 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7205 list.add(taskImpl); 7206 } 7207 } 7208 } finally { 7209 Binder.restoreCallingIdentity(ident); 7210 } 7211 return list; 7212 } 7213 } 7214 7215 @Override 7216 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7217 final int callingUid = Binder.getCallingUid(); 7218 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7219 7220 synchronized(this) { 7221 if (localLOGV) Slog.v( 7222 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7223 7224 final boolean allowed = checkCallingPermission( 7225 android.Manifest.permission.GET_TASKS) 7226 == PackageManager.PERMISSION_GRANTED; 7227 if (!allowed) { 7228 Slog.w(TAG, "getTasks: caller " + callingUid 7229 + " does not hold GET_TASKS; limiting output"); 7230 } 7231 7232 // TODO: Improve with MRU list from all ActivityStacks. 7233 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7234 } 7235 7236 return list; 7237 } 7238 7239 TaskRecord getMostRecentTask() { 7240 return mRecentTasks.get(0); 7241 } 7242 7243 /** 7244 * Creates a new RecentTaskInfo from a TaskRecord. 7245 */ 7246 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7247 // Update the task description to reflect any changes in the task stack 7248 tr.updateTaskDescription(); 7249 7250 // Compose the recent task info 7251 ActivityManager.RecentTaskInfo rti 7252 = new ActivityManager.RecentTaskInfo(); 7253 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7254 rti.persistentId = tr.taskId; 7255 rti.baseIntent = new Intent(tr.getBaseIntent()); 7256 rti.origActivity = tr.origActivity; 7257 rti.description = tr.lastDescription; 7258 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7259 rti.userId = tr.userId; 7260 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7261 rti.firstActiveTime = tr.firstActiveTime; 7262 rti.lastActiveTime = tr.lastActiveTime; 7263 return rti; 7264 } 7265 7266 @Override 7267 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7268 int flags, int userId) { 7269 final int callingUid = Binder.getCallingUid(); 7270 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7271 false, true, "getRecentTasks", null); 7272 7273 synchronized (this) { 7274 final boolean allowed = checkCallingPermission( 7275 android.Manifest.permission.GET_TASKS) 7276 == PackageManager.PERMISSION_GRANTED; 7277 if (!allowed) { 7278 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7279 + " does not hold GET_TASKS; limiting output"); 7280 } 7281 final boolean detailed = checkCallingPermission( 7282 android.Manifest.permission.GET_DETAILED_TASKS) 7283 == PackageManager.PERMISSION_GRANTED; 7284 7285 IPackageManager pm = AppGlobals.getPackageManager(); 7286 7287 final int N = mRecentTasks.size(); 7288 ArrayList<ActivityManager.RecentTaskInfo> res 7289 = new ArrayList<ActivityManager.RecentTaskInfo>( 7290 maxNum < N ? maxNum : N); 7291 7292 final Set<Integer> includedUsers; 7293 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7294 includedUsers = getProfileIdsLocked(userId); 7295 } else { 7296 includedUsers = new HashSet<Integer>(); 7297 } 7298 includedUsers.add(Integer.valueOf(userId)); 7299 for (int i=0; i<N && maxNum > 0; i++) { 7300 TaskRecord tr = mRecentTasks.get(i); 7301 // Only add calling user or related users recent tasks 7302 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7303 7304 // Return the entry if desired by the caller. We always return 7305 // the first entry, because callers always expect this to be the 7306 // foreground app. We may filter others if the caller has 7307 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7308 // we should exclude the entry. 7309 7310 if (i == 0 7311 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7312 || (tr.intent == null) 7313 || ((tr.intent.getFlags() 7314 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7315 if (!allowed) { 7316 // If the caller doesn't have the GET_TASKS permission, then only 7317 // allow them to see a small subset of tasks -- their own and home. 7318 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7319 continue; 7320 } 7321 } 7322 if (tr.intent != null && 7323 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7324 != 0 && tr.getTopActivity() == null) { 7325 // Don't include auto remove tasks that are finished or finishing. 7326 continue; 7327 } 7328 7329 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7330 if (!detailed) { 7331 rti.baseIntent.replaceExtras((Bundle)null); 7332 } 7333 7334 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7335 // Check whether this activity is currently available. 7336 try { 7337 if (rti.origActivity != null) { 7338 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7339 == null) { 7340 continue; 7341 } 7342 } else if (rti.baseIntent != null) { 7343 if (pm.queryIntentActivities(rti.baseIntent, 7344 null, 0, userId) == null) { 7345 continue; 7346 } 7347 } 7348 } catch (RemoteException e) { 7349 // Will never happen. 7350 } 7351 } 7352 7353 res.add(rti); 7354 maxNum--; 7355 } 7356 } 7357 return res; 7358 } 7359 } 7360 7361 private TaskRecord recentTaskForIdLocked(int id) { 7362 final int N = mRecentTasks.size(); 7363 for (int i=0; i<N; i++) { 7364 TaskRecord tr = mRecentTasks.get(i); 7365 if (tr.taskId == id) { 7366 return tr; 7367 } 7368 } 7369 return null; 7370 } 7371 7372 @Override 7373 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7374 synchronized (this) { 7375 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7376 "getTaskThumbnail()"); 7377 TaskRecord tr = recentTaskForIdLocked(id); 7378 if (tr != null) { 7379 return tr.getTaskThumbnailLocked(); 7380 } 7381 } 7382 return null; 7383 } 7384 7385 @Override 7386 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7387 synchronized (this) { 7388 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7389 if (r != null) { 7390 r.taskDescription = td; 7391 r.task.updateTaskDescription(); 7392 } 7393 } 7394 } 7395 7396 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7397 if (!pr.killedByAm) { 7398 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7399 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7400 pr.processName, pr.setAdj, reason); 7401 pr.killedByAm = true; 7402 Process.killProcessQuiet(pr.pid); 7403 } 7404 } 7405 7406 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7407 tr.disposeThumbnail(); 7408 mRecentTasks.remove(tr); 7409 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7410 Intent baseIntent = new Intent( 7411 tr.intent != null ? tr.intent : tr.affinityIntent); 7412 ComponentName component = baseIntent.getComponent(); 7413 if (component == null) { 7414 Slog.w(TAG, "Now component for base intent of task: " + tr); 7415 return; 7416 } 7417 7418 // Find any running services associated with this app. 7419 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7420 7421 if (killProcesses) { 7422 // Find any running processes associated with this app. 7423 final String pkg = component.getPackageName(); 7424 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7425 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7426 for (int i=0; i<pmap.size(); i++) { 7427 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7428 for (int j=0; j<uids.size(); j++) { 7429 ProcessRecord proc = uids.valueAt(j); 7430 if (proc.userId != tr.userId) { 7431 continue; 7432 } 7433 if (!proc.pkgList.containsKey(pkg)) { 7434 continue; 7435 } 7436 procs.add(proc); 7437 } 7438 } 7439 7440 // Kill the running processes. 7441 for (int i=0; i<procs.size(); i++) { 7442 ProcessRecord pr = procs.get(i); 7443 if (pr == mHomeProcess) { 7444 // Don't kill the home process along with tasks from the same package. 7445 continue; 7446 } 7447 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7448 killUnneededProcessLocked(pr, "remove task"); 7449 } else { 7450 pr.waitingToKill = "remove task"; 7451 } 7452 } 7453 } 7454 } 7455 7456 /** 7457 * Removes the task with the specified task id. 7458 * 7459 * @param taskId Identifier of the task to be removed. 7460 * @param flags Additional operational flags. May be 0 or 7461 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7462 * @return Returns true if the given task was found and removed. 7463 */ 7464 private boolean removeTaskByIdLocked(int taskId, int flags) { 7465 TaskRecord tr = recentTaskForIdLocked(taskId); 7466 if (tr != null) { 7467 tr.removeTaskActivitiesLocked(); 7468 cleanUpRemovedTaskLocked(tr, flags); 7469 if (tr.isPersistable) { 7470 notifyTaskPersisterLocked(tr, true); 7471 } 7472 return true; 7473 } 7474 return false; 7475 } 7476 7477 @Override 7478 public boolean removeTask(int taskId, int flags) { 7479 synchronized (this) { 7480 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7481 "removeTask()"); 7482 long ident = Binder.clearCallingIdentity(); 7483 try { 7484 return removeTaskByIdLocked(taskId, flags); 7485 } finally { 7486 Binder.restoreCallingIdentity(ident); 7487 } 7488 } 7489 } 7490 7491 /** 7492 * TODO: Add mController hook 7493 */ 7494 @Override 7495 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7496 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7497 "moveTaskToFront()"); 7498 7499 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7500 synchronized(this) { 7501 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7502 Binder.getCallingUid(), "Task to front")) { 7503 ActivityOptions.abort(options); 7504 return; 7505 } 7506 final long origId = Binder.clearCallingIdentity(); 7507 try { 7508 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7509 if (task == null) { 7510 return; 7511 } 7512 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7513 mStackSupervisor.showLockTaskToast(); 7514 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7515 return; 7516 } 7517 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7518 if (prev != null && prev.isRecentsActivity()) { 7519 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7520 } 7521 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7522 } finally { 7523 Binder.restoreCallingIdentity(origId); 7524 } 7525 ActivityOptions.abort(options); 7526 } 7527 } 7528 7529 @Override 7530 public void moveTaskToBack(int taskId) { 7531 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7532 "moveTaskToBack()"); 7533 7534 synchronized(this) { 7535 TaskRecord tr = recentTaskForIdLocked(taskId); 7536 if (tr != null) { 7537 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7538 ActivityStack stack = tr.stack; 7539 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7540 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7541 Binder.getCallingUid(), "Task to back")) { 7542 return; 7543 } 7544 } 7545 final long origId = Binder.clearCallingIdentity(); 7546 try { 7547 stack.moveTaskToBackLocked(taskId, null); 7548 } finally { 7549 Binder.restoreCallingIdentity(origId); 7550 } 7551 } 7552 } 7553 } 7554 7555 /** 7556 * Moves an activity, and all of the other activities within the same task, to the bottom 7557 * of the history stack. The activity's order within the task is unchanged. 7558 * 7559 * @param token A reference to the activity we wish to move 7560 * @param nonRoot If false then this only works if the activity is the root 7561 * of a task; if true it will work for any activity in a task. 7562 * @return Returns true if the move completed, false if not. 7563 */ 7564 @Override 7565 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7566 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7567 synchronized(this) { 7568 final long origId = Binder.clearCallingIdentity(); 7569 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7570 if (taskId >= 0) { 7571 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7572 } 7573 Binder.restoreCallingIdentity(origId); 7574 } 7575 return false; 7576 } 7577 7578 @Override 7579 public void moveTaskBackwards(int task) { 7580 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7581 "moveTaskBackwards()"); 7582 7583 synchronized(this) { 7584 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7585 Binder.getCallingUid(), "Task backwards")) { 7586 return; 7587 } 7588 final long origId = Binder.clearCallingIdentity(); 7589 moveTaskBackwardsLocked(task); 7590 Binder.restoreCallingIdentity(origId); 7591 } 7592 } 7593 7594 private final void moveTaskBackwardsLocked(int task) { 7595 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7596 } 7597 7598 @Override 7599 public IBinder getHomeActivityToken() throws RemoteException { 7600 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7601 "getHomeActivityToken()"); 7602 synchronized (this) { 7603 return mStackSupervisor.getHomeActivityToken(); 7604 } 7605 } 7606 7607 @Override 7608 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7609 IActivityContainerCallback callback) throws RemoteException { 7610 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7611 "createActivityContainer()"); 7612 synchronized (this) { 7613 if (parentActivityToken == null) { 7614 throw new IllegalArgumentException("parent token must not be null"); 7615 } 7616 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7617 if (r == null) { 7618 return null; 7619 } 7620 if (callback == null) { 7621 throw new IllegalArgumentException("callback must not be null"); 7622 } 7623 return mStackSupervisor.createActivityContainer(r, callback); 7624 } 7625 } 7626 7627 @Override 7628 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7629 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7630 "deleteActivityContainer()"); 7631 synchronized (this) { 7632 mStackSupervisor.deleteActivityContainer(container); 7633 } 7634 } 7635 7636 @Override 7637 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7638 throws RemoteException { 7639 synchronized (this) { 7640 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7641 if (stack != null) { 7642 return stack.mActivityContainer; 7643 } 7644 return null; 7645 } 7646 } 7647 7648 @Override 7649 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7650 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7651 "moveTaskToStack()"); 7652 if (stackId == HOME_STACK_ID) { 7653 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7654 new RuntimeException("here").fillInStackTrace()); 7655 } 7656 synchronized (this) { 7657 long ident = Binder.clearCallingIdentity(); 7658 try { 7659 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7660 + stackId + " toTop=" + toTop); 7661 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7662 } finally { 7663 Binder.restoreCallingIdentity(ident); 7664 } 7665 } 7666 } 7667 7668 @Override 7669 public void resizeStack(int stackBoxId, Rect bounds) { 7670 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7671 "resizeStackBox()"); 7672 long ident = Binder.clearCallingIdentity(); 7673 try { 7674 mWindowManager.resizeStack(stackBoxId, bounds); 7675 } finally { 7676 Binder.restoreCallingIdentity(ident); 7677 } 7678 } 7679 7680 @Override 7681 public List<StackInfo> getAllStackInfos() { 7682 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7683 "getAllStackInfos()"); 7684 long ident = Binder.clearCallingIdentity(); 7685 try { 7686 synchronized (this) { 7687 return mStackSupervisor.getAllStackInfosLocked(); 7688 } 7689 } finally { 7690 Binder.restoreCallingIdentity(ident); 7691 } 7692 } 7693 7694 @Override 7695 public StackInfo getStackInfo(int stackId) { 7696 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7697 "getStackInfo()"); 7698 long ident = Binder.clearCallingIdentity(); 7699 try { 7700 synchronized (this) { 7701 return mStackSupervisor.getStackInfoLocked(stackId); 7702 } 7703 } finally { 7704 Binder.restoreCallingIdentity(ident); 7705 } 7706 } 7707 7708 @Override 7709 public boolean isInHomeStack(int taskId) { 7710 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7711 "getStackInfo()"); 7712 long ident = Binder.clearCallingIdentity(); 7713 try { 7714 synchronized (this) { 7715 TaskRecord tr = recentTaskForIdLocked(taskId); 7716 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7717 } 7718 } finally { 7719 Binder.restoreCallingIdentity(ident); 7720 } 7721 } 7722 7723 @Override 7724 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7725 synchronized(this) { 7726 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7727 } 7728 } 7729 7730 private boolean isLockTaskAuthorized(String pkg) { 7731 final DevicePolicyManager dpm = (DevicePolicyManager) 7732 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7733 try { 7734 int uid = mContext.getPackageManager().getPackageUid(pkg, 7735 Binder.getCallingUserHandle().getIdentifier()); 7736 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7737 } catch (NameNotFoundException e) { 7738 return false; 7739 } 7740 } 7741 7742 void startLockTaskMode(TaskRecord task) { 7743 final String pkg; 7744 synchronized (this) { 7745 pkg = task.intent.getComponent().getPackageName(); 7746 } 7747 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7748 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7749 final TaskRecord taskRecord = task; 7750 mHandler.post(new Runnable() { 7751 @Override 7752 public void run() { 7753 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7754 } 7755 }); 7756 return; 7757 } 7758 long ident = Binder.clearCallingIdentity(); 7759 try { 7760 synchronized (this) { 7761 // Since we lost lock on task, make sure it is still there. 7762 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7763 if (task != null) { 7764 if (!isSystemInitiated 7765 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7766 throw new IllegalArgumentException("Invalid task, not in foreground"); 7767 } 7768 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7769 } 7770 } 7771 } finally { 7772 Binder.restoreCallingIdentity(ident); 7773 } 7774 } 7775 7776 @Override 7777 public void startLockTaskMode(int taskId) { 7778 final TaskRecord task; 7779 long ident = Binder.clearCallingIdentity(); 7780 try { 7781 synchronized (this) { 7782 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7783 } 7784 } finally { 7785 Binder.restoreCallingIdentity(ident); 7786 } 7787 if (task != null) { 7788 startLockTaskMode(task); 7789 } 7790 } 7791 7792 @Override 7793 public void startLockTaskMode(IBinder token) { 7794 final TaskRecord task; 7795 long ident = Binder.clearCallingIdentity(); 7796 try { 7797 synchronized (this) { 7798 final ActivityRecord r = ActivityRecord.forToken(token); 7799 if (r == null) { 7800 return; 7801 } 7802 task = r.task; 7803 } 7804 } finally { 7805 Binder.restoreCallingIdentity(ident); 7806 } 7807 if (task != null) { 7808 startLockTaskMode(task); 7809 } 7810 } 7811 7812 @Override 7813 public void startLockTaskModeOnCurrent() throws RemoteException { 7814 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7815 ActivityRecord r = null; 7816 synchronized (this) { 7817 r = mStackSupervisor.topRunningActivityLocked(); 7818 } 7819 startLockTaskMode(r.task); 7820 } 7821 7822 @Override 7823 public void stopLockTaskMode() { 7824 // Verify that the user matches the package of the intent for the TaskRecord 7825 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7826 // and stopLockTaskMode. 7827 final int callingUid = Binder.getCallingUid(); 7828 if (callingUid != Process.SYSTEM_UID) { 7829 try { 7830 String pkg = 7831 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7832 int uid = mContext.getPackageManager().getPackageUid(pkg, 7833 Binder.getCallingUserHandle().getIdentifier()); 7834 if (uid != callingUid) { 7835 throw new SecurityException("Invalid uid, expected " + uid); 7836 } 7837 } catch (NameNotFoundException e) { 7838 Log.d(TAG, "stopLockTaskMode " + e); 7839 return; 7840 } 7841 } 7842 long ident = Binder.clearCallingIdentity(); 7843 try { 7844 Log.d(TAG, "stopLockTaskMode"); 7845 // Stop lock task 7846 synchronized (this) { 7847 mStackSupervisor.setLockTaskModeLocked(null, false); 7848 } 7849 } finally { 7850 Binder.restoreCallingIdentity(ident); 7851 } 7852 } 7853 7854 @Override 7855 public void stopLockTaskModeOnCurrent() throws RemoteException { 7856 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7857 long ident = Binder.clearCallingIdentity(); 7858 try { 7859 stopLockTaskMode(); 7860 } finally { 7861 Binder.restoreCallingIdentity(ident); 7862 } 7863 } 7864 7865 @Override 7866 public boolean isInLockTaskMode() { 7867 synchronized (this) { 7868 return mStackSupervisor.isInLockTaskMode(); 7869 } 7870 } 7871 7872 // ========================================================= 7873 // CONTENT PROVIDERS 7874 // ========================================================= 7875 7876 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7877 List<ProviderInfo> providers = null; 7878 try { 7879 providers = AppGlobals.getPackageManager(). 7880 queryContentProviders(app.processName, app.uid, 7881 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7882 } catch (RemoteException ex) { 7883 } 7884 if (DEBUG_MU) 7885 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7886 int userId = app.userId; 7887 if (providers != null) { 7888 int N = providers.size(); 7889 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7890 for (int i=0; i<N; i++) { 7891 ProviderInfo cpi = 7892 (ProviderInfo)providers.get(i); 7893 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7894 cpi.name, cpi.flags); 7895 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7896 // This is a singleton provider, but a user besides the 7897 // default user is asking to initialize a process it runs 7898 // in... well, no, it doesn't actually run in this process, 7899 // it runs in the process of the default user. Get rid of it. 7900 providers.remove(i); 7901 N--; 7902 i--; 7903 continue; 7904 } 7905 7906 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7907 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7908 if (cpr == null) { 7909 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7910 mProviderMap.putProviderByClass(comp, cpr); 7911 } 7912 if (DEBUG_MU) 7913 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7914 app.pubProviders.put(cpi.name, cpr); 7915 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7916 // Don't add this if it is a platform component that is marked 7917 // to run in multiple processes, because this is actually 7918 // part of the framework so doesn't make sense to track as a 7919 // separate apk in the process. 7920 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7921 mProcessStats); 7922 } 7923 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7924 } 7925 } 7926 return providers; 7927 } 7928 7929 /** 7930 * Check if {@link ProcessRecord} has a possible chance at accessing the 7931 * given {@link ProviderInfo}. Final permission checking is always done 7932 * in {@link ContentProvider}. 7933 */ 7934 private final String checkContentProviderPermissionLocked( 7935 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7936 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7937 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7938 boolean checkedGrants = false; 7939 if (checkUser) { 7940 // Looking for cross-user grants before enforcing the typical cross-users permissions 7941 if (UserHandle.getUserId(callingUid) != userId) { 7942 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7943 return null; 7944 } 7945 checkedGrants = true; 7946 } 7947 userId = handleIncomingUser(callingPid, callingUid, userId, 7948 false, false, "checkContentProviderPermissionLocked " + cpi.authority, null); 7949 } 7950 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7951 cpi.applicationInfo.uid, cpi.exported) 7952 == PackageManager.PERMISSION_GRANTED) { 7953 return null; 7954 } 7955 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7956 cpi.applicationInfo.uid, cpi.exported) 7957 == PackageManager.PERMISSION_GRANTED) { 7958 return null; 7959 } 7960 7961 PathPermission[] pps = cpi.pathPermissions; 7962 if (pps != null) { 7963 int i = pps.length; 7964 while (i > 0) { 7965 i--; 7966 PathPermission pp = pps[i]; 7967 String pprperm = pp.getReadPermission(); 7968 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7969 cpi.applicationInfo.uid, cpi.exported) 7970 == PackageManager.PERMISSION_GRANTED) { 7971 return null; 7972 } 7973 String ppwperm = pp.getWritePermission(); 7974 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7975 cpi.applicationInfo.uid, cpi.exported) 7976 == PackageManager.PERMISSION_GRANTED) { 7977 return null; 7978 } 7979 } 7980 } 7981 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7982 return null; 7983 } 7984 7985 String msg; 7986 if (!cpi.exported) { 7987 msg = "Permission Denial: opening provider " + cpi.name 7988 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7989 + ", uid=" + callingUid + ") that is not exported from uid " 7990 + cpi.applicationInfo.uid; 7991 } else { 7992 msg = "Permission Denial: opening provider " + cpi.name 7993 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7994 + ", uid=" + callingUid + ") requires " 7995 + cpi.readPermission + " or " + cpi.writePermission; 7996 } 7997 Slog.w(TAG, msg); 7998 return msg; 7999 } 8000 8001 /** 8002 * Returns if the ContentProvider has granted a uri to callingUid 8003 */ 8004 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8005 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8006 if (perms != null) { 8007 for (GrantUri grantUri : perms.keySet()) { 8008 if (grantUri.sourceUserId == userId || !checkUser) { 8009 if (matchesProvider(grantUri.uri, cpi)) { 8010 return true; 8011 } 8012 } 8013 } 8014 } 8015 return false; 8016 } 8017 8018 /** 8019 * Returns true if the uri authority is one of the authorities specified in the provider. 8020 */ 8021 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8022 String uriAuth = uri.getAuthority(); 8023 String cpiAuth = cpi.authority; 8024 if (cpiAuth.indexOf(';') == -1) { 8025 return cpiAuth.equals(uriAuth); 8026 } 8027 String[] cpiAuths = cpiAuth.split(";"); 8028 int length = cpiAuths.length; 8029 for (int i = 0; i < length; i++) { 8030 if (cpiAuths[i].equals(uriAuth)) return true; 8031 } 8032 return false; 8033 } 8034 8035 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8036 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8037 if (r != null) { 8038 for (int i=0; i<r.conProviders.size(); i++) { 8039 ContentProviderConnection conn = r.conProviders.get(i); 8040 if (conn.provider == cpr) { 8041 if (DEBUG_PROVIDER) Slog.v(TAG, 8042 "Adding provider requested by " 8043 + r.processName + " from process " 8044 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8045 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8046 if (stable) { 8047 conn.stableCount++; 8048 conn.numStableIncs++; 8049 } else { 8050 conn.unstableCount++; 8051 conn.numUnstableIncs++; 8052 } 8053 return conn; 8054 } 8055 } 8056 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8057 if (stable) { 8058 conn.stableCount = 1; 8059 conn.numStableIncs = 1; 8060 } else { 8061 conn.unstableCount = 1; 8062 conn.numUnstableIncs = 1; 8063 } 8064 cpr.connections.add(conn); 8065 r.conProviders.add(conn); 8066 return conn; 8067 } 8068 cpr.addExternalProcessHandleLocked(externalProcessToken); 8069 return null; 8070 } 8071 8072 boolean decProviderCountLocked(ContentProviderConnection conn, 8073 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8074 if (conn != null) { 8075 cpr = conn.provider; 8076 if (DEBUG_PROVIDER) Slog.v(TAG, 8077 "Removing provider requested by " 8078 + conn.client.processName + " from process " 8079 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8080 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8081 if (stable) { 8082 conn.stableCount--; 8083 } else { 8084 conn.unstableCount--; 8085 } 8086 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8087 cpr.connections.remove(conn); 8088 conn.client.conProviders.remove(conn); 8089 return true; 8090 } 8091 return false; 8092 } 8093 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8094 return false; 8095 } 8096 8097 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8098 String name, IBinder token, boolean stable, int userId) { 8099 ContentProviderRecord cpr; 8100 ContentProviderConnection conn = null; 8101 ProviderInfo cpi = null; 8102 8103 synchronized(this) { 8104 ProcessRecord r = null; 8105 if (caller != null) { 8106 r = getRecordForAppLocked(caller); 8107 if (r == null) { 8108 throw new SecurityException( 8109 "Unable to find app for caller " + caller 8110 + " (pid=" + Binder.getCallingPid() 8111 + ") when getting content provider " + name); 8112 } 8113 } 8114 8115 boolean checkCrossUser = true; 8116 8117 // First check if this content provider has been published... 8118 cpr = mProviderMap.getProviderByName(name, userId); 8119 // If that didn't work, check if it exists for user 0 and then 8120 // verify that it's a singleton provider before using it. 8121 if (cpr == null && userId != UserHandle.USER_OWNER) { 8122 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8123 if (cpr != null) { 8124 cpi = cpr.info; 8125 if (isSingleton(cpi.processName, cpi.applicationInfo, 8126 cpi.name, cpi.flags) 8127 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8128 userId = UserHandle.USER_OWNER; 8129 checkCrossUser = false; 8130 } else { 8131 cpr = null; 8132 cpi = null; 8133 } 8134 } 8135 } 8136 8137 boolean providerRunning = cpr != null; 8138 if (providerRunning) { 8139 cpi = cpr.info; 8140 String msg; 8141 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8142 != null) { 8143 throw new SecurityException(msg); 8144 } 8145 8146 if (r != null && cpr.canRunHere(r)) { 8147 // This provider has been published or is in the process 8148 // of being published... but it is also allowed to run 8149 // in the caller's process, so don't make a connection 8150 // and just let the caller instantiate its own instance. 8151 ContentProviderHolder holder = cpr.newHolder(null); 8152 // don't give caller the provider object, it needs 8153 // to make its own. 8154 holder.provider = null; 8155 return holder; 8156 } 8157 8158 final long origId = Binder.clearCallingIdentity(); 8159 8160 // In this case the provider instance already exists, so we can 8161 // return it right away. 8162 conn = incProviderCountLocked(r, cpr, token, stable); 8163 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8164 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8165 // If this is a perceptible app accessing the provider, 8166 // make sure to count it as being accessed and thus 8167 // back up on the LRU list. This is good because 8168 // content providers are often expensive to start. 8169 updateLruProcessLocked(cpr.proc, false, null); 8170 } 8171 } 8172 8173 if (cpr.proc != null) { 8174 if (false) { 8175 if (cpr.name.flattenToShortString().equals( 8176 "com.android.providers.calendar/.CalendarProvider2")) { 8177 Slog.v(TAG, "****************** KILLING " 8178 + cpr.name.flattenToShortString()); 8179 Process.killProcess(cpr.proc.pid); 8180 } 8181 } 8182 boolean success = updateOomAdjLocked(cpr.proc); 8183 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8184 // NOTE: there is still a race here where a signal could be 8185 // pending on the process even though we managed to update its 8186 // adj level. Not sure what to do about this, but at least 8187 // the race is now smaller. 8188 if (!success) { 8189 // Uh oh... it looks like the provider's process 8190 // has been killed on us. We need to wait for a new 8191 // process to be started, and make sure its death 8192 // doesn't kill our process. 8193 Slog.i(TAG, 8194 "Existing provider " + cpr.name.flattenToShortString() 8195 + " is crashing; detaching " + r); 8196 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8197 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8198 if (!lastRef) { 8199 // This wasn't the last ref our process had on 8200 // the provider... we have now been killed, bail. 8201 return null; 8202 } 8203 providerRunning = false; 8204 conn = null; 8205 } 8206 } 8207 8208 Binder.restoreCallingIdentity(origId); 8209 } 8210 8211 boolean singleton; 8212 if (!providerRunning) { 8213 try { 8214 cpi = AppGlobals.getPackageManager(). 8215 resolveContentProvider(name, 8216 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8217 } catch (RemoteException ex) { 8218 } 8219 if (cpi == null) { 8220 return null; 8221 } 8222 // If the provider is a singleton AND 8223 // (it's a call within the same user || the provider is a 8224 // privileged app) 8225 // Then allow connecting to the singleton provider 8226 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8227 cpi.name, cpi.flags) 8228 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8229 if (singleton) { 8230 userId = UserHandle.USER_OWNER; 8231 } 8232 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8233 8234 String msg; 8235 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8236 != null) { 8237 throw new SecurityException(msg); 8238 } 8239 8240 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8241 && !cpi.processName.equals("system")) { 8242 // If this content provider does not run in the system 8243 // process, and the system is not yet ready to run other 8244 // processes, then fail fast instead of hanging. 8245 throw new IllegalArgumentException( 8246 "Attempt to launch content provider before system ready"); 8247 } 8248 8249 // Make sure that the user who owns this provider is started. If not, 8250 // we don't want to allow it to run. 8251 if (mStartedUsers.get(userId) == null) { 8252 Slog.w(TAG, "Unable to launch app " 8253 + cpi.applicationInfo.packageName + "/" 8254 + cpi.applicationInfo.uid + " for provider " 8255 + name + ": user " + userId + " is stopped"); 8256 return null; 8257 } 8258 8259 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8260 cpr = mProviderMap.getProviderByClass(comp, userId); 8261 final boolean firstClass = cpr == null; 8262 if (firstClass) { 8263 try { 8264 ApplicationInfo ai = 8265 AppGlobals.getPackageManager(). 8266 getApplicationInfo( 8267 cpi.applicationInfo.packageName, 8268 STOCK_PM_FLAGS, userId); 8269 if (ai == null) { 8270 Slog.w(TAG, "No package info for content provider " 8271 + cpi.name); 8272 return null; 8273 } 8274 ai = getAppInfoForUser(ai, userId); 8275 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8276 } catch (RemoteException ex) { 8277 // pm is in same process, this will never happen. 8278 } 8279 } 8280 8281 if (r != null && cpr.canRunHere(r)) { 8282 // If this is a multiprocess provider, then just return its 8283 // info and allow the caller to instantiate it. Only do 8284 // this if the provider is the same user as the caller's 8285 // process, or can run as root (so can be in any process). 8286 return cpr.newHolder(null); 8287 } 8288 8289 if (DEBUG_PROVIDER) { 8290 RuntimeException e = new RuntimeException("here"); 8291 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8292 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8293 } 8294 8295 // This is single process, and our app is now connecting to it. 8296 // See if we are already in the process of launching this 8297 // provider. 8298 final int N = mLaunchingProviders.size(); 8299 int i; 8300 for (i=0; i<N; i++) { 8301 if (mLaunchingProviders.get(i) == cpr) { 8302 break; 8303 } 8304 } 8305 8306 // If the provider is not already being launched, then get it 8307 // started. 8308 if (i >= N) { 8309 final long origId = Binder.clearCallingIdentity(); 8310 8311 try { 8312 // Content provider is now in use, its package can't be stopped. 8313 try { 8314 AppGlobals.getPackageManager().setPackageStoppedState( 8315 cpr.appInfo.packageName, false, userId); 8316 } catch (RemoteException e) { 8317 } catch (IllegalArgumentException e) { 8318 Slog.w(TAG, "Failed trying to unstop package " 8319 + cpr.appInfo.packageName + ": " + e); 8320 } 8321 8322 // Use existing process if already started 8323 ProcessRecord proc = getProcessRecordLocked( 8324 cpi.processName, cpr.appInfo.uid, false); 8325 if (proc != null && proc.thread != null) { 8326 if (DEBUG_PROVIDER) { 8327 Slog.d(TAG, "Installing in existing process " + proc); 8328 } 8329 proc.pubProviders.put(cpi.name, cpr); 8330 try { 8331 proc.thread.scheduleInstallProvider(cpi); 8332 } catch (RemoteException e) { 8333 } 8334 } else { 8335 proc = startProcessLocked(cpi.processName, 8336 cpr.appInfo, false, 0, "content provider", 8337 new ComponentName(cpi.applicationInfo.packageName, 8338 cpi.name), false, false, false); 8339 if (proc == null) { 8340 Slog.w(TAG, "Unable to launch app " 8341 + cpi.applicationInfo.packageName + "/" 8342 + cpi.applicationInfo.uid + " for provider " 8343 + name + ": process is bad"); 8344 return null; 8345 } 8346 } 8347 cpr.launchingApp = proc; 8348 mLaunchingProviders.add(cpr); 8349 } finally { 8350 Binder.restoreCallingIdentity(origId); 8351 } 8352 } 8353 8354 // Make sure the provider is published (the same provider class 8355 // may be published under multiple names). 8356 if (firstClass) { 8357 mProviderMap.putProviderByClass(comp, cpr); 8358 } 8359 8360 mProviderMap.putProviderByName(name, cpr); 8361 conn = incProviderCountLocked(r, cpr, token, stable); 8362 if (conn != null) { 8363 conn.waiting = true; 8364 } 8365 } 8366 } 8367 8368 // Wait for the provider to be published... 8369 synchronized (cpr) { 8370 while (cpr.provider == null) { 8371 if (cpr.launchingApp == null) { 8372 Slog.w(TAG, "Unable to launch app " 8373 + cpi.applicationInfo.packageName + "/" 8374 + cpi.applicationInfo.uid + " for provider " 8375 + name + ": launching app became null"); 8376 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8377 UserHandle.getUserId(cpi.applicationInfo.uid), 8378 cpi.applicationInfo.packageName, 8379 cpi.applicationInfo.uid, name); 8380 return null; 8381 } 8382 try { 8383 if (DEBUG_MU) { 8384 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8385 + cpr.launchingApp); 8386 } 8387 if (conn != null) { 8388 conn.waiting = true; 8389 } 8390 cpr.wait(); 8391 } catch (InterruptedException ex) { 8392 } finally { 8393 if (conn != null) { 8394 conn.waiting = false; 8395 } 8396 } 8397 } 8398 } 8399 return cpr != null ? cpr.newHolder(conn) : null; 8400 } 8401 8402 @Override 8403 public final ContentProviderHolder getContentProvider( 8404 IApplicationThread caller, String name, int userId, boolean stable) { 8405 enforceNotIsolatedCaller("getContentProvider"); 8406 if (caller == null) { 8407 String msg = "null IApplicationThread when getting content provider " 8408 + name; 8409 Slog.w(TAG, msg); 8410 throw new SecurityException(msg); 8411 } 8412 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8413 // with cross-user grant. 8414 return getContentProviderImpl(caller, name, null, stable, userId); 8415 } 8416 8417 public ContentProviderHolder getContentProviderExternal( 8418 String name, int userId, IBinder token) { 8419 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8420 "Do not have permission in call getContentProviderExternal()"); 8421 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8422 false, true, "getContentProvider", null); 8423 return getContentProviderExternalUnchecked(name, token, userId); 8424 } 8425 8426 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8427 IBinder token, int userId) { 8428 return getContentProviderImpl(null, name, token, true, userId); 8429 } 8430 8431 /** 8432 * Drop a content provider from a ProcessRecord's bookkeeping 8433 */ 8434 public void removeContentProvider(IBinder connection, boolean stable) { 8435 enforceNotIsolatedCaller("removeContentProvider"); 8436 long ident = Binder.clearCallingIdentity(); 8437 try { 8438 synchronized (this) { 8439 ContentProviderConnection conn; 8440 try { 8441 conn = (ContentProviderConnection)connection; 8442 } catch (ClassCastException e) { 8443 String msg ="removeContentProvider: " + connection 8444 + " not a ContentProviderConnection"; 8445 Slog.w(TAG, msg); 8446 throw new IllegalArgumentException(msg); 8447 } 8448 if (conn == null) { 8449 throw new NullPointerException("connection is null"); 8450 } 8451 if (decProviderCountLocked(conn, null, null, stable)) { 8452 updateOomAdjLocked(); 8453 } 8454 } 8455 } finally { 8456 Binder.restoreCallingIdentity(ident); 8457 } 8458 } 8459 8460 public void removeContentProviderExternal(String name, IBinder token) { 8461 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8462 "Do not have permission in call removeContentProviderExternal()"); 8463 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8464 } 8465 8466 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8467 synchronized (this) { 8468 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8469 if(cpr == null) { 8470 //remove from mProvidersByClass 8471 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8472 return; 8473 } 8474 8475 //update content provider record entry info 8476 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8477 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8478 if (localCpr.hasExternalProcessHandles()) { 8479 if (localCpr.removeExternalProcessHandleLocked(token)) { 8480 updateOomAdjLocked(); 8481 } else { 8482 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8483 + " with no external reference for token: " 8484 + token + "."); 8485 } 8486 } else { 8487 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8488 + " with no external references."); 8489 } 8490 } 8491 } 8492 8493 public final void publishContentProviders(IApplicationThread caller, 8494 List<ContentProviderHolder> providers) { 8495 if (providers == null) { 8496 return; 8497 } 8498 8499 enforceNotIsolatedCaller("publishContentProviders"); 8500 synchronized (this) { 8501 final ProcessRecord r = getRecordForAppLocked(caller); 8502 if (DEBUG_MU) 8503 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8504 if (r == null) { 8505 throw new SecurityException( 8506 "Unable to find app for caller " + caller 8507 + " (pid=" + Binder.getCallingPid() 8508 + ") when publishing content providers"); 8509 } 8510 8511 final long origId = Binder.clearCallingIdentity(); 8512 8513 final int N = providers.size(); 8514 for (int i=0; i<N; i++) { 8515 ContentProviderHolder src = providers.get(i); 8516 if (src == null || src.info == null || src.provider == null) { 8517 continue; 8518 } 8519 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8520 if (DEBUG_MU) 8521 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8522 if (dst != null) { 8523 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8524 mProviderMap.putProviderByClass(comp, dst); 8525 String names[] = dst.info.authority.split(";"); 8526 for (int j = 0; j < names.length; j++) { 8527 mProviderMap.putProviderByName(names[j], dst); 8528 } 8529 8530 int NL = mLaunchingProviders.size(); 8531 int j; 8532 for (j=0; j<NL; j++) { 8533 if (mLaunchingProviders.get(j) == dst) { 8534 mLaunchingProviders.remove(j); 8535 j--; 8536 NL--; 8537 } 8538 } 8539 synchronized (dst) { 8540 dst.provider = src.provider; 8541 dst.proc = r; 8542 dst.notifyAll(); 8543 } 8544 updateOomAdjLocked(r); 8545 } 8546 } 8547 8548 Binder.restoreCallingIdentity(origId); 8549 } 8550 } 8551 8552 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8553 ContentProviderConnection conn; 8554 try { 8555 conn = (ContentProviderConnection)connection; 8556 } catch (ClassCastException e) { 8557 String msg ="refContentProvider: " + connection 8558 + " not a ContentProviderConnection"; 8559 Slog.w(TAG, msg); 8560 throw new IllegalArgumentException(msg); 8561 } 8562 if (conn == null) { 8563 throw new NullPointerException("connection is null"); 8564 } 8565 8566 synchronized (this) { 8567 if (stable > 0) { 8568 conn.numStableIncs += stable; 8569 } 8570 stable = conn.stableCount + stable; 8571 if (stable < 0) { 8572 throw new IllegalStateException("stableCount < 0: " + stable); 8573 } 8574 8575 if (unstable > 0) { 8576 conn.numUnstableIncs += unstable; 8577 } 8578 unstable = conn.unstableCount + unstable; 8579 if (unstable < 0) { 8580 throw new IllegalStateException("unstableCount < 0: " + unstable); 8581 } 8582 8583 if ((stable+unstable) <= 0) { 8584 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8585 + stable + " unstable=" + unstable); 8586 } 8587 conn.stableCount = stable; 8588 conn.unstableCount = unstable; 8589 return !conn.dead; 8590 } 8591 } 8592 8593 public void unstableProviderDied(IBinder connection) { 8594 ContentProviderConnection conn; 8595 try { 8596 conn = (ContentProviderConnection)connection; 8597 } catch (ClassCastException e) { 8598 String msg ="refContentProvider: " + connection 8599 + " not a ContentProviderConnection"; 8600 Slog.w(TAG, msg); 8601 throw new IllegalArgumentException(msg); 8602 } 8603 if (conn == null) { 8604 throw new NullPointerException("connection is null"); 8605 } 8606 8607 // Safely retrieve the content provider associated with the connection. 8608 IContentProvider provider; 8609 synchronized (this) { 8610 provider = conn.provider.provider; 8611 } 8612 8613 if (provider == null) { 8614 // Um, yeah, we're way ahead of you. 8615 return; 8616 } 8617 8618 // Make sure the caller is being honest with us. 8619 if (provider.asBinder().pingBinder()) { 8620 // Er, no, still looks good to us. 8621 synchronized (this) { 8622 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8623 + " says " + conn + " died, but we don't agree"); 8624 return; 8625 } 8626 } 8627 8628 // Well look at that! It's dead! 8629 synchronized (this) { 8630 if (conn.provider.provider != provider) { 8631 // But something changed... good enough. 8632 return; 8633 } 8634 8635 ProcessRecord proc = conn.provider.proc; 8636 if (proc == null || proc.thread == null) { 8637 // Seems like the process is already cleaned up. 8638 return; 8639 } 8640 8641 // As far as we're concerned, this is just like receiving a 8642 // death notification... just a bit prematurely. 8643 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8644 + ") early provider death"); 8645 final long ident = Binder.clearCallingIdentity(); 8646 try { 8647 appDiedLocked(proc, proc.pid, proc.thread); 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 } 8652 } 8653 8654 @Override 8655 public void appNotRespondingViaProvider(IBinder connection) { 8656 enforceCallingPermission( 8657 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8658 8659 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8660 if (conn == null) { 8661 Slog.w(TAG, "ContentProviderConnection is null"); 8662 return; 8663 } 8664 8665 final ProcessRecord host = conn.provider.proc; 8666 if (host == null) { 8667 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8668 return; 8669 } 8670 8671 final long token = Binder.clearCallingIdentity(); 8672 try { 8673 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8674 } finally { 8675 Binder.restoreCallingIdentity(token); 8676 } 8677 } 8678 8679 public final void installSystemProviders() { 8680 List<ProviderInfo> providers; 8681 synchronized (this) { 8682 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8683 providers = generateApplicationProvidersLocked(app); 8684 if (providers != null) { 8685 for (int i=providers.size()-1; i>=0; i--) { 8686 ProviderInfo pi = (ProviderInfo)providers.get(i); 8687 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8688 Slog.w(TAG, "Not installing system proc provider " + pi.name 8689 + ": not system .apk"); 8690 providers.remove(i); 8691 } 8692 } 8693 } 8694 } 8695 if (providers != null) { 8696 mSystemThread.installSystemProviders(providers); 8697 } 8698 8699 mCoreSettingsObserver = new CoreSettingsObserver(this); 8700 8701 mUsageStatsService.monitorPackages(); 8702 } 8703 8704 /** 8705 * Allows app to retrieve the MIME type of a URI without having permission 8706 * to access its content provider. 8707 * 8708 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8709 * 8710 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8711 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8712 */ 8713 public String getProviderMimeType(Uri uri, int userId) { 8714 enforceNotIsolatedCaller("getProviderMimeType"); 8715 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8716 userId, false, true, "getProviderMimeType", null); 8717 final String name = uri.getAuthority(); 8718 final long ident = Binder.clearCallingIdentity(); 8719 ContentProviderHolder holder = null; 8720 8721 try { 8722 holder = getContentProviderExternalUnchecked(name, null, userId); 8723 if (holder != null) { 8724 return holder.provider.getType(uri); 8725 } 8726 } catch (RemoteException e) { 8727 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8728 return null; 8729 } finally { 8730 if (holder != null) { 8731 removeContentProviderExternalUnchecked(name, null, userId); 8732 } 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 8736 return null; 8737 } 8738 8739 // ========================================================= 8740 // GLOBAL MANAGEMENT 8741 // ========================================================= 8742 8743 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8744 boolean isolated) { 8745 String proc = customProcess != null ? customProcess : info.processName; 8746 BatteryStatsImpl.Uid.Proc ps = null; 8747 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8748 int uid = info.uid; 8749 if (isolated) { 8750 int userId = UserHandle.getUserId(uid); 8751 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8752 while (true) { 8753 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8754 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8755 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8756 } 8757 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8758 mNextIsolatedProcessUid++; 8759 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8760 // No process for this uid, use it. 8761 break; 8762 } 8763 stepsLeft--; 8764 if (stepsLeft <= 0) { 8765 return null; 8766 } 8767 } 8768 } 8769 return new ProcessRecord(stats, info, proc, uid); 8770 } 8771 8772 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8773 String abiOverride) { 8774 ProcessRecord app; 8775 if (!isolated) { 8776 app = getProcessRecordLocked(info.processName, info.uid, true); 8777 } else { 8778 app = null; 8779 } 8780 8781 if (app == null) { 8782 app = newProcessRecordLocked(info, null, isolated); 8783 mProcessNames.put(info.processName, app.uid, app); 8784 if (isolated) { 8785 mIsolatedProcesses.put(app.uid, app); 8786 } 8787 updateLruProcessLocked(app, false, null); 8788 updateOomAdjLocked(); 8789 } 8790 8791 // This package really, really can not be stopped. 8792 try { 8793 AppGlobals.getPackageManager().setPackageStoppedState( 8794 info.packageName, false, UserHandle.getUserId(app.uid)); 8795 } catch (RemoteException e) { 8796 } catch (IllegalArgumentException e) { 8797 Slog.w(TAG, "Failed trying to unstop package " 8798 + info.packageName + ": " + e); 8799 } 8800 8801 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8802 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8803 app.persistent = true; 8804 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8805 } 8806 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8807 mPersistentStartingProcesses.add(app); 8808 startProcessLocked(app, "added application", app.processName, 8809 abiOverride); 8810 } 8811 8812 return app; 8813 } 8814 8815 public void unhandledBack() { 8816 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8817 "unhandledBack()"); 8818 8819 synchronized(this) { 8820 final long origId = Binder.clearCallingIdentity(); 8821 try { 8822 getFocusedStack().unhandledBackLocked(); 8823 } finally { 8824 Binder.restoreCallingIdentity(origId); 8825 } 8826 } 8827 } 8828 8829 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8830 enforceNotIsolatedCaller("openContentUri"); 8831 final int userId = UserHandle.getCallingUserId(); 8832 String name = uri.getAuthority(); 8833 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8834 ParcelFileDescriptor pfd = null; 8835 if (cph != null) { 8836 // We record the binder invoker's uid in thread-local storage before 8837 // going to the content provider to open the file. Later, in the code 8838 // that handles all permissions checks, we look for this uid and use 8839 // that rather than the Activity Manager's own uid. The effect is that 8840 // we do the check against the caller's permissions even though it looks 8841 // to the content provider like the Activity Manager itself is making 8842 // the request. 8843 sCallerIdentity.set(new Identity( 8844 Binder.getCallingPid(), Binder.getCallingUid())); 8845 try { 8846 pfd = cph.provider.openFile(null, uri, "r", null); 8847 } catch (FileNotFoundException e) { 8848 // do nothing; pfd will be returned null 8849 } finally { 8850 // Ensure that whatever happens, we clean up the identity state 8851 sCallerIdentity.remove(); 8852 } 8853 8854 // We've got the fd now, so we're done with the provider. 8855 removeContentProviderExternalUnchecked(name, null, userId); 8856 } else { 8857 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8858 } 8859 return pfd; 8860 } 8861 8862 // Actually is sleeping or shutting down or whatever else in the future 8863 // is an inactive state. 8864 public boolean isSleepingOrShuttingDown() { 8865 return mSleeping || mShuttingDown; 8866 } 8867 8868 public boolean isSleeping() { 8869 return mSleeping; 8870 } 8871 8872 void goingToSleep() { 8873 synchronized(this) { 8874 mWentToSleep = true; 8875 updateEventDispatchingLocked(); 8876 goToSleepIfNeededLocked(); 8877 } 8878 } 8879 8880 void finishRunningVoiceLocked() { 8881 if (mRunningVoice) { 8882 mRunningVoice = false; 8883 goToSleepIfNeededLocked(); 8884 } 8885 } 8886 8887 void goToSleepIfNeededLocked() { 8888 if (mWentToSleep && !mRunningVoice) { 8889 if (!mSleeping) { 8890 mSleeping = true; 8891 mStackSupervisor.goingToSleepLocked(); 8892 8893 // Initialize the wake times of all processes. 8894 checkExcessivePowerUsageLocked(false); 8895 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8896 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8897 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8898 } 8899 } 8900 } 8901 8902 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8903 mTaskPersister.notify(task, flush); 8904 } 8905 8906 @Override 8907 public boolean shutdown(int timeout) { 8908 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8909 != PackageManager.PERMISSION_GRANTED) { 8910 throw new SecurityException("Requires permission " 8911 + android.Manifest.permission.SHUTDOWN); 8912 } 8913 8914 boolean timedout = false; 8915 8916 synchronized(this) { 8917 mShuttingDown = true; 8918 updateEventDispatchingLocked(); 8919 timedout = mStackSupervisor.shutdownLocked(timeout); 8920 } 8921 8922 mAppOpsService.shutdown(); 8923 mUsageStatsService.shutdown(); 8924 mBatteryStatsService.shutdown(); 8925 synchronized (this) { 8926 mProcessStats.shutdownLocked(); 8927 } 8928 notifyTaskPersisterLocked(null, true); 8929 8930 return timedout; 8931 } 8932 8933 public final void activitySlept(IBinder token) { 8934 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8935 8936 final long origId = Binder.clearCallingIdentity(); 8937 8938 synchronized (this) { 8939 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8940 if (r != null) { 8941 mStackSupervisor.activitySleptLocked(r); 8942 } 8943 } 8944 8945 Binder.restoreCallingIdentity(origId); 8946 } 8947 8948 void logLockScreen(String msg) { 8949 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8950 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8951 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8952 mStackSupervisor.mDismissKeyguardOnNextActivity); 8953 } 8954 8955 private void comeOutOfSleepIfNeededLocked() { 8956 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8957 if (mSleeping) { 8958 mSleeping = false; 8959 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8960 } 8961 } 8962 } 8963 8964 void wakingUp() { 8965 synchronized(this) { 8966 mWentToSleep = false; 8967 updateEventDispatchingLocked(); 8968 comeOutOfSleepIfNeededLocked(); 8969 } 8970 } 8971 8972 void startRunningVoiceLocked() { 8973 if (!mRunningVoice) { 8974 mRunningVoice = true; 8975 comeOutOfSleepIfNeededLocked(); 8976 } 8977 } 8978 8979 private void updateEventDispatchingLocked() { 8980 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8981 } 8982 8983 public void setLockScreenShown(boolean shown) { 8984 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8985 != PackageManager.PERMISSION_GRANTED) { 8986 throw new SecurityException("Requires permission " 8987 + android.Manifest.permission.DEVICE_POWER); 8988 } 8989 8990 synchronized(this) { 8991 long ident = Binder.clearCallingIdentity(); 8992 try { 8993 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8994 mLockScreenShown = shown; 8995 comeOutOfSleepIfNeededLocked(); 8996 } finally { 8997 Binder.restoreCallingIdentity(ident); 8998 } 8999 } 9000 } 9001 9002 public void stopAppSwitches() { 9003 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9004 != PackageManager.PERMISSION_GRANTED) { 9005 throw new SecurityException("Requires permission " 9006 + android.Manifest.permission.STOP_APP_SWITCHES); 9007 } 9008 9009 synchronized(this) { 9010 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9011 + APP_SWITCH_DELAY_TIME; 9012 mDidAppSwitch = false; 9013 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9014 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9015 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9016 } 9017 } 9018 9019 public void resumeAppSwitches() { 9020 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9021 != PackageManager.PERMISSION_GRANTED) { 9022 throw new SecurityException("Requires permission " 9023 + android.Manifest.permission.STOP_APP_SWITCHES); 9024 } 9025 9026 synchronized(this) { 9027 // Note that we don't execute any pending app switches... we will 9028 // let those wait until either the timeout, or the next start 9029 // activity request. 9030 mAppSwitchesAllowedTime = 0; 9031 } 9032 } 9033 9034 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9035 String name) { 9036 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9037 return true; 9038 } 9039 9040 final int perm = checkComponentPermission( 9041 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9042 callingUid, -1, true); 9043 if (perm == PackageManager.PERMISSION_GRANTED) { 9044 return true; 9045 } 9046 9047 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9048 return false; 9049 } 9050 9051 public void setDebugApp(String packageName, boolean waitForDebugger, 9052 boolean persistent) { 9053 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9054 "setDebugApp()"); 9055 9056 long ident = Binder.clearCallingIdentity(); 9057 try { 9058 // Note that this is not really thread safe if there are multiple 9059 // callers into it at the same time, but that's not a situation we 9060 // care about. 9061 if (persistent) { 9062 final ContentResolver resolver = mContext.getContentResolver(); 9063 Settings.Global.putString( 9064 resolver, Settings.Global.DEBUG_APP, 9065 packageName); 9066 Settings.Global.putInt( 9067 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9068 waitForDebugger ? 1 : 0); 9069 } 9070 9071 synchronized (this) { 9072 if (!persistent) { 9073 mOrigDebugApp = mDebugApp; 9074 mOrigWaitForDebugger = mWaitForDebugger; 9075 } 9076 mDebugApp = packageName; 9077 mWaitForDebugger = waitForDebugger; 9078 mDebugTransient = !persistent; 9079 if (packageName != null) { 9080 forceStopPackageLocked(packageName, -1, false, false, true, true, 9081 false, UserHandle.USER_ALL, "set debug app"); 9082 } 9083 } 9084 } finally { 9085 Binder.restoreCallingIdentity(ident); 9086 } 9087 } 9088 9089 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9090 synchronized (this) { 9091 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9092 if (!isDebuggable) { 9093 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9094 throw new SecurityException("Process not debuggable: " + app.packageName); 9095 } 9096 } 9097 9098 mOpenGlTraceApp = processName; 9099 } 9100 } 9101 9102 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9103 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9104 synchronized (this) { 9105 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9106 if (!isDebuggable) { 9107 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9108 throw new SecurityException("Process not debuggable: " + app.packageName); 9109 } 9110 } 9111 mProfileApp = processName; 9112 mProfileFile = profileFile; 9113 if (mProfileFd != null) { 9114 try { 9115 mProfileFd.close(); 9116 } catch (IOException e) { 9117 } 9118 mProfileFd = null; 9119 } 9120 mProfileFd = profileFd; 9121 mProfileType = 0; 9122 mAutoStopProfiler = autoStopProfiler; 9123 } 9124 } 9125 9126 @Override 9127 public void setAlwaysFinish(boolean enabled) { 9128 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9129 "setAlwaysFinish()"); 9130 9131 Settings.Global.putInt( 9132 mContext.getContentResolver(), 9133 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9134 9135 synchronized (this) { 9136 mAlwaysFinishActivities = enabled; 9137 } 9138 } 9139 9140 @Override 9141 public void setActivityController(IActivityController controller) { 9142 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9143 "setActivityController()"); 9144 synchronized (this) { 9145 mController = controller; 9146 Watchdog.getInstance().setActivityController(controller); 9147 } 9148 } 9149 9150 @Override 9151 public void setUserIsMonkey(boolean userIsMonkey) { 9152 synchronized (this) { 9153 synchronized (mPidsSelfLocked) { 9154 final int callingPid = Binder.getCallingPid(); 9155 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9156 if (precessRecord == null) { 9157 throw new SecurityException("Unknown process: " + callingPid); 9158 } 9159 if (precessRecord.instrumentationUiAutomationConnection == null) { 9160 throw new SecurityException("Only an instrumentation process " 9161 + "with a UiAutomation can call setUserIsMonkey"); 9162 } 9163 } 9164 mUserIsMonkey = userIsMonkey; 9165 } 9166 } 9167 9168 @Override 9169 public boolean isUserAMonkey() { 9170 synchronized (this) { 9171 // If there is a controller also implies the user is a monkey. 9172 return (mUserIsMonkey || mController != null); 9173 } 9174 } 9175 9176 public void requestBugReport() { 9177 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9178 SystemProperties.set("ctl.start", "bugreport"); 9179 } 9180 9181 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9182 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9183 } 9184 9185 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9186 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9187 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9188 } 9189 return KEY_DISPATCHING_TIMEOUT; 9190 } 9191 9192 @Override 9193 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9194 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9195 != PackageManager.PERMISSION_GRANTED) { 9196 throw new SecurityException("Requires permission " 9197 + android.Manifest.permission.FILTER_EVENTS); 9198 } 9199 ProcessRecord proc; 9200 long timeout; 9201 synchronized (this) { 9202 synchronized (mPidsSelfLocked) { 9203 proc = mPidsSelfLocked.get(pid); 9204 } 9205 timeout = getInputDispatchingTimeoutLocked(proc); 9206 } 9207 9208 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9209 return -1; 9210 } 9211 9212 return timeout; 9213 } 9214 9215 /** 9216 * Handle input dispatching timeouts. 9217 * Returns whether input dispatching should be aborted or not. 9218 */ 9219 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9220 final ActivityRecord activity, final ActivityRecord parent, 9221 final boolean aboveSystem, String reason) { 9222 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9223 != PackageManager.PERMISSION_GRANTED) { 9224 throw new SecurityException("Requires permission " 9225 + android.Manifest.permission.FILTER_EVENTS); 9226 } 9227 9228 final String annotation; 9229 if (reason == null) { 9230 annotation = "Input dispatching timed out"; 9231 } else { 9232 annotation = "Input dispatching timed out (" + reason + ")"; 9233 } 9234 9235 if (proc != null) { 9236 synchronized (this) { 9237 if (proc.debugging) { 9238 return false; 9239 } 9240 9241 if (mDidDexOpt) { 9242 // Give more time since we were dexopting. 9243 mDidDexOpt = false; 9244 return false; 9245 } 9246 9247 if (proc.instrumentationClass != null) { 9248 Bundle info = new Bundle(); 9249 info.putString("shortMsg", "keyDispatchingTimedOut"); 9250 info.putString("longMsg", annotation); 9251 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9252 return true; 9253 } 9254 } 9255 mHandler.post(new Runnable() { 9256 @Override 9257 public void run() { 9258 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9259 } 9260 }); 9261 } 9262 9263 return true; 9264 } 9265 9266 public Bundle getAssistContextExtras(int requestType) { 9267 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9268 "getAssistContextExtras()"); 9269 PendingAssistExtras pae; 9270 Bundle extras = new Bundle(); 9271 synchronized (this) { 9272 ActivityRecord activity = getFocusedStack().mResumedActivity; 9273 if (activity == null) { 9274 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9275 return null; 9276 } 9277 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9278 if (activity.app == null || activity.app.thread == null) { 9279 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9280 return extras; 9281 } 9282 if (activity.app.pid == Binder.getCallingPid()) { 9283 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9284 return extras; 9285 } 9286 pae = new PendingAssistExtras(activity); 9287 try { 9288 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9289 requestType); 9290 mPendingAssistExtras.add(pae); 9291 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9292 } catch (RemoteException e) { 9293 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9294 return extras; 9295 } 9296 } 9297 synchronized (pae) { 9298 while (!pae.haveResult) { 9299 try { 9300 pae.wait(); 9301 } catch (InterruptedException e) { 9302 } 9303 } 9304 if (pae.result != null) { 9305 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9306 } 9307 } 9308 synchronized (this) { 9309 mPendingAssistExtras.remove(pae); 9310 mHandler.removeCallbacks(pae); 9311 } 9312 return extras; 9313 } 9314 9315 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9316 PendingAssistExtras pae = (PendingAssistExtras)token; 9317 synchronized (pae) { 9318 pae.result = extras; 9319 pae.haveResult = true; 9320 pae.notifyAll(); 9321 } 9322 } 9323 9324 public void registerProcessObserver(IProcessObserver observer) { 9325 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9326 "registerProcessObserver()"); 9327 synchronized (this) { 9328 mProcessObservers.register(observer); 9329 } 9330 } 9331 9332 @Override 9333 public void unregisterProcessObserver(IProcessObserver observer) { 9334 synchronized (this) { 9335 mProcessObservers.unregister(observer); 9336 } 9337 } 9338 9339 @Override 9340 public boolean convertFromTranslucent(IBinder token) { 9341 final long origId = Binder.clearCallingIdentity(); 9342 try { 9343 synchronized (this) { 9344 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9345 if (r == null) { 9346 return false; 9347 } 9348 if (r.changeWindowTranslucency(true)) { 9349 mWindowManager.setAppFullscreen(token, true); 9350 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9351 return true; 9352 } 9353 return false; 9354 } 9355 } finally { 9356 Binder.restoreCallingIdentity(origId); 9357 } 9358 } 9359 9360 @Override 9361 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9362 final long origId = Binder.clearCallingIdentity(); 9363 try { 9364 synchronized (this) { 9365 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9366 if (r == null) { 9367 return false; 9368 } 9369 if (r.changeWindowTranslucency(false)) { 9370 r.task.stack.convertToTranslucent(r, options); 9371 mWindowManager.setAppFullscreen(token, false); 9372 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9373 return true; 9374 } else { 9375 r.task.stack.mReturningActivityOptions = options; 9376 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9377 return false; 9378 } 9379 } 9380 } finally { 9381 Binder.restoreCallingIdentity(origId); 9382 } 9383 } 9384 9385 @Override 9386 public ActivityOptions getActivityOptions(IBinder token) { 9387 final long origId = Binder.clearCallingIdentity(); 9388 try { 9389 synchronized (this) { 9390 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9391 if (r != null) { 9392 final ActivityOptions activityOptions = r.pendingOptions; 9393 r.pendingOptions = null; 9394 return activityOptions; 9395 } 9396 return null; 9397 } 9398 } finally { 9399 Binder.restoreCallingIdentity(origId); 9400 } 9401 } 9402 9403 @Override 9404 public void setImmersive(IBinder token, boolean immersive) { 9405 synchronized(this) { 9406 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9407 if (r == null) { 9408 throw new IllegalArgumentException(); 9409 } 9410 r.immersive = immersive; 9411 9412 // update associated state if we're frontmost 9413 if (r == mFocusedActivity) { 9414 if (DEBUG_IMMERSIVE) { 9415 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9416 } 9417 applyUpdateLockStateLocked(r); 9418 } 9419 } 9420 } 9421 9422 @Override 9423 public boolean isImmersive(IBinder token) { 9424 synchronized (this) { 9425 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9426 if (r == null) { 9427 throw new IllegalArgumentException(); 9428 } 9429 return r.immersive; 9430 } 9431 } 9432 9433 public boolean isTopActivityImmersive() { 9434 enforceNotIsolatedCaller("startActivity"); 9435 synchronized (this) { 9436 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9437 return (r != null) ? r.immersive : false; 9438 } 9439 } 9440 9441 @Override 9442 public boolean isTopOfTask(IBinder token) { 9443 synchronized (this) { 9444 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9445 if (r == null) { 9446 throw new IllegalArgumentException(); 9447 } 9448 return r.task.getTopActivity() == r; 9449 } 9450 } 9451 9452 public final void enterSafeMode() { 9453 synchronized(this) { 9454 // It only makes sense to do this before the system is ready 9455 // and started launching other packages. 9456 if (!mSystemReady) { 9457 try { 9458 AppGlobals.getPackageManager().enterSafeMode(); 9459 } catch (RemoteException e) { 9460 } 9461 } 9462 9463 mSafeMode = true; 9464 } 9465 } 9466 9467 public final void showSafeModeOverlay() { 9468 View v = LayoutInflater.from(mContext).inflate( 9469 com.android.internal.R.layout.safe_mode, null); 9470 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9471 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9472 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9473 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9474 lp.gravity = Gravity.BOTTOM | Gravity.START; 9475 lp.format = v.getBackground().getOpacity(); 9476 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9477 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9478 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9479 ((WindowManager)mContext.getSystemService( 9480 Context.WINDOW_SERVICE)).addView(v, lp); 9481 } 9482 9483 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9484 if (!(sender instanceof PendingIntentRecord)) { 9485 return; 9486 } 9487 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9488 synchronized (stats) { 9489 if (mBatteryStatsService.isOnBattery()) { 9490 mBatteryStatsService.enforceCallingPermission(); 9491 PendingIntentRecord rec = (PendingIntentRecord)sender; 9492 int MY_UID = Binder.getCallingUid(); 9493 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9494 BatteryStatsImpl.Uid.Pkg pkg = 9495 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9496 sourcePkg != null ? sourcePkg : rec.key.packageName); 9497 pkg.incWakeupsLocked(); 9498 } 9499 } 9500 } 9501 9502 public boolean killPids(int[] pids, String pReason, boolean secure) { 9503 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9504 throw new SecurityException("killPids only available to the system"); 9505 } 9506 String reason = (pReason == null) ? "Unknown" : pReason; 9507 // XXX Note: don't acquire main activity lock here, because the window 9508 // manager calls in with its locks held. 9509 9510 boolean killed = false; 9511 synchronized (mPidsSelfLocked) { 9512 int[] types = new int[pids.length]; 9513 int worstType = 0; 9514 for (int i=0; i<pids.length; i++) { 9515 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9516 if (proc != null) { 9517 int type = proc.setAdj; 9518 types[i] = type; 9519 if (type > worstType) { 9520 worstType = type; 9521 } 9522 } 9523 } 9524 9525 // If the worst oom_adj is somewhere in the cached proc LRU range, 9526 // then constrain it so we will kill all cached procs. 9527 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9528 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9529 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9530 } 9531 9532 // If this is not a secure call, don't let it kill processes that 9533 // are important. 9534 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9535 worstType = ProcessList.SERVICE_ADJ; 9536 } 9537 9538 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9539 for (int i=0; i<pids.length; i++) { 9540 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9541 if (proc == null) { 9542 continue; 9543 } 9544 int adj = proc.setAdj; 9545 if (adj >= worstType && !proc.killedByAm) { 9546 killUnneededProcessLocked(proc, reason); 9547 killed = true; 9548 } 9549 } 9550 } 9551 return killed; 9552 } 9553 9554 @Override 9555 public void killUid(int uid, String reason) { 9556 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9557 throw new SecurityException("killUid only available to the system"); 9558 } 9559 synchronized (this) { 9560 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9561 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9562 reason != null ? reason : "kill uid"); 9563 } 9564 } 9565 9566 @Override 9567 public boolean killProcessesBelowForeground(String reason) { 9568 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9569 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9570 } 9571 9572 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9573 } 9574 9575 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9576 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9577 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9578 } 9579 9580 boolean killed = false; 9581 synchronized (mPidsSelfLocked) { 9582 final int size = mPidsSelfLocked.size(); 9583 for (int i = 0; i < size; i++) { 9584 final int pid = mPidsSelfLocked.keyAt(i); 9585 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9586 if (proc == null) continue; 9587 9588 final int adj = proc.setAdj; 9589 if (adj > belowAdj && !proc.killedByAm) { 9590 killUnneededProcessLocked(proc, reason); 9591 killed = true; 9592 } 9593 } 9594 } 9595 return killed; 9596 } 9597 9598 @Override 9599 public void hang(final IBinder who, boolean allowRestart) { 9600 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9601 != PackageManager.PERMISSION_GRANTED) { 9602 throw new SecurityException("Requires permission " 9603 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9604 } 9605 9606 final IBinder.DeathRecipient death = new DeathRecipient() { 9607 @Override 9608 public void binderDied() { 9609 synchronized (this) { 9610 notifyAll(); 9611 } 9612 } 9613 }; 9614 9615 try { 9616 who.linkToDeath(death, 0); 9617 } catch (RemoteException e) { 9618 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9619 return; 9620 } 9621 9622 synchronized (this) { 9623 Watchdog.getInstance().setAllowRestart(allowRestart); 9624 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9625 synchronized (death) { 9626 while (who.isBinderAlive()) { 9627 try { 9628 death.wait(); 9629 } catch (InterruptedException e) { 9630 } 9631 } 9632 } 9633 Watchdog.getInstance().setAllowRestart(true); 9634 } 9635 } 9636 9637 @Override 9638 public void restart() { 9639 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9640 != PackageManager.PERMISSION_GRANTED) { 9641 throw new SecurityException("Requires permission " 9642 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9643 } 9644 9645 Log.i(TAG, "Sending shutdown broadcast..."); 9646 9647 BroadcastReceiver br = new BroadcastReceiver() { 9648 @Override public void onReceive(Context context, Intent intent) { 9649 // Now the broadcast is done, finish up the low-level shutdown. 9650 Log.i(TAG, "Shutting down activity manager..."); 9651 shutdown(10000); 9652 Log.i(TAG, "Shutdown complete, restarting!"); 9653 Process.killProcess(Process.myPid()); 9654 System.exit(10); 9655 } 9656 }; 9657 9658 // First send the high-level shut down broadcast. 9659 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9660 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9661 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9662 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9663 mContext.sendOrderedBroadcastAsUser(intent, 9664 UserHandle.ALL, null, br, mHandler, 0, null, null); 9665 */ 9666 br.onReceive(mContext, intent); 9667 } 9668 9669 private long getLowRamTimeSinceIdle(long now) { 9670 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9671 } 9672 9673 @Override 9674 public void performIdleMaintenance() { 9675 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9676 != PackageManager.PERMISSION_GRANTED) { 9677 throw new SecurityException("Requires permission " 9678 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9679 } 9680 9681 synchronized (this) { 9682 final long now = SystemClock.uptimeMillis(); 9683 final long timeSinceLastIdle = now - mLastIdleTime; 9684 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9685 mLastIdleTime = now; 9686 mLowRamTimeSinceLastIdle = 0; 9687 if (mLowRamStartTime != 0) { 9688 mLowRamStartTime = now; 9689 } 9690 9691 StringBuilder sb = new StringBuilder(128); 9692 sb.append("Idle maintenance over "); 9693 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9694 sb.append(" low RAM for "); 9695 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9696 Slog.i(TAG, sb.toString()); 9697 9698 // If at least 1/3 of our time since the last idle period has been spent 9699 // with RAM low, then we want to kill processes. 9700 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9701 9702 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9703 ProcessRecord proc = mLruProcesses.get(i); 9704 if (proc.notCachedSinceIdle) { 9705 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9706 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9707 if (doKilling && proc.initialIdlePss != 0 9708 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9709 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9710 + " from " + proc.initialIdlePss + ")"); 9711 } 9712 } 9713 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9714 proc.notCachedSinceIdle = true; 9715 proc.initialIdlePss = 0; 9716 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9717 isSleeping(), now); 9718 } 9719 } 9720 9721 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9722 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9723 } 9724 } 9725 9726 private void retrieveSettings() { 9727 final ContentResolver resolver = mContext.getContentResolver(); 9728 String debugApp = Settings.Global.getString( 9729 resolver, Settings.Global.DEBUG_APP); 9730 boolean waitForDebugger = Settings.Global.getInt( 9731 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9732 boolean alwaysFinishActivities = Settings.Global.getInt( 9733 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9734 boolean forceRtl = Settings.Global.getInt( 9735 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9736 // Transfer any global setting for forcing RTL layout, into a System Property 9737 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9738 9739 Configuration configuration = new Configuration(); 9740 Settings.System.getConfiguration(resolver, configuration); 9741 if (forceRtl) { 9742 // This will take care of setting the correct layout direction flags 9743 configuration.setLayoutDirection(configuration.locale); 9744 } 9745 9746 synchronized (this) { 9747 mDebugApp = mOrigDebugApp = debugApp; 9748 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9749 mAlwaysFinishActivities = alwaysFinishActivities; 9750 // This happens before any activities are started, so we can 9751 // change mConfiguration in-place. 9752 updateConfigurationLocked(configuration, null, false, true); 9753 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9754 } 9755 } 9756 9757 public boolean testIsSystemReady() { 9758 // no need to synchronize(this) just to read & return the value 9759 return mSystemReady; 9760 } 9761 9762 private static File getCalledPreBootReceiversFile() { 9763 File dataDir = Environment.getDataDirectory(); 9764 File systemDir = new File(dataDir, "system"); 9765 File fname = new File(systemDir, "called_pre_boots.dat"); 9766 return fname; 9767 } 9768 9769 static final int LAST_DONE_VERSION = 10000; 9770 9771 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9772 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9773 File file = getCalledPreBootReceiversFile(); 9774 FileInputStream fis = null; 9775 try { 9776 fis = new FileInputStream(file); 9777 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9778 int fvers = dis.readInt(); 9779 if (fvers == LAST_DONE_VERSION) { 9780 String vers = dis.readUTF(); 9781 String codename = dis.readUTF(); 9782 String build = dis.readUTF(); 9783 if (android.os.Build.VERSION.RELEASE.equals(vers) 9784 && android.os.Build.VERSION.CODENAME.equals(codename) 9785 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9786 int num = dis.readInt(); 9787 while (num > 0) { 9788 num--; 9789 String pkg = dis.readUTF(); 9790 String cls = dis.readUTF(); 9791 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9792 } 9793 } 9794 } 9795 } catch (FileNotFoundException e) { 9796 } catch (IOException e) { 9797 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9798 } finally { 9799 if (fis != null) { 9800 try { 9801 fis.close(); 9802 } catch (IOException e) { 9803 } 9804 } 9805 } 9806 return lastDoneReceivers; 9807 } 9808 9809 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9810 File file = getCalledPreBootReceiversFile(); 9811 FileOutputStream fos = null; 9812 DataOutputStream dos = null; 9813 try { 9814 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9815 fos = new FileOutputStream(file); 9816 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9817 dos.writeInt(LAST_DONE_VERSION); 9818 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9819 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9820 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9821 dos.writeInt(list.size()); 9822 for (int i=0; i<list.size(); i++) { 9823 dos.writeUTF(list.get(i).getPackageName()); 9824 dos.writeUTF(list.get(i).getClassName()); 9825 } 9826 } catch (IOException e) { 9827 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9828 file.delete(); 9829 } finally { 9830 FileUtils.sync(fos); 9831 if (dos != null) { 9832 try { 9833 dos.close(); 9834 } catch (IOException e) { 9835 // TODO Auto-generated catch block 9836 e.printStackTrace(); 9837 } 9838 } 9839 } 9840 } 9841 9842 public void systemReady(final Runnable goingCallback) { 9843 synchronized(this) { 9844 if (mSystemReady) { 9845 if (goingCallback != null) goingCallback.run(); 9846 return; 9847 } 9848 9849 if (mRecentTasks == null) { 9850 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9851 if (!mRecentTasks.isEmpty()) { 9852 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9853 } 9854 mTaskPersister.startPersisting(); 9855 } 9856 9857 // Check to see if there are any update receivers to run. 9858 if (!mDidUpdate) { 9859 if (mWaitingUpdate) { 9860 return; 9861 } 9862 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9863 List<ResolveInfo> ris = null; 9864 try { 9865 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9866 intent, null, 0, 0); 9867 } catch (RemoteException e) { 9868 } 9869 if (ris != null) { 9870 for (int i=ris.size()-1; i>=0; i--) { 9871 if ((ris.get(i).activityInfo.applicationInfo.flags 9872 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9873 ris.remove(i); 9874 } 9875 } 9876 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9877 9878 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9879 9880 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9881 for (int i=0; i<ris.size(); i++) { 9882 ActivityInfo ai = ris.get(i).activityInfo; 9883 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9884 if (lastDoneReceivers.contains(comp)) { 9885 // We already did the pre boot receiver for this app with the current 9886 // platform version, so don't do it again... 9887 ris.remove(i); 9888 i--; 9889 // ...however, do keep it as one that has been done, so we don't 9890 // forget about it when rewriting the file of last done receivers. 9891 doneReceivers.add(comp); 9892 } 9893 } 9894 9895 final int[] users = getUsersLocked(); 9896 for (int i=0; i<ris.size(); i++) { 9897 ActivityInfo ai = ris.get(i).activityInfo; 9898 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9899 doneReceivers.add(comp); 9900 intent.setComponent(comp); 9901 for (int j=0; j<users.length; j++) { 9902 IIntentReceiver finisher = null; 9903 if (i == ris.size()-1 && j == users.length-1) { 9904 finisher = new IIntentReceiver.Stub() { 9905 public void performReceive(Intent intent, int resultCode, 9906 String data, Bundle extras, boolean ordered, 9907 boolean sticky, int sendingUser) { 9908 // The raw IIntentReceiver interface is called 9909 // with the AM lock held, so redispatch to 9910 // execute our code without the lock. 9911 mHandler.post(new Runnable() { 9912 public void run() { 9913 synchronized (ActivityManagerService.this) { 9914 mDidUpdate = true; 9915 } 9916 writeLastDonePreBootReceivers(doneReceivers); 9917 showBootMessage(mContext.getText( 9918 R.string.android_upgrading_complete), 9919 false); 9920 systemReady(goingCallback); 9921 } 9922 }); 9923 } 9924 }; 9925 } 9926 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9927 + " for user " + users[j]); 9928 broadcastIntentLocked(null, null, intent, null, finisher, 9929 0, null, null, null, AppOpsManager.OP_NONE, 9930 true, false, MY_PID, Process.SYSTEM_UID, 9931 users[j]); 9932 if (finisher != null) { 9933 mWaitingUpdate = true; 9934 } 9935 } 9936 } 9937 } 9938 if (mWaitingUpdate) { 9939 return; 9940 } 9941 mDidUpdate = true; 9942 } 9943 9944 mAppOpsService.systemReady(); 9945 mUsageStatsService.systemReady(); 9946 mSystemReady = true; 9947 } 9948 9949 ArrayList<ProcessRecord> procsToKill = null; 9950 synchronized(mPidsSelfLocked) { 9951 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9952 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9953 if (!isAllowedWhileBooting(proc.info)){ 9954 if (procsToKill == null) { 9955 procsToKill = new ArrayList<ProcessRecord>(); 9956 } 9957 procsToKill.add(proc); 9958 } 9959 } 9960 } 9961 9962 synchronized(this) { 9963 if (procsToKill != null) { 9964 for (int i=procsToKill.size()-1; i>=0; i--) { 9965 ProcessRecord proc = procsToKill.get(i); 9966 Slog.i(TAG, "Removing system update proc: " + proc); 9967 removeProcessLocked(proc, true, false, "system update done"); 9968 } 9969 } 9970 9971 // Now that we have cleaned up any update processes, we 9972 // are ready to start launching real processes and know that 9973 // we won't trample on them any more. 9974 mProcessesReady = true; 9975 } 9976 9977 Slog.i(TAG, "System now ready"); 9978 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9979 SystemClock.uptimeMillis()); 9980 9981 synchronized(this) { 9982 // Make sure we have no pre-ready processes sitting around. 9983 9984 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9985 ResolveInfo ri = mContext.getPackageManager() 9986 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9987 STOCK_PM_FLAGS); 9988 CharSequence errorMsg = null; 9989 if (ri != null) { 9990 ActivityInfo ai = ri.activityInfo; 9991 ApplicationInfo app = ai.applicationInfo; 9992 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9993 mTopAction = Intent.ACTION_FACTORY_TEST; 9994 mTopData = null; 9995 mTopComponent = new ComponentName(app.packageName, 9996 ai.name); 9997 } else { 9998 errorMsg = mContext.getResources().getText( 9999 com.android.internal.R.string.factorytest_not_system); 10000 } 10001 } else { 10002 errorMsg = mContext.getResources().getText( 10003 com.android.internal.R.string.factorytest_no_action); 10004 } 10005 if (errorMsg != null) { 10006 mTopAction = null; 10007 mTopData = null; 10008 mTopComponent = null; 10009 Message msg = Message.obtain(); 10010 msg.what = SHOW_FACTORY_ERROR_MSG; 10011 msg.getData().putCharSequence("msg", errorMsg); 10012 mHandler.sendMessage(msg); 10013 } 10014 } 10015 } 10016 10017 retrieveSettings(); 10018 10019 synchronized (this) { 10020 readGrantedUriPermissionsLocked(); 10021 } 10022 10023 if (goingCallback != null) goingCallback.run(); 10024 10025 mSystemServiceManager.startUser(mCurrentUserId); 10026 10027 synchronized (this) { 10028 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10029 try { 10030 List apps = AppGlobals.getPackageManager(). 10031 getPersistentApplications(STOCK_PM_FLAGS); 10032 if (apps != null) { 10033 int N = apps.size(); 10034 int i; 10035 for (i=0; i<N; i++) { 10036 ApplicationInfo info 10037 = (ApplicationInfo)apps.get(i); 10038 if (info != null && 10039 !info.packageName.equals("android")) { 10040 addAppLocked(info, false, null /* ABI override */); 10041 } 10042 } 10043 } 10044 } catch (RemoteException ex) { 10045 // pm is in same process, this will never happen. 10046 } 10047 } 10048 10049 // Start up initial activity. 10050 mBooting = true; 10051 10052 try { 10053 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10054 Message msg = Message.obtain(); 10055 msg.what = SHOW_UID_ERROR_MSG; 10056 mHandler.sendMessage(msg); 10057 } 10058 } catch (RemoteException e) { 10059 } 10060 10061 long ident = Binder.clearCallingIdentity(); 10062 try { 10063 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10065 | Intent.FLAG_RECEIVER_FOREGROUND); 10066 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10067 broadcastIntentLocked(null, null, intent, 10068 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10069 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10070 intent = new Intent(Intent.ACTION_USER_STARTING); 10071 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10072 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10073 broadcastIntentLocked(null, null, intent, 10074 null, new IIntentReceiver.Stub() { 10075 @Override 10076 public void performReceive(Intent intent, int resultCode, String data, 10077 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10078 throws RemoteException { 10079 } 10080 }, 0, null, null, 10081 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10082 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10083 } catch (Throwable t) { 10084 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10085 } finally { 10086 Binder.restoreCallingIdentity(ident); 10087 } 10088 mStackSupervisor.resumeTopActivitiesLocked(); 10089 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10090 } 10091 } 10092 10093 private boolean makeAppCrashingLocked(ProcessRecord app, 10094 String shortMsg, String longMsg, String stackTrace) { 10095 app.crashing = true; 10096 app.crashingReport = generateProcessError(app, 10097 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10098 startAppProblemLocked(app); 10099 app.stopFreezingAllLocked(); 10100 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10101 } 10102 10103 private void makeAppNotRespondingLocked(ProcessRecord app, 10104 String activity, String shortMsg, String longMsg) { 10105 app.notResponding = true; 10106 app.notRespondingReport = generateProcessError(app, 10107 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10108 activity, shortMsg, longMsg, null); 10109 startAppProblemLocked(app); 10110 app.stopFreezingAllLocked(); 10111 } 10112 10113 /** 10114 * Generate a process error record, suitable for attachment to a ProcessRecord. 10115 * 10116 * @param app The ProcessRecord in which the error occurred. 10117 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10118 * ActivityManager.AppErrorStateInfo 10119 * @param activity The activity associated with the crash, if known. 10120 * @param shortMsg Short message describing the crash. 10121 * @param longMsg Long message describing the crash. 10122 * @param stackTrace Full crash stack trace, may be null. 10123 * 10124 * @return Returns a fully-formed AppErrorStateInfo record. 10125 */ 10126 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10127 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10128 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10129 10130 report.condition = condition; 10131 report.processName = app.processName; 10132 report.pid = app.pid; 10133 report.uid = app.info.uid; 10134 report.tag = activity; 10135 report.shortMsg = shortMsg; 10136 report.longMsg = longMsg; 10137 report.stackTrace = stackTrace; 10138 10139 return report; 10140 } 10141 10142 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10143 synchronized (this) { 10144 app.crashing = false; 10145 app.crashingReport = null; 10146 app.notResponding = false; 10147 app.notRespondingReport = null; 10148 if (app.anrDialog == fromDialog) { 10149 app.anrDialog = null; 10150 } 10151 if (app.waitDialog == fromDialog) { 10152 app.waitDialog = null; 10153 } 10154 if (app.pid > 0 && app.pid != MY_PID) { 10155 handleAppCrashLocked(app, null, null, null); 10156 killUnneededProcessLocked(app, "user request after error"); 10157 } 10158 } 10159 } 10160 10161 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10162 String stackTrace) { 10163 long now = SystemClock.uptimeMillis(); 10164 10165 Long crashTime; 10166 if (!app.isolated) { 10167 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10168 } else { 10169 crashTime = null; 10170 } 10171 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10172 // This process loses! 10173 Slog.w(TAG, "Process " + app.info.processName 10174 + " has crashed too many times: killing!"); 10175 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10176 app.userId, app.info.processName, app.uid); 10177 mStackSupervisor.handleAppCrashLocked(app); 10178 if (!app.persistent) { 10179 // We don't want to start this process again until the user 10180 // explicitly does so... but for persistent process, we really 10181 // need to keep it running. If a persistent process is actually 10182 // repeatedly crashing, then badness for everyone. 10183 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10184 app.info.processName); 10185 if (!app.isolated) { 10186 // XXX We don't have a way to mark isolated processes 10187 // as bad, since they don't have a peristent identity. 10188 mBadProcesses.put(app.info.processName, app.uid, 10189 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10190 mProcessCrashTimes.remove(app.info.processName, app.uid); 10191 } 10192 app.bad = true; 10193 app.removed = true; 10194 // Don't let services in this process be restarted and potentially 10195 // annoy the user repeatedly. Unless it is persistent, since those 10196 // processes run critical code. 10197 removeProcessLocked(app, false, false, "crash"); 10198 mStackSupervisor.resumeTopActivitiesLocked(); 10199 return false; 10200 } 10201 mStackSupervisor.resumeTopActivitiesLocked(); 10202 } else { 10203 mStackSupervisor.finishTopRunningActivityLocked(app); 10204 } 10205 10206 // Bump up the crash count of any services currently running in the proc. 10207 for (int i=app.services.size()-1; i>=0; i--) { 10208 // Any services running in the application need to be placed 10209 // back in the pending list. 10210 ServiceRecord sr = app.services.valueAt(i); 10211 sr.crashCount++; 10212 } 10213 10214 // If the crashing process is what we consider to be the "home process" and it has been 10215 // replaced by a third-party app, clear the package preferred activities from packages 10216 // with a home activity running in the process to prevent a repeatedly crashing app 10217 // from blocking the user to manually clear the list. 10218 final ArrayList<ActivityRecord> activities = app.activities; 10219 if (app == mHomeProcess && activities.size() > 0 10220 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10221 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10222 final ActivityRecord r = activities.get(activityNdx); 10223 if (r.isHomeActivity()) { 10224 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10225 try { 10226 ActivityThread.getPackageManager() 10227 .clearPackagePreferredActivities(r.packageName); 10228 } catch (RemoteException c) { 10229 // pm is in same process, this will never happen. 10230 } 10231 } 10232 } 10233 } 10234 10235 if (!app.isolated) { 10236 // XXX Can't keep track of crash times for isolated processes, 10237 // because they don't have a perisistent identity. 10238 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10239 } 10240 10241 return true; 10242 } 10243 10244 void startAppProblemLocked(ProcessRecord app) { 10245 if (app.userId == mCurrentUserId) { 10246 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10247 mContext, app.info.packageName, app.info.flags); 10248 } else { 10249 // If this app is not running under the current user, then we 10250 // can't give it a report button because that would require 10251 // launching the report UI under a different user. 10252 app.errorReportReceiver = null; 10253 } 10254 skipCurrentReceiverLocked(app); 10255 } 10256 10257 void skipCurrentReceiverLocked(ProcessRecord app) { 10258 for (BroadcastQueue queue : mBroadcastQueues) { 10259 queue.skipCurrentReceiverLocked(app); 10260 } 10261 } 10262 10263 /** 10264 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10265 * The application process will exit immediately after this call returns. 10266 * @param app object of the crashing app, null for the system server 10267 * @param crashInfo describing the exception 10268 */ 10269 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10270 ProcessRecord r = findAppProcess(app, "Crash"); 10271 final String processName = app == null ? "system_server" 10272 : (r == null ? "unknown" : r.processName); 10273 10274 handleApplicationCrashInner("crash", r, processName, crashInfo); 10275 } 10276 10277 /* Native crash reporting uses this inner version because it needs to be somewhat 10278 * decoupled from the AM-managed cleanup lifecycle 10279 */ 10280 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10281 ApplicationErrorReport.CrashInfo crashInfo) { 10282 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10283 UserHandle.getUserId(Binder.getCallingUid()), processName, 10284 r == null ? -1 : r.info.flags, 10285 crashInfo.exceptionClassName, 10286 crashInfo.exceptionMessage, 10287 crashInfo.throwFileName, 10288 crashInfo.throwLineNumber); 10289 10290 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10291 10292 crashApplication(r, crashInfo); 10293 } 10294 10295 public void handleApplicationStrictModeViolation( 10296 IBinder app, 10297 int violationMask, 10298 StrictMode.ViolationInfo info) { 10299 ProcessRecord r = findAppProcess(app, "StrictMode"); 10300 if (r == null) { 10301 return; 10302 } 10303 10304 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10305 Integer stackFingerprint = info.hashCode(); 10306 boolean logIt = true; 10307 synchronized (mAlreadyLoggedViolatedStacks) { 10308 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10309 logIt = false; 10310 // TODO: sub-sample into EventLog for these, with 10311 // the info.durationMillis? Then we'd get 10312 // the relative pain numbers, without logging all 10313 // the stack traces repeatedly. We'd want to do 10314 // likewise in the client code, which also does 10315 // dup suppression, before the Binder call. 10316 } else { 10317 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10318 mAlreadyLoggedViolatedStacks.clear(); 10319 } 10320 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10321 } 10322 } 10323 if (logIt) { 10324 logStrictModeViolationToDropBox(r, info); 10325 } 10326 } 10327 10328 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10329 AppErrorResult result = new AppErrorResult(); 10330 synchronized (this) { 10331 final long origId = Binder.clearCallingIdentity(); 10332 10333 Message msg = Message.obtain(); 10334 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10335 HashMap<String, Object> data = new HashMap<String, Object>(); 10336 data.put("result", result); 10337 data.put("app", r); 10338 data.put("violationMask", violationMask); 10339 data.put("info", info); 10340 msg.obj = data; 10341 mHandler.sendMessage(msg); 10342 10343 Binder.restoreCallingIdentity(origId); 10344 } 10345 int res = result.get(); 10346 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10347 } 10348 } 10349 10350 // Depending on the policy in effect, there could be a bunch of 10351 // these in quick succession so we try to batch these together to 10352 // minimize disk writes, number of dropbox entries, and maximize 10353 // compression, by having more fewer, larger records. 10354 private void logStrictModeViolationToDropBox( 10355 ProcessRecord process, 10356 StrictMode.ViolationInfo info) { 10357 if (info == null) { 10358 return; 10359 } 10360 final boolean isSystemApp = process == null || 10361 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10362 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10363 final String processName = process == null ? "unknown" : process.processName; 10364 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10365 final DropBoxManager dbox = (DropBoxManager) 10366 mContext.getSystemService(Context.DROPBOX_SERVICE); 10367 10368 // Exit early if the dropbox isn't configured to accept this report type. 10369 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10370 10371 boolean bufferWasEmpty; 10372 boolean needsFlush; 10373 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10374 synchronized (sb) { 10375 bufferWasEmpty = sb.length() == 0; 10376 appendDropBoxProcessHeaders(process, processName, sb); 10377 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10378 sb.append("System-App: ").append(isSystemApp).append("\n"); 10379 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10380 if (info.violationNumThisLoop != 0) { 10381 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10382 } 10383 if (info.numAnimationsRunning != 0) { 10384 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10385 } 10386 if (info.broadcastIntentAction != null) { 10387 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10388 } 10389 if (info.durationMillis != -1) { 10390 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10391 } 10392 if (info.numInstances != -1) { 10393 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10394 } 10395 if (info.tags != null) { 10396 for (String tag : info.tags) { 10397 sb.append("Span-Tag: ").append(tag).append("\n"); 10398 } 10399 } 10400 sb.append("\n"); 10401 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10402 sb.append(info.crashInfo.stackTrace); 10403 } 10404 sb.append("\n"); 10405 10406 // Only buffer up to ~64k. Various logging bits truncate 10407 // things at 128k. 10408 needsFlush = (sb.length() > 64 * 1024); 10409 } 10410 10411 // Flush immediately if the buffer's grown too large, or this 10412 // is a non-system app. Non-system apps are isolated with a 10413 // different tag & policy and not batched. 10414 // 10415 // Batching is useful during internal testing with 10416 // StrictMode settings turned up high. Without batching, 10417 // thousands of separate files could be created on boot. 10418 if (!isSystemApp || needsFlush) { 10419 new Thread("Error dump: " + dropboxTag) { 10420 @Override 10421 public void run() { 10422 String report; 10423 synchronized (sb) { 10424 report = sb.toString(); 10425 sb.delete(0, sb.length()); 10426 sb.trimToSize(); 10427 } 10428 if (report.length() != 0) { 10429 dbox.addText(dropboxTag, report); 10430 } 10431 } 10432 }.start(); 10433 return; 10434 } 10435 10436 // System app batching: 10437 if (!bufferWasEmpty) { 10438 // An existing dropbox-writing thread is outstanding, so 10439 // we don't need to start it up. The existing thread will 10440 // catch the buffer appends we just did. 10441 return; 10442 } 10443 10444 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10445 // (After this point, we shouldn't access AMS internal data structures.) 10446 new Thread("Error dump: " + dropboxTag) { 10447 @Override 10448 public void run() { 10449 // 5 second sleep to let stacks arrive and be batched together 10450 try { 10451 Thread.sleep(5000); // 5 seconds 10452 } catch (InterruptedException e) {} 10453 10454 String errorReport; 10455 synchronized (mStrictModeBuffer) { 10456 errorReport = mStrictModeBuffer.toString(); 10457 if (errorReport.length() == 0) { 10458 return; 10459 } 10460 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10461 mStrictModeBuffer.trimToSize(); 10462 } 10463 dbox.addText(dropboxTag, errorReport); 10464 } 10465 }.start(); 10466 } 10467 10468 /** 10469 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10470 * @param app object of the crashing app, null for the system server 10471 * @param tag reported by the caller 10472 * @param crashInfo describing the context of the error 10473 * @return true if the process should exit immediately (WTF is fatal) 10474 */ 10475 public boolean handleApplicationWtf(IBinder app, String tag, 10476 ApplicationErrorReport.CrashInfo crashInfo) { 10477 ProcessRecord r = findAppProcess(app, "WTF"); 10478 final String processName = app == null ? "system_server" 10479 : (r == null ? "unknown" : r.processName); 10480 10481 EventLog.writeEvent(EventLogTags.AM_WTF, 10482 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10483 processName, 10484 r == null ? -1 : r.info.flags, 10485 tag, crashInfo.exceptionMessage); 10486 10487 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10488 10489 if (r != null && r.pid != Process.myPid() && 10490 Settings.Global.getInt(mContext.getContentResolver(), 10491 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10492 crashApplication(r, crashInfo); 10493 return true; 10494 } else { 10495 return false; 10496 } 10497 } 10498 10499 /** 10500 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10501 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10502 */ 10503 private ProcessRecord findAppProcess(IBinder app, String reason) { 10504 if (app == null) { 10505 return null; 10506 } 10507 10508 synchronized (this) { 10509 final int NP = mProcessNames.getMap().size(); 10510 for (int ip=0; ip<NP; ip++) { 10511 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10512 final int NA = apps.size(); 10513 for (int ia=0; ia<NA; ia++) { 10514 ProcessRecord p = apps.valueAt(ia); 10515 if (p.thread != null && p.thread.asBinder() == app) { 10516 return p; 10517 } 10518 } 10519 } 10520 10521 Slog.w(TAG, "Can't find mystery application for " + reason 10522 + " from pid=" + Binder.getCallingPid() 10523 + " uid=" + Binder.getCallingUid() + ": " + app); 10524 return null; 10525 } 10526 } 10527 10528 /** 10529 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10530 * to append various headers to the dropbox log text. 10531 */ 10532 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10533 StringBuilder sb) { 10534 // Watchdog thread ends up invoking this function (with 10535 // a null ProcessRecord) to add the stack file to dropbox. 10536 // Do not acquire a lock on this (am) in such cases, as it 10537 // could cause a potential deadlock, if and when watchdog 10538 // is invoked due to unavailability of lock on am and it 10539 // would prevent watchdog from killing system_server. 10540 if (process == null) { 10541 sb.append("Process: ").append(processName).append("\n"); 10542 return; 10543 } 10544 // Note: ProcessRecord 'process' is guarded by the service 10545 // instance. (notably process.pkgList, which could otherwise change 10546 // concurrently during execution of this method) 10547 synchronized (this) { 10548 sb.append("Process: ").append(processName).append("\n"); 10549 int flags = process.info.flags; 10550 IPackageManager pm = AppGlobals.getPackageManager(); 10551 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10552 for (int ip=0; ip<process.pkgList.size(); ip++) { 10553 String pkg = process.pkgList.keyAt(ip); 10554 sb.append("Package: ").append(pkg); 10555 try { 10556 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10557 if (pi != null) { 10558 sb.append(" v").append(pi.versionCode); 10559 if (pi.versionName != null) { 10560 sb.append(" (").append(pi.versionName).append(")"); 10561 } 10562 } 10563 } catch (RemoteException e) { 10564 Slog.e(TAG, "Error getting package info: " + pkg, e); 10565 } 10566 sb.append("\n"); 10567 } 10568 } 10569 } 10570 10571 private static String processClass(ProcessRecord process) { 10572 if (process == null || process.pid == MY_PID) { 10573 return "system_server"; 10574 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10575 return "system_app"; 10576 } else { 10577 return "data_app"; 10578 } 10579 } 10580 10581 /** 10582 * Write a description of an error (crash, WTF, ANR) to the drop box. 10583 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10584 * @param process which caused the error, null means the system server 10585 * @param activity which triggered the error, null if unknown 10586 * @param parent activity related to the error, null if unknown 10587 * @param subject line related to the error, null if absent 10588 * @param report in long form describing the error, null if absent 10589 * @param logFile to include in the report, null if none 10590 * @param crashInfo giving an application stack trace, null if absent 10591 */ 10592 public void addErrorToDropBox(String eventType, 10593 ProcessRecord process, String processName, ActivityRecord activity, 10594 ActivityRecord parent, String subject, 10595 final String report, final File logFile, 10596 final ApplicationErrorReport.CrashInfo crashInfo) { 10597 // NOTE -- this must never acquire the ActivityManagerService lock, 10598 // otherwise the watchdog may be prevented from resetting the system. 10599 10600 final String dropboxTag = processClass(process) + "_" + eventType; 10601 final DropBoxManager dbox = (DropBoxManager) 10602 mContext.getSystemService(Context.DROPBOX_SERVICE); 10603 10604 // Exit early if the dropbox isn't configured to accept this report type. 10605 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10606 10607 final StringBuilder sb = new StringBuilder(1024); 10608 appendDropBoxProcessHeaders(process, processName, sb); 10609 if (activity != null) { 10610 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10611 } 10612 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10613 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10614 } 10615 if (parent != null && parent != activity) { 10616 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10617 } 10618 if (subject != null) { 10619 sb.append("Subject: ").append(subject).append("\n"); 10620 } 10621 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10622 if (Debug.isDebuggerConnected()) { 10623 sb.append("Debugger: Connected\n"); 10624 } 10625 sb.append("\n"); 10626 10627 // Do the rest in a worker thread to avoid blocking the caller on I/O 10628 // (After this point, we shouldn't access AMS internal data structures.) 10629 Thread worker = new Thread("Error dump: " + dropboxTag) { 10630 @Override 10631 public void run() { 10632 if (report != null) { 10633 sb.append(report); 10634 } 10635 if (logFile != null) { 10636 try { 10637 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10638 "\n\n[[TRUNCATED]]")); 10639 } catch (IOException e) { 10640 Slog.e(TAG, "Error reading " + logFile, e); 10641 } 10642 } 10643 if (crashInfo != null && crashInfo.stackTrace != null) { 10644 sb.append(crashInfo.stackTrace); 10645 } 10646 10647 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10648 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10649 if (lines > 0) { 10650 sb.append("\n"); 10651 10652 // Merge several logcat streams, and take the last N lines 10653 InputStreamReader input = null; 10654 try { 10655 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10656 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10657 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10658 10659 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10660 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10661 input = new InputStreamReader(logcat.getInputStream()); 10662 10663 int num; 10664 char[] buf = new char[8192]; 10665 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10666 } catch (IOException e) { 10667 Slog.e(TAG, "Error running logcat", e); 10668 } finally { 10669 if (input != null) try { input.close(); } catch (IOException e) {} 10670 } 10671 } 10672 10673 dbox.addText(dropboxTag, sb.toString()); 10674 } 10675 }; 10676 10677 if (process == null) { 10678 // If process is null, we are being called from some internal code 10679 // and may be about to die -- run this synchronously. 10680 worker.run(); 10681 } else { 10682 worker.start(); 10683 } 10684 } 10685 10686 /** 10687 * Bring up the "unexpected error" dialog box for a crashing app. 10688 * Deal with edge cases (intercepts from instrumented applications, 10689 * ActivityController, error intent receivers, that sort of thing). 10690 * @param r the application crashing 10691 * @param crashInfo describing the failure 10692 */ 10693 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10694 long timeMillis = System.currentTimeMillis(); 10695 String shortMsg = crashInfo.exceptionClassName; 10696 String longMsg = crashInfo.exceptionMessage; 10697 String stackTrace = crashInfo.stackTrace; 10698 if (shortMsg != null && longMsg != null) { 10699 longMsg = shortMsg + ": " + longMsg; 10700 } else if (shortMsg != null) { 10701 longMsg = shortMsg; 10702 } 10703 10704 AppErrorResult result = new AppErrorResult(); 10705 synchronized (this) { 10706 if (mController != null) { 10707 try { 10708 String name = r != null ? r.processName : null; 10709 int pid = r != null ? r.pid : Binder.getCallingPid(); 10710 if (!mController.appCrashed(name, pid, 10711 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10712 Slog.w(TAG, "Force-killing crashed app " + name 10713 + " at watcher's request"); 10714 Process.killProcess(pid); 10715 return; 10716 } 10717 } catch (RemoteException e) { 10718 mController = null; 10719 Watchdog.getInstance().setActivityController(null); 10720 } 10721 } 10722 10723 final long origId = Binder.clearCallingIdentity(); 10724 10725 // If this process is running instrumentation, finish it. 10726 if (r != null && r.instrumentationClass != null) { 10727 Slog.w(TAG, "Error in app " + r.processName 10728 + " running instrumentation " + r.instrumentationClass + ":"); 10729 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10730 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10731 Bundle info = new Bundle(); 10732 info.putString("shortMsg", shortMsg); 10733 info.putString("longMsg", longMsg); 10734 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10735 Binder.restoreCallingIdentity(origId); 10736 return; 10737 } 10738 10739 // If we can't identify the process or it's already exceeded its crash quota, 10740 // quit right away without showing a crash dialog. 10741 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10742 Binder.restoreCallingIdentity(origId); 10743 return; 10744 } 10745 10746 Message msg = Message.obtain(); 10747 msg.what = SHOW_ERROR_MSG; 10748 HashMap data = new HashMap(); 10749 data.put("result", result); 10750 data.put("app", r); 10751 msg.obj = data; 10752 mHandler.sendMessage(msg); 10753 10754 Binder.restoreCallingIdentity(origId); 10755 } 10756 10757 int res = result.get(); 10758 10759 Intent appErrorIntent = null; 10760 synchronized (this) { 10761 if (r != null && !r.isolated) { 10762 // XXX Can't keep track of crash time for isolated processes, 10763 // since they don't have a persistent identity. 10764 mProcessCrashTimes.put(r.info.processName, r.uid, 10765 SystemClock.uptimeMillis()); 10766 } 10767 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10768 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10769 } 10770 } 10771 10772 if (appErrorIntent != null) { 10773 try { 10774 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10775 } catch (ActivityNotFoundException e) { 10776 Slog.w(TAG, "bug report receiver dissappeared", e); 10777 } 10778 } 10779 } 10780 10781 Intent createAppErrorIntentLocked(ProcessRecord r, 10782 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10783 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10784 if (report == null) { 10785 return null; 10786 } 10787 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10788 result.setComponent(r.errorReportReceiver); 10789 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10790 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10791 return result; 10792 } 10793 10794 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10795 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10796 if (r.errorReportReceiver == null) { 10797 return null; 10798 } 10799 10800 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10801 return null; 10802 } 10803 10804 ApplicationErrorReport report = new ApplicationErrorReport(); 10805 report.packageName = r.info.packageName; 10806 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10807 report.processName = r.processName; 10808 report.time = timeMillis; 10809 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10810 10811 if (r.crashing || r.forceCrashReport) { 10812 report.type = ApplicationErrorReport.TYPE_CRASH; 10813 report.crashInfo = crashInfo; 10814 } else if (r.notResponding) { 10815 report.type = ApplicationErrorReport.TYPE_ANR; 10816 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10817 10818 report.anrInfo.activity = r.notRespondingReport.tag; 10819 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10820 report.anrInfo.info = r.notRespondingReport.longMsg; 10821 } 10822 10823 return report; 10824 } 10825 10826 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10827 enforceNotIsolatedCaller("getProcessesInErrorState"); 10828 // assume our apps are happy - lazy create the list 10829 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10830 10831 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10832 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10833 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10834 10835 synchronized (this) { 10836 10837 // iterate across all processes 10838 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10839 ProcessRecord app = mLruProcesses.get(i); 10840 if (!allUsers && app.userId != userId) { 10841 continue; 10842 } 10843 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10844 // This one's in trouble, so we'll generate a report for it 10845 // crashes are higher priority (in case there's a crash *and* an anr) 10846 ActivityManager.ProcessErrorStateInfo report = null; 10847 if (app.crashing) { 10848 report = app.crashingReport; 10849 } else if (app.notResponding) { 10850 report = app.notRespondingReport; 10851 } 10852 10853 if (report != null) { 10854 if (errList == null) { 10855 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10856 } 10857 errList.add(report); 10858 } else { 10859 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10860 " crashing = " + app.crashing + 10861 " notResponding = " + app.notResponding); 10862 } 10863 } 10864 } 10865 } 10866 10867 return errList; 10868 } 10869 10870 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10871 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10872 if (currApp != null) { 10873 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10874 } 10875 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10876 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10877 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10878 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10879 if (currApp != null) { 10880 currApp.lru = 0; 10881 } 10882 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10883 } else if (adj >= ProcessList.SERVICE_ADJ) { 10884 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10885 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10886 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10887 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10888 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10889 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10890 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10891 } else { 10892 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10893 } 10894 } 10895 10896 private void fillInProcMemInfo(ProcessRecord app, 10897 ActivityManager.RunningAppProcessInfo outInfo) { 10898 outInfo.pid = app.pid; 10899 outInfo.uid = app.info.uid; 10900 if (mHeavyWeightProcess == app) { 10901 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10902 } 10903 if (app.persistent) { 10904 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10905 } 10906 if (app.activities.size() > 0) { 10907 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10908 } 10909 outInfo.lastTrimLevel = app.trimMemoryLevel; 10910 int adj = app.curAdj; 10911 outInfo.importance = oomAdjToImportance(adj, outInfo); 10912 outInfo.importanceReasonCode = app.adjTypeCode; 10913 outInfo.processState = app.curProcState; 10914 } 10915 10916 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10917 enforceNotIsolatedCaller("getRunningAppProcesses"); 10918 // Lazy instantiation of list 10919 List<ActivityManager.RunningAppProcessInfo> runList = null; 10920 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10921 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10922 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10923 synchronized (this) { 10924 // Iterate across all processes 10925 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10926 ProcessRecord app = mLruProcesses.get(i); 10927 if (!allUsers && app.userId != userId) { 10928 continue; 10929 } 10930 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10931 // Generate process state info for running application 10932 ActivityManager.RunningAppProcessInfo currApp = 10933 new ActivityManager.RunningAppProcessInfo(app.processName, 10934 app.pid, app.getPackageList()); 10935 fillInProcMemInfo(app, currApp); 10936 if (app.adjSource instanceof ProcessRecord) { 10937 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10938 currApp.importanceReasonImportance = oomAdjToImportance( 10939 app.adjSourceOom, null); 10940 } else if (app.adjSource instanceof ActivityRecord) { 10941 ActivityRecord r = (ActivityRecord)app.adjSource; 10942 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10943 } 10944 if (app.adjTarget instanceof ComponentName) { 10945 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10946 } 10947 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10948 // + " lru=" + currApp.lru); 10949 if (runList == null) { 10950 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10951 } 10952 runList.add(currApp); 10953 } 10954 } 10955 } 10956 return runList; 10957 } 10958 10959 public List<ApplicationInfo> getRunningExternalApplications() { 10960 enforceNotIsolatedCaller("getRunningExternalApplications"); 10961 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10962 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10963 if (runningApps != null && runningApps.size() > 0) { 10964 Set<String> extList = new HashSet<String>(); 10965 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10966 if (app.pkgList != null) { 10967 for (String pkg : app.pkgList) { 10968 extList.add(pkg); 10969 } 10970 } 10971 } 10972 IPackageManager pm = AppGlobals.getPackageManager(); 10973 for (String pkg : extList) { 10974 try { 10975 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10976 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10977 retList.add(info); 10978 } 10979 } catch (RemoteException e) { 10980 } 10981 } 10982 } 10983 return retList; 10984 } 10985 10986 @Override 10987 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10988 enforceNotIsolatedCaller("getMyMemoryState"); 10989 synchronized (this) { 10990 ProcessRecord proc; 10991 synchronized (mPidsSelfLocked) { 10992 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10993 } 10994 fillInProcMemInfo(proc, outInfo); 10995 } 10996 } 10997 10998 @Override 10999 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11000 if (checkCallingPermission(android.Manifest.permission.DUMP) 11001 != PackageManager.PERMISSION_GRANTED) { 11002 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11003 + Binder.getCallingPid() 11004 + ", uid=" + Binder.getCallingUid() 11005 + " without permission " 11006 + android.Manifest.permission.DUMP); 11007 return; 11008 } 11009 11010 boolean dumpAll = false; 11011 boolean dumpClient = false; 11012 String dumpPackage = null; 11013 11014 int opti = 0; 11015 while (opti < args.length) { 11016 String opt = args[opti]; 11017 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11018 break; 11019 } 11020 opti++; 11021 if ("-a".equals(opt)) { 11022 dumpAll = true; 11023 } else if ("-c".equals(opt)) { 11024 dumpClient = true; 11025 } else if ("-h".equals(opt)) { 11026 pw.println("Activity manager dump options:"); 11027 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11028 pw.println(" cmd may be one of:"); 11029 pw.println(" a[ctivities]: activity stack state"); 11030 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11031 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11032 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11033 pw.println(" o[om]: out of memory management"); 11034 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11035 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11036 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11037 pw.println(" service [COMP_SPEC]: service client-side state"); 11038 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11039 pw.println(" all: dump all activities"); 11040 pw.println(" top: dump the top activity"); 11041 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11042 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11043 pw.println(" a partial substring in a component name, a"); 11044 pw.println(" hex object identifier."); 11045 pw.println(" -a: include all available server state."); 11046 pw.println(" -c: include client state."); 11047 return; 11048 } else { 11049 pw.println("Unknown argument: " + opt + "; use -h for help"); 11050 } 11051 } 11052 11053 long origId = Binder.clearCallingIdentity(); 11054 boolean more = false; 11055 // Is the caller requesting to dump a particular piece of data? 11056 if (opti < args.length) { 11057 String cmd = args[opti]; 11058 opti++; 11059 if ("activities".equals(cmd) || "a".equals(cmd)) { 11060 synchronized (this) { 11061 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11062 } 11063 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11064 String[] newArgs; 11065 String name; 11066 if (opti >= args.length) { 11067 name = null; 11068 newArgs = EMPTY_STRING_ARRAY; 11069 } else { 11070 name = args[opti]; 11071 opti++; 11072 newArgs = new String[args.length - opti]; 11073 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11074 args.length - opti); 11075 } 11076 synchronized (this) { 11077 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11078 } 11079 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11080 String[] newArgs; 11081 String name; 11082 if (opti >= args.length) { 11083 name = null; 11084 newArgs = EMPTY_STRING_ARRAY; 11085 } else { 11086 name = args[opti]; 11087 opti++; 11088 newArgs = new String[args.length - opti]; 11089 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11090 args.length - opti); 11091 } 11092 synchronized (this) { 11093 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11094 } 11095 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11096 String[] newArgs; 11097 String name; 11098 if (opti >= args.length) { 11099 name = null; 11100 newArgs = EMPTY_STRING_ARRAY; 11101 } else { 11102 name = args[opti]; 11103 opti++; 11104 newArgs = new String[args.length - opti]; 11105 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11106 args.length - opti); 11107 } 11108 synchronized (this) { 11109 dumpProcessesLocked(fd, pw, args, opti, true, name); 11110 } 11111 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11112 synchronized (this) { 11113 dumpOomLocked(fd, pw, args, opti, true); 11114 } 11115 } else if ("provider".equals(cmd)) { 11116 String[] newArgs; 11117 String name; 11118 if (opti >= args.length) { 11119 name = null; 11120 newArgs = EMPTY_STRING_ARRAY; 11121 } else { 11122 name = args[opti]; 11123 opti++; 11124 newArgs = new String[args.length - opti]; 11125 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11126 } 11127 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11128 pw.println("No providers match: " + name); 11129 pw.println("Use -h for help."); 11130 } 11131 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11132 synchronized (this) { 11133 dumpProvidersLocked(fd, pw, args, opti, true, null); 11134 } 11135 } else if ("service".equals(cmd)) { 11136 String[] newArgs; 11137 String name; 11138 if (opti >= args.length) { 11139 name = null; 11140 newArgs = EMPTY_STRING_ARRAY; 11141 } else { 11142 name = args[opti]; 11143 opti++; 11144 newArgs = new String[args.length - opti]; 11145 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11146 args.length - opti); 11147 } 11148 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11149 pw.println("No services match: " + name); 11150 pw.println("Use -h for help."); 11151 } 11152 } else if ("package".equals(cmd)) { 11153 String[] newArgs; 11154 if (opti >= args.length) { 11155 pw.println("package: no package name specified"); 11156 pw.println("Use -h for help."); 11157 } else { 11158 dumpPackage = args[opti]; 11159 opti++; 11160 newArgs = new String[args.length - opti]; 11161 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11162 args.length - opti); 11163 args = newArgs; 11164 opti = 0; 11165 more = true; 11166 } 11167 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11168 synchronized (this) { 11169 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11170 } 11171 } else { 11172 // Dumping a single activity? 11173 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11174 pw.println("Bad activity command, or no activities match: " + cmd); 11175 pw.println("Use -h for help."); 11176 } 11177 } 11178 if (!more) { 11179 Binder.restoreCallingIdentity(origId); 11180 return; 11181 } 11182 } 11183 11184 // No piece of data specified, dump everything. 11185 synchronized (this) { 11186 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11187 pw.println(); 11188 if (dumpAll) { 11189 pw.println("-------------------------------------------------------------------------------"); 11190 } 11191 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11192 pw.println(); 11193 if (dumpAll) { 11194 pw.println("-------------------------------------------------------------------------------"); 11195 } 11196 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11197 pw.println(); 11198 if (dumpAll) { 11199 pw.println("-------------------------------------------------------------------------------"); 11200 } 11201 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11202 pw.println(); 11203 if (dumpAll) { 11204 pw.println("-------------------------------------------------------------------------------"); 11205 } 11206 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11207 pw.println(); 11208 if (dumpAll) { 11209 pw.println("-------------------------------------------------------------------------------"); 11210 } 11211 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11212 } 11213 Binder.restoreCallingIdentity(origId); 11214 } 11215 11216 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11217 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11218 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11219 11220 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11221 dumpPackage); 11222 boolean needSep = printedAnything; 11223 11224 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11225 dumpPackage, needSep, " mFocusedActivity: "); 11226 if (printed) { 11227 printedAnything = true; 11228 needSep = false; 11229 } 11230 11231 if (dumpPackage == null) { 11232 if (needSep) { 11233 pw.println(); 11234 } 11235 needSep = true; 11236 printedAnything = true; 11237 mStackSupervisor.dump(pw, " "); 11238 } 11239 11240 if (mRecentTasks.size() > 0) { 11241 boolean printedHeader = false; 11242 11243 final int N = mRecentTasks.size(); 11244 for (int i=0; i<N; i++) { 11245 TaskRecord tr = mRecentTasks.get(i); 11246 if (dumpPackage != null) { 11247 if (tr.realActivity == null || 11248 !dumpPackage.equals(tr.realActivity)) { 11249 continue; 11250 } 11251 } 11252 if (!printedHeader) { 11253 if (needSep) { 11254 pw.println(); 11255 } 11256 pw.println(" Recent tasks:"); 11257 printedHeader = true; 11258 printedAnything = true; 11259 } 11260 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11261 pw.println(tr); 11262 if (dumpAll) { 11263 mRecentTasks.get(i).dump(pw, " "); 11264 } 11265 } 11266 } 11267 11268 if (!printedAnything) { 11269 pw.println(" (nothing)"); 11270 } 11271 } 11272 11273 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11274 int opti, boolean dumpAll, String dumpPackage) { 11275 boolean needSep = false; 11276 boolean printedAnything = false; 11277 int numPers = 0; 11278 11279 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11280 11281 if (dumpAll) { 11282 final int NP = mProcessNames.getMap().size(); 11283 for (int ip=0; ip<NP; ip++) { 11284 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11285 final int NA = procs.size(); 11286 for (int ia=0; ia<NA; ia++) { 11287 ProcessRecord r = procs.valueAt(ia); 11288 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11289 continue; 11290 } 11291 if (!needSep) { 11292 pw.println(" All known processes:"); 11293 needSep = true; 11294 printedAnything = true; 11295 } 11296 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11297 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11298 pw.print(" "); pw.println(r); 11299 r.dump(pw, " "); 11300 if (r.persistent) { 11301 numPers++; 11302 } 11303 } 11304 } 11305 } 11306 11307 if (mIsolatedProcesses.size() > 0) { 11308 boolean printed = false; 11309 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11310 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11311 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11312 continue; 11313 } 11314 if (!printed) { 11315 if (needSep) { 11316 pw.println(); 11317 } 11318 pw.println(" Isolated process list (sorted by uid):"); 11319 printedAnything = true; 11320 printed = true; 11321 needSep = true; 11322 } 11323 pw.println(String.format("%sIsolated #%2d: %s", 11324 " ", i, r.toString())); 11325 } 11326 } 11327 11328 if (mLruProcesses.size() > 0) { 11329 if (needSep) { 11330 pw.println(); 11331 } 11332 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11333 pw.print(" total, non-act at "); 11334 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11335 pw.print(", non-svc at "); 11336 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11337 pw.println("):"); 11338 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11339 needSep = true; 11340 printedAnything = true; 11341 } 11342 11343 if (dumpAll || dumpPackage != null) { 11344 synchronized (mPidsSelfLocked) { 11345 boolean printed = false; 11346 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11347 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11348 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11349 continue; 11350 } 11351 if (!printed) { 11352 if (needSep) pw.println(); 11353 needSep = true; 11354 pw.println(" PID mappings:"); 11355 printed = true; 11356 printedAnything = true; 11357 } 11358 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11359 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11360 } 11361 } 11362 } 11363 11364 if (mForegroundProcesses.size() > 0) { 11365 synchronized (mPidsSelfLocked) { 11366 boolean printed = false; 11367 for (int i=0; i<mForegroundProcesses.size(); i++) { 11368 ProcessRecord r = mPidsSelfLocked.get( 11369 mForegroundProcesses.valueAt(i).pid); 11370 if (dumpPackage != null && (r == null 11371 || !r.pkgList.containsKey(dumpPackage))) { 11372 continue; 11373 } 11374 if (!printed) { 11375 if (needSep) pw.println(); 11376 needSep = true; 11377 pw.println(" Foreground Processes:"); 11378 printed = true; 11379 printedAnything = true; 11380 } 11381 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11382 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11383 } 11384 } 11385 } 11386 11387 if (mPersistentStartingProcesses.size() > 0) { 11388 if (needSep) pw.println(); 11389 needSep = true; 11390 printedAnything = true; 11391 pw.println(" Persisent processes that are starting:"); 11392 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11393 "Starting Norm", "Restarting PERS", dumpPackage); 11394 } 11395 11396 if (mRemovedProcesses.size() > 0) { 11397 if (needSep) pw.println(); 11398 needSep = true; 11399 printedAnything = true; 11400 pw.println(" Processes that are being removed:"); 11401 dumpProcessList(pw, this, mRemovedProcesses, " ", 11402 "Removed Norm", "Removed PERS", dumpPackage); 11403 } 11404 11405 if (mProcessesOnHold.size() > 0) { 11406 if (needSep) pw.println(); 11407 needSep = true; 11408 printedAnything = true; 11409 pw.println(" Processes that are on old until the system is ready:"); 11410 dumpProcessList(pw, this, mProcessesOnHold, " ", 11411 "OnHold Norm", "OnHold PERS", dumpPackage); 11412 } 11413 11414 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11415 11416 if (mProcessCrashTimes.getMap().size() > 0) { 11417 boolean printed = false; 11418 long now = SystemClock.uptimeMillis(); 11419 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11420 final int NP = pmap.size(); 11421 for (int ip=0; ip<NP; ip++) { 11422 String pname = pmap.keyAt(ip); 11423 SparseArray<Long> uids = pmap.valueAt(ip); 11424 final int N = uids.size(); 11425 for (int i=0; i<N; i++) { 11426 int puid = uids.keyAt(i); 11427 ProcessRecord r = mProcessNames.get(pname, puid); 11428 if (dumpPackage != null && (r == null 11429 || !r.pkgList.containsKey(dumpPackage))) { 11430 continue; 11431 } 11432 if (!printed) { 11433 if (needSep) pw.println(); 11434 needSep = true; 11435 pw.println(" Time since processes crashed:"); 11436 printed = true; 11437 printedAnything = true; 11438 } 11439 pw.print(" Process "); pw.print(pname); 11440 pw.print(" uid "); pw.print(puid); 11441 pw.print(": last crashed "); 11442 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11443 pw.println(" ago"); 11444 } 11445 } 11446 } 11447 11448 if (mBadProcesses.getMap().size() > 0) { 11449 boolean printed = false; 11450 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11451 final int NP = pmap.size(); 11452 for (int ip=0; ip<NP; ip++) { 11453 String pname = pmap.keyAt(ip); 11454 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11455 final int N = uids.size(); 11456 for (int i=0; i<N; i++) { 11457 int puid = uids.keyAt(i); 11458 ProcessRecord r = mProcessNames.get(pname, puid); 11459 if (dumpPackage != null && (r == null 11460 || !r.pkgList.containsKey(dumpPackage))) { 11461 continue; 11462 } 11463 if (!printed) { 11464 if (needSep) pw.println(); 11465 needSep = true; 11466 pw.println(" Bad processes:"); 11467 printedAnything = true; 11468 } 11469 BadProcessInfo info = uids.valueAt(i); 11470 pw.print(" Bad process "); pw.print(pname); 11471 pw.print(" uid "); pw.print(puid); 11472 pw.print(": crashed at time "); pw.println(info.time); 11473 if (info.shortMsg != null) { 11474 pw.print(" Short msg: "); pw.println(info.shortMsg); 11475 } 11476 if (info.longMsg != null) { 11477 pw.print(" Long msg: "); pw.println(info.longMsg); 11478 } 11479 if (info.stack != null) { 11480 pw.println(" Stack:"); 11481 int lastPos = 0; 11482 for (int pos=0; pos<info.stack.length(); pos++) { 11483 if (info.stack.charAt(pos) == '\n') { 11484 pw.print(" "); 11485 pw.write(info.stack, lastPos, pos-lastPos); 11486 pw.println(); 11487 lastPos = pos+1; 11488 } 11489 } 11490 if (lastPos < info.stack.length()) { 11491 pw.print(" "); 11492 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11493 pw.println(); 11494 } 11495 } 11496 } 11497 } 11498 } 11499 11500 if (dumpPackage == null) { 11501 pw.println(); 11502 needSep = false; 11503 pw.println(" mStartedUsers:"); 11504 for (int i=0; i<mStartedUsers.size(); i++) { 11505 UserStartedState uss = mStartedUsers.valueAt(i); 11506 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11507 pw.print(": "); uss.dump("", pw); 11508 } 11509 pw.print(" mStartedUserArray: ["); 11510 for (int i=0; i<mStartedUserArray.length; i++) { 11511 if (i > 0) pw.print(", "); 11512 pw.print(mStartedUserArray[i]); 11513 } 11514 pw.println("]"); 11515 pw.print(" mUserLru: ["); 11516 for (int i=0; i<mUserLru.size(); i++) { 11517 if (i > 0) pw.print(", "); 11518 pw.print(mUserLru.get(i)); 11519 } 11520 pw.println("]"); 11521 if (dumpAll) { 11522 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11523 } 11524 } 11525 if (mHomeProcess != null && (dumpPackage == null 11526 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11527 if (needSep) { 11528 pw.println(); 11529 needSep = false; 11530 } 11531 pw.println(" mHomeProcess: " + mHomeProcess); 11532 } 11533 if (mPreviousProcess != null && (dumpPackage == null 11534 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11535 if (needSep) { 11536 pw.println(); 11537 needSep = false; 11538 } 11539 pw.println(" mPreviousProcess: " + mPreviousProcess); 11540 } 11541 if (dumpAll) { 11542 StringBuilder sb = new StringBuilder(128); 11543 sb.append(" mPreviousProcessVisibleTime: "); 11544 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11545 pw.println(sb); 11546 } 11547 if (mHeavyWeightProcess != null && (dumpPackage == null 11548 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11549 if (needSep) { 11550 pw.println(); 11551 needSep = false; 11552 } 11553 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11554 } 11555 if (dumpPackage == null) { 11556 pw.println(" mConfiguration: " + mConfiguration); 11557 } 11558 if (dumpAll) { 11559 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11560 if (mCompatModePackages.getPackages().size() > 0) { 11561 boolean printed = false; 11562 for (Map.Entry<String, Integer> entry 11563 : mCompatModePackages.getPackages().entrySet()) { 11564 String pkg = entry.getKey(); 11565 int mode = entry.getValue(); 11566 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11567 continue; 11568 } 11569 if (!printed) { 11570 pw.println(" mScreenCompatPackages:"); 11571 printed = true; 11572 } 11573 pw.print(" "); pw.print(pkg); pw.print(": "); 11574 pw.print(mode); pw.println(); 11575 } 11576 } 11577 } 11578 if (dumpPackage == null) { 11579 if (mSleeping || mWentToSleep || mLockScreenShown) { 11580 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11581 + " mLockScreenShown " + mLockScreenShown); 11582 } 11583 if (mShuttingDown || mRunningVoice) { 11584 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11585 } 11586 } 11587 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11588 || mOrigWaitForDebugger) { 11589 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11590 || dumpPackage.equals(mOrigDebugApp)) { 11591 if (needSep) { 11592 pw.println(); 11593 needSep = false; 11594 } 11595 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11596 + " mDebugTransient=" + mDebugTransient 11597 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11598 } 11599 } 11600 if (mOpenGlTraceApp != null) { 11601 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11602 if (needSep) { 11603 pw.println(); 11604 needSep = false; 11605 } 11606 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11607 } 11608 } 11609 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11610 || mProfileFd != null) { 11611 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11612 if (needSep) { 11613 pw.println(); 11614 needSep = false; 11615 } 11616 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11617 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11618 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11619 + mAutoStopProfiler); 11620 } 11621 } 11622 if (dumpPackage == null) { 11623 if (mAlwaysFinishActivities || mController != null) { 11624 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11625 + " mController=" + mController); 11626 } 11627 if (dumpAll) { 11628 pw.println(" Total persistent processes: " + numPers); 11629 pw.println(" mProcessesReady=" + mProcessesReady 11630 + " mSystemReady=" + mSystemReady); 11631 pw.println(" mBooting=" + mBooting 11632 + " mBooted=" + mBooted 11633 + " mFactoryTest=" + mFactoryTest); 11634 pw.print(" mLastPowerCheckRealtime="); 11635 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11636 pw.println(""); 11637 pw.print(" mLastPowerCheckUptime="); 11638 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11639 pw.println(""); 11640 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11641 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11642 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11643 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11644 + " (" + mLruProcesses.size() + " total)" 11645 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11646 + " mNumServiceProcs=" + mNumServiceProcs 11647 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11648 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11649 + " mLastMemoryLevel" + mLastMemoryLevel 11650 + " mLastNumProcesses" + mLastNumProcesses); 11651 long now = SystemClock.uptimeMillis(); 11652 pw.print(" mLastIdleTime="); 11653 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11654 pw.print(" mLowRamSinceLastIdle="); 11655 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11656 pw.println(); 11657 } 11658 } 11659 11660 if (!printedAnything) { 11661 pw.println(" (nothing)"); 11662 } 11663 } 11664 11665 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11666 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11667 if (mProcessesToGc.size() > 0) { 11668 boolean printed = false; 11669 long now = SystemClock.uptimeMillis(); 11670 for (int i=0; i<mProcessesToGc.size(); i++) { 11671 ProcessRecord proc = mProcessesToGc.get(i); 11672 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11673 continue; 11674 } 11675 if (!printed) { 11676 if (needSep) pw.println(); 11677 needSep = true; 11678 pw.println(" Processes that are waiting to GC:"); 11679 printed = true; 11680 } 11681 pw.print(" Process "); pw.println(proc); 11682 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11683 pw.print(", last gced="); 11684 pw.print(now-proc.lastRequestedGc); 11685 pw.print(" ms ago, last lowMem="); 11686 pw.print(now-proc.lastLowMemory); 11687 pw.println(" ms ago"); 11688 11689 } 11690 } 11691 return needSep; 11692 } 11693 11694 void printOomLevel(PrintWriter pw, String name, int adj) { 11695 pw.print(" "); 11696 if (adj >= 0) { 11697 pw.print(' '); 11698 if (adj < 10) pw.print(' '); 11699 } else { 11700 if (adj > -10) pw.print(' '); 11701 } 11702 pw.print(adj); 11703 pw.print(": "); 11704 pw.print(name); 11705 pw.print(" ("); 11706 pw.print(mProcessList.getMemLevel(adj)/1024); 11707 pw.println(" kB)"); 11708 } 11709 11710 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11711 int opti, boolean dumpAll) { 11712 boolean needSep = false; 11713 11714 if (mLruProcesses.size() > 0) { 11715 if (needSep) pw.println(); 11716 needSep = true; 11717 pw.println(" OOM levels:"); 11718 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11719 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11720 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11721 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11722 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11723 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11724 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11725 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11726 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11727 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11728 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11729 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11730 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11731 11732 if (needSep) pw.println(); 11733 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11734 pw.print(" total, non-act at "); 11735 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11736 pw.print(", non-svc at "); 11737 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11738 pw.println("):"); 11739 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11740 needSep = true; 11741 } 11742 11743 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11744 11745 pw.println(); 11746 pw.println(" mHomeProcess: " + mHomeProcess); 11747 pw.println(" mPreviousProcess: " + mPreviousProcess); 11748 if (mHeavyWeightProcess != null) { 11749 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11750 } 11751 11752 return true; 11753 } 11754 11755 /** 11756 * There are three ways to call this: 11757 * - no provider specified: dump all the providers 11758 * - a flattened component name that matched an existing provider was specified as the 11759 * first arg: dump that one provider 11760 * - the first arg isn't the flattened component name of an existing provider: 11761 * dump all providers whose component contains the first arg as a substring 11762 */ 11763 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11764 int opti, boolean dumpAll) { 11765 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11766 } 11767 11768 static class ItemMatcher { 11769 ArrayList<ComponentName> components; 11770 ArrayList<String> strings; 11771 ArrayList<Integer> objects; 11772 boolean all; 11773 11774 ItemMatcher() { 11775 all = true; 11776 } 11777 11778 void build(String name) { 11779 ComponentName componentName = ComponentName.unflattenFromString(name); 11780 if (componentName != null) { 11781 if (components == null) { 11782 components = new ArrayList<ComponentName>(); 11783 } 11784 components.add(componentName); 11785 all = false; 11786 } else { 11787 int objectId = 0; 11788 // Not a '/' separated full component name; maybe an object ID? 11789 try { 11790 objectId = Integer.parseInt(name, 16); 11791 if (objects == null) { 11792 objects = new ArrayList<Integer>(); 11793 } 11794 objects.add(objectId); 11795 all = false; 11796 } catch (RuntimeException e) { 11797 // Not an integer; just do string match. 11798 if (strings == null) { 11799 strings = new ArrayList<String>(); 11800 } 11801 strings.add(name); 11802 all = false; 11803 } 11804 } 11805 } 11806 11807 int build(String[] args, int opti) { 11808 for (; opti<args.length; opti++) { 11809 String name = args[opti]; 11810 if ("--".equals(name)) { 11811 return opti+1; 11812 } 11813 build(name); 11814 } 11815 return opti; 11816 } 11817 11818 boolean match(Object object, ComponentName comp) { 11819 if (all) { 11820 return true; 11821 } 11822 if (components != null) { 11823 for (int i=0; i<components.size(); i++) { 11824 if (components.get(i).equals(comp)) { 11825 return true; 11826 } 11827 } 11828 } 11829 if (objects != null) { 11830 for (int i=0; i<objects.size(); i++) { 11831 if (System.identityHashCode(object) == objects.get(i)) { 11832 return true; 11833 } 11834 } 11835 } 11836 if (strings != null) { 11837 String flat = comp.flattenToString(); 11838 for (int i=0; i<strings.size(); i++) { 11839 if (flat.contains(strings.get(i))) { 11840 return true; 11841 } 11842 } 11843 } 11844 return false; 11845 } 11846 } 11847 11848 /** 11849 * There are three things that cmd can be: 11850 * - a flattened component name that matches an existing activity 11851 * - the cmd arg isn't the flattened component name of an existing activity: 11852 * dump all activity whose component contains the cmd as a substring 11853 * - A hex number of the ActivityRecord object instance. 11854 */ 11855 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11856 int opti, boolean dumpAll) { 11857 ArrayList<ActivityRecord> activities; 11858 11859 synchronized (this) { 11860 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11861 } 11862 11863 if (activities.size() <= 0) { 11864 return false; 11865 } 11866 11867 String[] newArgs = new String[args.length - opti]; 11868 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11869 11870 TaskRecord lastTask = null; 11871 boolean needSep = false; 11872 for (int i=activities.size()-1; i>=0; i--) { 11873 ActivityRecord r = activities.get(i); 11874 if (needSep) { 11875 pw.println(); 11876 } 11877 needSep = true; 11878 synchronized (this) { 11879 if (lastTask != r.task) { 11880 lastTask = r.task; 11881 pw.print("TASK "); pw.print(lastTask.affinity); 11882 pw.print(" id="); pw.println(lastTask.taskId); 11883 if (dumpAll) { 11884 lastTask.dump(pw, " "); 11885 } 11886 } 11887 } 11888 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11889 } 11890 return true; 11891 } 11892 11893 /** 11894 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11895 * there is a thread associated with the activity. 11896 */ 11897 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11898 final ActivityRecord r, String[] args, boolean dumpAll) { 11899 String innerPrefix = prefix + " "; 11900 synchronized (this) { 11901 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11902 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11903 pw.print(" pid="); 11904 if (r.app != null) pw.println(r.app.pid); 11905 else pw.println("(not running)"); 11906 if (dumpAll) { 11907 r.dump(pw, innerPrefix); 11908 } 11909 } 11910 if (r.app != null && r.app.thread != null) { 11911 // flush anything that is already in the PrintWriter since the thread is going 11912 // to write to the file descriptor directly 11913 pw.flush(); 11914 try { 11915 TransferPipe tp = new TransferPipe(); 11916 try { 11917 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11918 r.appToken, innerPrefix, args); 11919 tp.go(fd); 11920 } finally { 11921 tp.kill(); 11922 } 11923 } catch (IOException e) { 11924 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11925 } catch (RemoteException e) { 11926 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11927 } 11928 } 11929 } 11930 11931 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11932 int opti, boolean dumpAll, String dumpPackage) { 11933 boolean needSep = false; 11934 boolean onlyHistory = false; 11935 boolean printedAnything = false; 11936 11937 if ("history".equals(dumpPackage)) { 11938 if (opti < args.length && "-s".equals(args[opti])) { 11939 dumpAll = false; 11940 } 11941 onlyHistory = true; 11942 dumpPackage = null; 11943 } 11944 11945 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11946 if (!onlyHistory && dumpAll) { 11947 if (mRegisteredReceivers.size() > 0) { 11948 boolean printed = false; 11949 Iterator it = mRegisteredReceivers.values().iterator(); 11950 while (it.hasNext()) { 11951 ReceiverList r = (ReceiverList)it.next(); 11952 if (dumpPackage != null && (r.app == null || 11953 !dumpPackage.equals(r.app.info.packageName))) { 11954 continue; 11955 } 11956 if (!printed) { 11957 pw.println(" Registered Receivers:"); 11958 needSep = true; 11959 printed = true; 11960 printedAnything = true; 11961 } 11962 pw.print(" * "); pw.println(r); 11963 r.dump(pw, " "); 11964 } 11965 } 11966 11967 if (mReceiverResolver.dump(pw, needSep ? 11968 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11969 " ", dumpPackage, false)) { 11970 needSep = true; 11971 printedAnything = true; 11972 } 11973 } 11974 11975 for (BroadcastQueue q : mBroadcastQueues) { 11976 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11977 printedAnything |= needSep; 11978 } 11979 11980 needSep = true; 11981 11982 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11983 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11984 if (needSep) { 11985 pw.println(); 11986 } 11987 needSep = true; 11988 printedAnything = true; 11989 pw.print(" Sticky broadcasts for user "); 11990 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11991 StringBuilder sb = new StringBuilder(128); 11992 for (Map.Entry<String, ArrayList<Intent>> ent 11993 : mStickyBroadcasts.valueAt(user).entrySet()) { 11994 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11995 if (dumpAll) { 11996 pw.println(":"); 11997 ArrayList<Intent> intents = ent.getValue(); 11998 final int N = intents.size(); 11999 for (int i=0; i<N; i++) { 12000 sb.setLength(0); 12001 sb.append(" Intent: "); 12002 intents.get(i).toShortString(sb, false, true, false, false); 12003 pw.println(sb.toString()); 12004 Bundle bundle = intents.get(i).getExtras(); 12005 if (bundle != null) { 12006 pw.print(" "); 12007 pw.println(bundle.toString()); 12008 } 12009 } 12010 } else { 12011 pw.println(""); 12012 } 12013 } 12014 } 12015 } 12016 12017 if (!onlyHistory && dumpAll) { 12018 pw.println(); 12019 for (BroadcastQueue queue : mBroadcastQueues) { 12020 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12021 + queue.mBroadcastsScheduled); 12022 } 12023 pw.println(" mHandler:"); 12024 mHandler.dump(new PrintWriterPrinter(pw), " "); 12025 needSep = true; 12026 printedAnything = true; 12027 } 12028 12029 if (!printedAnything) { 12030 pw.println(" (nothing)"); 12031 } 12032 } 12033 12034 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12035 int opti, boolean dumpAll, String dumpPackage) { 12036 boolean needSep; 12037 boolean printedAnything = false; 12038 12039 ItemMatcher matcher = new ItemMatcher(); 12040 matcher.build(args, opti); 12041 12042 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12043 12044 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12045 printedAnything |= needSep; 12046 12047 if (mLaunchingProviders.size() > 0) { 12048 boolean printed = false; 12049 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12050 ContentProviderRecord r = mLaunchingProviders.get(i); 12051 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12052 continue; 12053 } 12054 if (!printed) { 12055 if (needSep) pw.println(); 12056 needSep = true; 12057 pw.println(" Launching content providers:"); 12058 printed = true; 12059 printedAnything = true; 12060 } 12061 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12062 pw.println(r); 12063 } 12064 } 12065 12066 if (mGrantedUriPermissions.size() > 0) { 12067 boolean printed = false; 12068 int dumpUid = -2; 12069 if (dumpPackage != null) { 12070 try { 12071 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12072 } catch (NameNotFoundException e) { 12073 dumpUid = -1; 12074 } 12075 } 12076 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12077 int uid = mGrantedUriPermissions.keyAt(i); 12078 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12079 continue; 12080 } 12081 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12082 if (!printed) { 12083 if (needSep) pw.println(); 12084 needSep = true; 12085 pw.println(" Granted Uri Permissions:"); 12086 printed = true; 12087 printedAnything = true; 12088 } 12089 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12090 for (UriPermission perm : perms.values()) { 12091 pw.print(" "); pw.println(perm); 12092 if (dumpAll) { 12093 perm.dump(pw, " "); 12094 } 12095 } 12096 } 12097 } 12098 12099 if (!printedAnything) { 12100 pw.println(" (nothing)"); 12101 } 12102 } 12103 12104 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12105 int opti, boolean dumpAll, String dumpPackage) { 12106 boolean printed = false; 12107 12108 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12109 12110 if (mIntentSenderRecords.size() > 0) { 12111 Iterator<WeakReference<PendingIntentRecord>> it 12112 = mIntentSenderRecords.values().iterator(); 12113 while (it.hasNext()) { 12114 WeakReference<PendingIntentRecord> ref = it.next(); 12115 PendingIntentRecord rec = ref != null ? ref.get(): null; 12116 if (dumpPackage != null && (rec == null 12117 || !dumpPackage.equals(rec.key.packageName))) { 12118 continue; 12119 } 12120 printed = true; 12121 if (rec != null) { 12122 pw.print(" * "); pw.println(rec); 12123 if (dumpAll) { 12124 rec.dump(pw, " "); 12125 } 12126 } else { 12127 pw.print(" * "); pw.println(ref); 12128 } 12129 } 12130 } 12131 12132 if (!printed) { 12133 pw.println(" (nothing)"); 12134 } 12135 } 12136 12137 private static final int dumpProcessList(PrintWriter pw, 12138 ActivityManagerService service, List list, 12139 String prefix, String normalLabel, String persistentLabel, 12140 String dumpPackage) { 12141 int numPers = 0; 12142 final int N = list.size()-1; 12143 for (int i=N; i>=0; i--) { 12144 ProcessRecord r = (ProcessRecord)list.get(i); 12145 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12146 continue; 12147 } 12148 pw.println(String.format("%s%s #%2d: %s", 12149 prefix, (r.persistent ? persistentLabel : normalLabel), 12150 i, r.toString())); 12151 if (r.persistent) { 12152 numPers++; 12153 } 12154 } 12155 return numPers; 12156 } 12157 12158 private static final boolean dumpProcessOomList(PrintWriter pw, 12159 ActivityManagerService service, List<ProcessRecord> origList, 12160 String prefix, String normalLabel, String persistentLabel, 12161 boolean inclDetails, String dumpPackage) { 12162 12163 ArrayList<Pair<ProcessRecord, Integer>> list 12164 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12165 for (int i=0; i<origList.size(); i++) { 12166 ProcessRecord r = origList.get(i); 12167 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12168 continue; 12169 } 12170 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12171 } 12172 12173 if (list.size() <= 0) { 12174 return false; 12175 } 12176 12177 Comparator<Pair<ProcessRecord, Integer>> comparator 12178 = new Comparator<Pair<ProcessRecord, Integer>>() { 12179 @Override 12180 public int compare(Pair<ProcessRecord, Integer> object1, 12181 Pair<ProcessRecord, Integer> object2) { 12182 if (object1.first.setAdj != object2.first.setAdj) { 12183 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12184 } 12185 if (object1.second.intValue() != object2.second.intValue()) { 12186 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12187 } 12188 return 0; 12189 } 12190 }; 12191 12192 Collections.sort(list, comparator); 12193 12194 final long curRealtime = SystemClock.elapsedRealtime(); 12195 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12196 final long curUptime = SystemClock.uptimeMillis(); 12197 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12198 12199 for (int i=list.size()-1; i>=0; i--) { 12200 ProcessRecord r = list.get(i).first; 12201 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12202 char schedGroup; 12203 switch (r.setSchedGroup) { 12204 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12205 schedGroup = 'B'; 12206 break; 12207 case Process.THREAD_GROUP_DEFAULT: 12208 schedGroup = 'F'; 12209 break; 12210 default: 12211 schedGroup = '?'; 12212 break; 12213 } 12214 char foreground; 12215 if (r.foregroundActivities) { 12216 foreground = 'A'; 12217 } else if (r.foregroundServices) { 12218 foreground = 'S'; 12219 } else { 12220 foreground = ' '; 12221 } 12222 String procState = ProcessList.makeProcStateString(r.curProcState); 12223 pw.print(prefix); 12224 pw.print(r.persistent ? persistentLabel : normalLabel); 12225 pw.print(" #"); 12226 int num = (origList.size()-1)-list.get(i).second; 12227 if (num < 10) pw.print(' '); 12228 pw.print(num); 12229 pw.print(": "); 12230 pw.print(oomAdj); 12231 pw.print(' '); 12232 pw.print(schedGroup); 12233 pw.print('/'); 12234 pw.print(foreground); 12235 pw.print('/'); 12236 pw.print(procState); 12237 pw.print(" trm:"); 12238 if (r.trimMemoryLevel < 10) pw.print(' '); 12239 pw.print(r.trimMemoryLevel); 12240 pw.print(' '); 12241 pw.print(r.toShortString()); 12242 pw.print(" ("); 12243 pw.print(r.adjType); 12244 pw.println(')'); 12245 if (r.adjSource != null || r.adjTarget != null) { 12246 pw.print(prefix); 12247 pw.print(" "); 12248 if (r.adjTarget instanceof ComponentName) { 12249 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12250 } else if (r.adjTarget != null) { 12251 pw.print(r.adjTarget.toString()); 12252 } else { 12253 pw.print("{null}"); 12254 } 12255 pw.print("<="); 12256 if (r.adjSource instanceof ProcessRecord) { 12257 pw.print("Proc{"); 12258 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12259 pw.println("}"); 12260 } else if (r.adjSource != null) { 12261 pw.println(r.adjSource.toString()); 12262 } else { 12263 pw.println("{null}"); 12264 } 12265 } 12266 if (inclDetails) { 12267 pw.print(prefix); 12268 pw.print(" "); 12269 pw.print("oom: max="); pw.print(r.maxAdj); 12270 pw.print(" curRaw="); pw.print(r.curRawAdj); 12271 pw.print(" setRaw="); pw.print(r.setRawAdj); 12272 pw.print(" cur="); pw.print(r.curAdj); 12273 pw.print(" set="); pw.println(r.setAdj); 12274 pw.print(prefix); 12275 pw.print(" "); 12276 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12277 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12278 pw.print(" lastPss="); pw.print(r.lastPss); 12279 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12280 pw.print(prefix); 12281 pw.print(" "); 12282 pw.print("keeping="); pw.print(r.keeping); 12283 pw.print(" cached="); pw.print(r.cached); 12284 pw.print(" empty="); pw.print(r.empty); 12285 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12286 12287 if (!r.keeping) { 12288 if (r.lastWakeTime != 0) { 12289 long wtime; 12290 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12291 synchronized (stats) { 12292 wtime = stats.getProcessWakeTime(r.info.uid, 12293 r.pid, curRealtime); 12294 } 12295 long timeUsed = wtime - r.lastWakeTime; 12296 pw.print(prefix); 12297 pw.print(" "); 12298 pw.print("keep awake over "); 12299 TimeUtils.formatDuration(realtimeSince, pw); 12300 pw.print(" used "); 12301 TimeUtils.formatDuration(timeUsed, pw); 12302 pw.print(" ("); 12303 pw.print((timeUsed*100)/realtimeSince); 12304 pw.println("%)"); 12305 } 12306 if (r.lastCpuTime != 0) { 12307 long timeUsed = r.curCpuTime - r.lastCpuTime; 12308 pw.print(prefix); 12309 pw.print(" "); 12310 pw.print("run cpu over "); 12311 TimeUtils.formatDuration(uptimeSince, pw); 12312 pw.print(" used "); 12313 TimeUtils.formatDuration(timeUsed, pw); 12314 pw.print(" ("); 12315 pw.print((timeUsed*100)/uptimeSince); 12316 pw.println("%)"); 12317 } 12318 } 12319 } 12320 } 12321 return true; 12322 } 12323 12324 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12325 ArrayList<ProcessRecord> procs; 12326 synchronized (this) { 12327 if (args != null && args.length > start 12328 && args[start].charAt(0) != '-') { 12329 procs = new ArrayList<ProcessRecord>(); 12330 int pid = -1; 12331 try { 12332 pid = Integer.parseInt(args[start]); 12333 } catch (NumberFormatException e) { 12334 } 12335 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12336 ProcessRecord proc = mLruProcesses.get(i); 12337 if (proc.pid == pid) { 12338 procs.add(proc); 12339 } else if (proc.processName.equals(args[start])) { 12340 procs.add(proc); 12341 } 12342 } 12343 if (procs.size() <= 0) { 12344 return null; 12345 } 12346 } else { 12347 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12348 } 12349 } 12350 return procs; 12351 } 12352 12353 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12354 PrintWriter pw, String[] args) { 12355 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12356 if (procs == null) { 12357 pw.println("No process found for: " + args[0]); 12358 return; 12359 } 12360 12361 long uptime = SystemClock.uptimeMillis(); 12362 long realtime = SystemClock.elapsedRealtime(); 12363 pw.println("Applications Graphics Acceleration Info:"); 12364 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12365 12366 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12367 ProcessRecord r = procs.get(i); 12368 if (r.thread != null) { 12369 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12370 pw.flush(); 12371 try { 12372 TransferPipe tp = new TransferPipe(); 12373 try { 12374 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12375 tp.go(fd); 12376 } finally { 12377 tp.kill(); 12378 } 12379 } catch (IOException e) { 12380 pw.println("Failure while dumping the app: " + r); 12381 pw.flush(); 12382 } catch (RemoteException e) { 12383 pw.println("Got a RemoteException while dumping the app " + r); 12384 pw.flush(); 12385 } 12386 } 12387 } 12388 } 12389 12390 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12391 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12392 if (procs == null) { 12393 pw.println("No process found for: " + args[0]); 12394 return; 12395 } 12396 12397 pw.println("Applications Database Info:"); 12398 12399 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12400 ProcessRecord r = procs.get(i); 12401 if (r.thread != null) { 12402 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12403 pw.flush(); 12404 try { 12405 TransferPipe tp = new TransferPipe(); 12406 try { 12407 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12408 tp.go(fd); 12409 } finally { 12410 tp.kill(); 12411 } 12412 } catch (IOException e) { 12413 pw.println("Failure while dumping the app: " + r); 12414 pw.flush(); 12415 } catch (RemoteException e) { 12416 pw.println("Got a RemoteException while dumping the app " + r); 12417 pw.flush(); 12418 } 12419 } 12420 } 12421 } 12422 12423 final static class MemItem { 12424 final boolean isProc; 12425 final String label; 12426 final String shortLabel; 12427 final long pss; 12428 final int id; 12429 final boolean hasActivities; 12430 ArrayList<MemItem> subitems; 12431 12432 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12433 boolean _hasActivities) { 12434 isProc = true; 12435 label = _label; 12436 shortLabel = _shortLabel; 12437 pss = _pss; 12438 id = _id; 12439 hasActivities = _hasActivities; 12440 } 12441 12442 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12443 isProc = false; 12444 label = _label; 12445 shortLabel = _shortLabel; 12446 pss = _pss; 12447 id = _id; 12448 hasActivities = false; 12449 } 12450 } 12451 12452 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12453 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12454 if (sort && !isCompact) { 12455 Collections.sort(items, new Comparator<MemItem>() { 12456 @Override 12457 public int compare(MemItem lhs, MemItem rhs) { 12458 if (lhs.pss < rhs.pss) { 12459 return 1; 12460 } else if (lhs.pss > rhs.pss) { 12461 return -1; 12462 } 12463 return 0; 12464 } 12465 }); 12466 } 12467 12468 for (int i=0; i<items.size(); i++) { 12469 MemItem mi = items.get(i); 12470 if (!isCompact) { 12471 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12472 } else if (mi.isProc) { 12473 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12474 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12475 pw.println(mi.hasActivities ? ",a" : ",e"); 12476 } else { 12477 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12478 pw.println(mi.pss); 12479 } 12480 if (mi.subitems != null) { 12481 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12482 true, isCompact); 12483 } 12484 } 12485 } 12486 12487 // These are in KB. 12488 static final long[] DUMP_MEM_BUCKETS = new long[] { 12489 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12490 120*1024, 160*1024, 200*1024, 12491 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12492 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12493 }; 12494 12495 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12496 boolean stackLike) { 12497 int start = label.lastIndexOf('.'); 12498 if (start >= 0) start++; 12499 else start = 0; 12500 int end = label.length(); 12501 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12502 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12503 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12504 out.append(bucket); 12505 out.append(stackLike ? "MB." : "MB "); 12506 out.append(label, start, end); 12507 return; 12508 } 12509 } 12510 out.append(memKB/1024); 12511 out.append(stackLike ? "MB." : "MB "); 12512 out.append(label, start, end); 12513 } 12514 12515 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12516 ProcessList.NATIVE_ADJ, 12517 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12518 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12519 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12520 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12521 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12522 }; 12523 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12524 "Native", 12525 "System", "Persistent", "Foreground", 12526 "Visible", "Perceptible", 12527 "Heavy Weight", "Backup", 12528 "A Services", "Home", 12529 "Previous", "B Services", "Cached" 12530 }; 12531 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12532 "native", 12533 "sys", "pers", "fore", 12534 "vis", "percept", 12535 "heavy", "backup", 12536 "servicea", "home", 12537 "prev", "serviceb", "cached" 12538 }; 12539 12540 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12541 long realtime, boolean isCheckinRequest, boolean isCompact) { 12542 if (isCheckinRequest || isCompact) { 12543 // short checkin version 12544 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12545 } else { 12546 pw.println("Applications Memory Usage (kB):"); 12547 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12548 } 12549 } 12550 12551 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12552 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12553 boolean dumpDetails = false; 12554 boolean dumpFullDetails = false; 12555 boolean dumpDalvik = false; 12556 boolean oomOnly = false; 12557 boolean isCompact = false; 12558 boolean localOnly = false; 12559 12560 int opti = 0; 12561 while (opti < args.length) { 12562 String opt = args[opti]; 12563 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12564 break; 12565 } 12566 opti++; 12567 if ("-a".equals(opt)) { 12568 dumpDetails = true; 12569 dumpFullDetails = true; 12570 dumpDalvik = true; 12571 } else if ("-d".equals(opt)) { 12572 dumpDalvik = true; 12573 } else if ("-c".equals(opt)) { 12574 isCompact = true; 12575 } else if ("--oom".equals(opt)) { 12576 oomOnly = true; 12577 } else if ("--local".equals(opt)) { 12578 localOnly = true; 12579 } else if ("-h".equals(opt)) { 12580 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12581 pw.println(" -a: include all available information for each process."); 12582 pw.println(" -d: include dalvik details when dumping process details."); 12583 pw.println(" -c: dump in a compact machine-parseable representation."); 12584 pw.println(" --oom: only show processes organized by oom adj."); 12585 pw.println(" --local: only collect details locally, don't call process."); 12586 pw.println("If [process] is specified it can be the name or "); 12587 pw.println("pid of a specific process to dump."); 12588 return; 12589 } else { 12590 pw.println("Unknown argument: " + opt + "; use -h for help"); 12591 } 12592 } 12593 12594 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12595 long uptime = SystemClock.uptimeMillis(); 12596 long realtime = SystemClock.elapsedRealtime(); 12597 final long[] tmpLong = new long[1]; 12598 12599 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12600 if (procs == null) { 12601 // No Java processes. Maybe they want to print a native process. 12602 if (args != null && args.length > opti 12603 && args[opti].charAt(0) != '-') { 12604 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12605 = new ArrayList<ProcessCpuTracker.Stats>(); 12606 updateCpuStatsNow(); 12607 int findPid = -1; 12608 try { 12609 findPid = Integer.parseInt(args[opti]); 12610 } catch (NumberFormatException e) { 12611 } 12612 synchronized (mProcessCpuThread) { 12613 final int N = mProcessCpuTracker.countStats(); 12614 for (int i=0; i<N; i++) { 12615 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12616 if (st.pid == findPid || (st.baseName != null 12617 && st.baseName.equals(args[opti]))) { 12618 nativeProcs.add(st); 12619 } 12620 } 12621 } 12622 if (nativeProcs.size() > 0) { 12623 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12624 isCompact); 12625 Debug.MemoryInfo mi = null; 12626 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12627 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12628 final int pid = r.pid; 12629 if (!isCheckinRequest && dumpDetails) { 12630 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12631 } 12632 if (mi == null) { 12633 mi = new Debug.MemoryInfo(); 12634 } 12635 if (dumpDetails || (!brief && !oomOnly)) { 12636 Debug.getMemoryInfo(pid, mi); 12637 } else { 12638 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12639 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12640 } 12641 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12642 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12643 if (isCheckinRequest) { 12644 pw.println(); 12645 } 12646 } 12647 return; 12648 } 12649 } 12650 pw.println("No process found for: " + args[opti]); 12651 return; 12652 } 12653 12654 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12655 dumpDetails = true; 12656 } 12657 12658 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12659 12660 String[] innerArgs = new String[args.length-opti]; 12661 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12662 12663 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12664 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12665 long nativePss=0, dalvikPss=0, otherPss=0; 12666 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12667 12668 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12669 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12670 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12671 12672 long totalPss = 0; 12673 long cachedPss = 0; 12674 12675 Debug.MemoryInfo mi = null; 12676 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12677 final ProcessRecord r = procs.get(i); 12678 final IApplicationThread thread; 12679 final int pid; 12680 final int oomAdj; 12681 final boolean hasActivities; 12682 synchronized (this) { 12683 thread = r.thread; 12684 pid = r.pid; 12685 oomAdj = r.getSetAdjWithServices(); 12686 hasActivities = r.activities.size() > 0; 12687 } 12688 if (thread != null) { 12689 if (!isCheckinRequest && dumpDetails) { 12690 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12691 } 12692 if (mi == null) { 12693 mi = new Debug.MemoryInfo(); 12694 } 12695 if (dumpDetails || (!brief && !oomOnly)) { 12696 Debug.getMemoryInfo(pid, mi); 12697 } else { 12698 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12699 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12700 } 12701 if (dumpDetails) { 12702 if (localOnly) { 12703 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12704 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12705 if (isCheckinRequest) { 12706 pw.println(); 12707 } 12708 } else { 12709 try { 12710 pw.flush(); 12711 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12712 dumpDalvik, innerArgs); 12713 } catch (RemoteException e) { 12714 if (!isCheckinRequest) { 12715 pw.println("Got RemoteException!"); 12716 pw.flush(); 12717 } 12718 } 12719 } 12720 } 12721 12722 final long myTotalPss = mi.getTotalPss(); 12723 final long myTotalUss = mi.getTotalUss(); 12724 12725 synchronized (this) { 12726 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12727 // Record this for posterity if the process has been stable. 12728 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12729 } 12730 } 12731 12732 if (!isCheckinRequest && mi != null) { 12733 totalPss += myTotalPss; 12734 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12735 (hasActivities ? " / activities)" : ")"), 12736 r.processName, myTotalPss, pid, hasActivities); 12737 procMems.add(pssItem); 12738 procMemsMap.put(pid, pssItem); 12739 12740 nativePss += mi.nativePss; 12741 dalvikPss += mi.dalvikPss; 12742 otherPss += mi.otherPss; 12743 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12744 long mem = mi.getOtherPss(j); 12745 miscPss[j] += mem; 12746 otherPss -= mem; 12747 } 12748 12749 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12750 cachedPss += myTotalPss; 12751 } 12752 12753 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12754 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12755 || oomIndex == (oomPss.length-1)) { 12756 oomPss[oomIndex] += myTotalPss; 12757 if (oomProcs[oomIndex] == null) { 12758 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12759 } 12760 oomProcs[oomIndex].add(pssItem); 12761 break; 12762 } 12763 } 12764 } 12765 } 12766 } 12767 12768 long nativeProcTotalPss = 0; 12769 12770 if (!isCheckinRequest && procs.size() > 1) { 12771 // If we are showing aggregations, also look for native processes to 12772 // include so that our aggregations are more accurate. 12773 updateCpuStatsNow(); 12774 synchronized (mProcessCpuThread) { 12775 final int N = mProcessCpuTracker.countStats(); 12776 for (int i=0; i<N; i++) { 12777 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12778 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12779 if (mi == null) { 12780 mi = new Debug.MemoryInfo(); 12781 } 12782 if (!brief && !oomOnly) { 12783 Debug.getMemoryInfo(st.pid, mi); 12784 } else { 12785 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12786 mi.nativePrivateDirty = (int)tmpLong[0]; 12787 } 12788 12789 final long myTotalPss = mi.getTotalPss(); 12790 totalPss += myTotalPss; 12791 nativeProcTotalPss += myTotalPss; 12792 12793 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12794 st.name, myTotalPss, st.pid, false); 12795 procMems.add(pssItem); 12796 12797 nativePss += mi.nativePss; 12798 dalvikPss += mi.dalvikPss; 12799 otherPss += mi.otherPss; 12800 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12801 long mem = mi.getOtherPss(j); 12802 miscPss[j] += mem; 12803 otherPss -= mem; 12804 } 12805 oomPss[0] += myTotalPss; 12806 if (oomProcs[0] == null) { 12807 oomProcs[0] = new ArrayList<MemItem>(); 12808 } 12809 oomProcs[0].add(pssItem); 12810 } 12811 } 12812 } 12813 12814 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12815 12816 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12817 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12818 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12819 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12820 String label = Debug.MemoryInfo.getOtherLabel(j); 12821 catMems.add(new MemItem(label, label, miscPss[j], j)); 12822 } 12823 12824 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12825 for (int j=0; j<oomPss.length; j++) { 12826 if (oomPss[j] != 0) { 12827 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12828 : DUMP_MEM_OOM_LABEL[j]; 12829 MemItem item = new MemItem(label, label, oomPss[j], 12830 DUMP_MEM_OOM_ADJ[j]); 12831 item.subitems = oomProcs[j]; 12832 oomMems.add(item); 12833 } 12834 } 12835 12836 if (!brief && !oomOnly && !isCompact) { 12837 pw.println(); 12838 pw.println("Total PSS by process:"); 12839 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12840 pw.println(); 12841 } 12842 if (!isCompact) { 12843 pw.println("Total PSS by OOM adjustment:"); 12844 } 12845 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12846 if (!brief && !oomOnly) { 12847 PrintWriter out = categoryPw != null ? categoryPw : pw; 12848 if (!isCompact) { 12849 out.println(); 12850 out.println("Total PSS by category:"); 12851 } 12852 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12853 } 12854 if (!isCompact) { 12855 pw.println(); 12856 } 12857 MemInfoReader memInfo = new MemInfoReader(); 12858 memInfo.readMemInfo(); 12859 if (nativeProcTotalPss > 0) { 12860 synchronized (this) { 12861 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12862 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12863 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12864 nativeProcTotalPss); 12865 } 12866 } 12867 if (!brief) { 12868 if (!isCompact) { 12869 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12870 pw.print(" kB (status "); 12871 switch (mLastMemoryLevel) { 12872 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12873 pw.println("normal)"); 12874 break; 12875 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12876 pw.println("moderate)"); 12877 break; 12878 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12879 pw.println("low)"); 12880 break; 12881 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12882 pw.println("critical)"); 12883 break; 12884 default: 12885 pw.print(mLastMemoryLevel); 12886 pw.println(")"); 12887 break; 12888 } 12889 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12890 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12891 pw.print(cachedPss); pw.print(" cached pss + "); 12892 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12893 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12894 } else { 12895 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12896 pw.print(cachedPss + memInfo.getCachedSizeKb() 12897 + memInfo.getFreeSizeKb()); pw.print(","); 12898 pw.println(totalPss - cachedPss); 12899 } 12900 } 12901 if (!isCompact) { 12902 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12903 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12904 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12905 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12906 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12907 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12908 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12909 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12910 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12911 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12912 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12913 } 12914 if (!brief) { 12915 if (memInfo.getZramTotalSizeKb() != 0) { 12916 if (!isCompact) { 12917 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12918 pw.print(" kB physical used for "); 12919 pw.print(memInfo.getSwapTotalSizeKb() 12920 - memInfo.getSwapFreeSizeKb()); 12921 pw.print(" kB in swap ("); 12922 pw.print(memInfo.getSwapTotalSizeKb()); 12923 pw.println(" kB total swap)"); 12924 } else { 12925 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12926 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12927 pw.println(memInfo.getSwapFreeSizeKb()); 12928 } 12929 } 12930 final int[] SINGLE_LONG_FORMAT = new int[] { 12931 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12932 }; 12933 long[] longOut = new long[1]; 12934 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12935 SINGLE_LONG_FORMAT, null, longOut, null); 12936 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12937 longOut[0] = 0; 12938 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12939 SINGLE_LONG_FORMAT, null, longOut, null); 12940 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12941 longOut[0] = 0; 12942 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12943 SINGLE_LONG_FORMAT, null, longOut, null); 12944 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12945 longOut[0] = 0; 12946 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12947 SINGLE_LONG_FORMAT, null, longOut, null); 12948 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12949 if (!isCompact) { 12950 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12951 pw.print(" KSM: "); pw.print(sharing); 12952 pw.print(" kB saved from shared "); 12953 pw.print(shared); pw.println(" kB"); 12954 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12955 pw.print(voltile); pw.println(" kB volatile"); 12956 } 12957 pw.print(" Tuning: "); 12958 pw.print(ActivityManager.staticGetMemoryClass()); 12959 pw.print(" (large "); 12960 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12961 pw.print("), oom "); 12962 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12963 pw.print(" kB"); 12964 pw.print(", restore limit "); 12965 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12966 pw.print(" kB"); 12967 if (ActivityManager.isLowRamDeviceStatic()) { 12968 pw.print(" (low-ram)"); 12969 } 12970 if (ActivityManager.isHighEndGfx()) { 12971 pw.print(" (high-end-gfx)"); 12972 } 12973 pw.println(); 12974 } else { 12975 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12976 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12977 pw.println(voltile); 12978 pw.print("tuning,"); 12979 pw.print(ActivityManager.staticGetMemoryClass()); 12980 pw.print(','); 12981 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12982 pw.print(','); 12983 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12984 if (ActivityManager.isLowRamDeviceStatic()) { 12985 pw.print(",low-ram"); 12986 } 12987 if (ActivityManager.isHighEndGfx()) { 12988 pw.print(",high-end-gfx"); 12989 } 12990 pw.println(); 12991 } 12992 } 12993 } 12994 } 12995 12996 /** 12997 * Searches array of arguments for the specified string 12998 * @param args array of argument strings 12999 * @param value value to search for 13000 * @return true if the value is contained in the array 13001 */ 13002 private static boolean scanArgs(String[] args, String value) { 13003 if (args != null) { 13004 for (String arg : args) { 13005 if (value.equals(arg)) { 13006 return true; 13007 } 13008 } 13009 } 13010 return false; 13011 } 13012 13013 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13014 ContentProviderRecord cpr, boolean always) { 13015 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13016 13017 if (!inLaunching || always) { 13018 synchronized (cpr) { 13019 cpr.launchingApp = null; 13020 cpr.notifyAll(); 13021 } 13022 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13023 String names[] = cpr.info.authority.split(";"); 13024 for (int j = 0; j < names.length; j++) { 13025 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13026 } 13027 } 13028 13029 for (int i=0; i<cpr.connections.size(); i++) { 13030 ContentProviderConnection conn = cpr.connections.get(i); 13031 if (conn.waiting) { 13032 // If this connection is waiting for the provider, then we don't 13033 // need to mess with its process unless we are always removing 13034 // or for some reason the provider is not currently launching. 13035 if (inLaunching && !always) { 13036 continue; 13037 } 13038 } 13039 ProcessRecord capp = conn.client; 13040 conn.dead = true; 13041 if (conn.stableCount > 0) { 13042 if (!capp.persistent && capp.thread != null 13043 && capp.pid != 0 13044 && capp.pid != MY_PID) { 13045 killUnneededProcessLocked(capp, "depends on provider " 13046 + cpr.name.flattenToShortString() 13047 + " in dying proc " + (proc != null ? proc.processName : "??")); 13048 } 13049 } else if (capp.thread != null && conn.provider.provider != null) { 13050 try { 13051 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13052 } catch (RemoteException e) { 13053 } 13054 // In the protocol here, we don't expect the client to correctly 13055 // clean up this connection, we'll just remove it. 13056 cpr.connections.remove(i); 13057 conn.client.conProviders.remove(conn); 13058 } 13059 } 13060 13061 if (inLaunching && always) { 13062 mLaunchingProviders.remove(cpr); 13063 } 13064 return inLaunching; 13065 } 13066 13067 /** 13068 * Main code for cleaning up a process when it has gone away. This is 13069 * called both as a result of the process dying, or directly when stopping 13070 * a process when running in single process mode. 13071 */ 13072 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13073 boolean restarting, boolean allowRestart, int index) { 13074 if (index >= 0) { 13075 removeLruProcessLocked(app); 13076 ProcessList.remove(app.pid); 13077 } 13078 13079 mProcessesToGc.remove(app); 13080 mPendingPssProcesses.remove(app); 13081 13082 // Dismiss any open dialogs. 13083 if (app.crashDialog != null && !app.forceCrashReport) { 13084 app.crashDialog.dismiss(); 13085 app.crashDialog = null; 13086 } 13087 if (app.anrDialog != null) { 13088 app.anrDialog.dismiss(); 13089 app.anrDialog = null; 13090 } 13091 if (app.waitDialog != null) { 13092 app.waitDialog.dismiss(); 13093 app.waitDialog = null; 13094 } 13095 13096 app.crashing = false; 13097 app.notResponding = false; 13098 13099 app.resetPackageList(mProcessStats); 13100 app.unlinkDeathRecipient(); 13101 app.makeInactive(mProcessStats); 13102 app.waitingToKill = null; 13103 app.forcingToForeground = null; 13104 updateProcessForegroundLocked(app, false, false); 13105 app.foregroundActivities = false; 13106 app.hasShownUi = false; 13107 app.treatLikeActivity = false; 13108 app.hasAboveClient = false; 13109 app.hasClientActivities = false; 13110 13111 mServices.killServicesLocked(app, allowRestart); 13112 13113 boolean restart = false; 13114 13115 // Remove published content providers. 13116 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13117 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13118 final boolean always = app.bad || !allowRestart; 13119 if (removeDyingProviderLocked(app, cpr, always) || always) { 13120 // We left the provider in the launching list, need to 13121 // restart it. 13122 restart = true; 13123 } 13124 13125 cpr.provider = null; 13126 cpr.proc = null; 13127 } 13128 app.pubProviders.clear(); 13129 13130 // Take care of any launching providers waiting for this process. 13131 if (checkAppInLaunchingProvidersLocked(app, false)) { 13132 restart = true; 13133 } 13134 13135 // Unregister from connected content providers. 13136 if (!app.conProviders.isEmpty()) { 13137 for (int i=0; i<app.conProviders.size(); i++) { 13138 ContentProviderConnection conn = app.conProviders.get(i); 13139 conn.provider.connections.remove(conn); 13140 } 13141 app.conProviders.clear(); 13142 } 13143 13144 // At this point there may be remaining entries in mLaunchingProviders 13145 // where we were the only one waiting, so they are no longer of use. 13146 // Look for these and clean up if found. 13147 // XXX Commented out for now. Trying to figure out a way to reproduce 13148 // the actual situation to identify what is actually going on. 13149 if (false) { 13150 for (int i=0; i<mLaunchingProviders.size(); i++) { 13151 ContentProviderRecord cpr = (ContentProviderRecord) 13152 mLaunchingProviders.get(i); 13153 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13154 synchronized (cpr) { 13155 cpr.launchingApp = null; 13156 cpr.notifyAll(); 13157 } 13158 } 13159 } 13160 } 13161 13162 skipCurrentReceiverLocked(app); 13163 13164 // Unregister any receivers. 13165 for (int i=app.receivers.size()-1; i>=0; i--) { 13166 removeReceiverLocked(app.receivers.valueAt(i)); 13167 } 13168 app.receivers.clear(); 13169 13170 // If the app is undergoing backup, tell the backup manager about it 13171 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13172 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13173 + mBackupTarget.appInfo + " died during backup"); 13174 try { 13175 IBackupManager bm = IBackupManager.Stub.asInterface( 13176 ServiceManager.getService(Context.BACKUP_SERVICE)); 13177 bm.agentDisconnected(app.info.packageName); 13178 } catch (RemoteException e) { 13179 // can't happen; backup manager is local 13180 } 13181 } 13182 13183 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13184 ProcessChangeItem item = mPendingProcessChanges.get(i); 13185 if (item.pid == app.pid) { 13186 mPendingProcessChanges.remove(i); 13187 mAvailProcessChanges.add(item); 13188 } 13189 } 13190 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13191 13192 // If the caller is restarting this app, then leave it in its 13193 // current lists and let the caller take care of it. 13194 if (restarting) { 13195 return; 13196 } 13197 13198 if (!app.persistent || app.isolated) { 13199 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13200 "Removing non-persistent process during cleanup: " + app); 13201 mProcessNames.remove(app.processName, app.uid); 13202 mIsolatedProcesses.remove(app.uid); 13203 if (mHeavyWeightProcess == app) { 13204 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13205 mHeavyWeightProcess.userId, 0)); 13206 mHeavyWeightProcess = null; 13207 } 13208 } else if (!app.removed) { 13209 // This app is persistent, so we need to keep its record around. 13210 // If it is not already on the pending app list, add it there 13211 // and start a new process for it. 13212 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13213 mPersistentStartingProcesses.add(app); 13214 restart = true; 13215 } 13216 } 13217 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13218 "Clean-up removing on hold: " + app); 13219 mProcessesOnHold.remove(app); 13220 13221 if (app == mHomeProcess) { 13222 mHomeProcess = null; 13223 } 13224 if (app == mPreviousProcess) { 13225 mPreviousProcess = null; 13226 } 13227 13228 if (restart && !app.isolated) { 13229 // We have components that still need to be running in the 13230 // process, so re-launch it. 13231 mProcessNames.put(app.processName, app.uid, app); 13232 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13233 } else if (app.pid > 0 && app.pid != MY_PID) { 13234 // Goodbye! 13235 boolean removed; 13236 synchronized (mPidsSelfLocked) { 13237 mPidsSelfLocked.remove(app.pid); 13238 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13239 } 13240 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13241 app.processName, app.info.uid); 13242 if (app.isolated) { 13243 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13244 } 13245 app.setPid(0); 13246 } 13247 } 13248 13249 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13250 // Look through the content providers we are waiting to have launched, 13251 // and if any run in this process then either schedule a restart of 13252 // the process or kill the client waiting for it if this process has 13253 // gone bad. 13254 int NL = mLaunchingProviders.size(); 13255 boolean restart = false; 13256 for (int i=0; i<NL; i++) { 13257 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13258 if (cpr.launchingApp == app) { 13259 if (!alwaysBad && !app.bad) { 13260 restart = true; 13261 } else { 13262 removeDyingProviderLocked(app, cpr, true); 13263 // cpr should have been removed from mLaunchingProviders 13264 NL = mLaunchingProviders.size(); 13265 i--; 13266 } 13267 } 13268 } 13269 return restart; 13270 } 13271 13272 // ========================================================= 13273 // SERVICES 13274 // ========================================================= 13275 13276 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13277 int flags) { 13278 enforceNotIsolatedCaller("getServices"); 13279 synchronized (this) { 13280 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13281 } 13282 } 13283 13284 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13285 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13286 synchronized (this) { 13287 return mServices.getRunningServiceControlPanelLocked(name); 13288 } 13289 } 13290 13291 public ComponentName startService(IApplicationThread caller, Intent service, 13292 String resolvedType, int userId) { 13293 enforceNotIsolatedCaller("startService"); 13294 // Refuse possible leaked file descriptors 13295 if (service != null && service.hasFileDescriptors() == true) { 13296 throw new IllegalArgumentException("File descriptors passed in Intent"); 13297 } 13298 13299 if (DEBUG_SERVICE) 13300 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13301 synchronized(this) { 13302 final int callingPid = Binder.getCallingPid(); 13303 final int callingUid = Binder.getCallingUid(); 13304 final long origId = Binder.clearCallingIdentity(); 13305 ComponentName res = mServices.startServiceLocked(caller, service, 13306 resolvedType, callingPid, callingUid, userId); 13307 Binder.restoreCallingIdentity(origId); 13308 return res; 13309 } 13310 } 13311 13312 ComponentName startServiceInPackage(int uid, 13313 Intent service, String resolvedType, int userId) { 13314 synchronized(this) { 13315 if (DEBUG_SERVICE) 13316 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13317 final long origId = Binder.clearCallingIdentity(); 13318 ComponentName res = mServices.startServiceLocked(null, service, 13319 resolvedType, -1, uid, userId); 13320 Binder.restoreCallingIdentity(origId); 13321 return res; 13322 } 13323 } 13324 13325 public int stopService(IApplicationThread caller, Intent service, 13326 String resolvedType, int userId) { 13327 enforceNotIsolatedCaller("stopService"); 13328 // Refuse possible leaked file descriptors 13329 if (service != null && service.hasFileDescriptors() == true) { 13330 throw new IllegalArgumentException("File descriptors passed in Intent"); 13331 } 13332 13333 synchronized(this) { 13334 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13335 } 13336 } 13337 13338 public IBinder peekService(Intent service, String resolvedType) { 13339 enforceNotIsolatedCaller("peekService"); 13340 // Refuse possible leaked file descriptors 13341 if (service != null && service.hasFileDescriptors() == true) { 13342 throw new IllegalArgumentException("File descriptors passed in Intent"); 13343 } 13344 synchronized(this) { 13345 return mServices.peekServiceLocked(service, resolvedType); 13346 } 13347 } 13348 13349 public boolean stopServiceToken(ComponentName className, IBinder token, 13350 int startId) { 13351 synchronized(this) { 13352 return mServices.stopServiceTokenLocked(className, token, startId); 13353 } 13354 } 13355 13356 public void setServiceForeground(ComponentName className, IBinder token, 13357 int id, Notification notification, boolean removeNotification) { 13358 synchronized(this) { 13359 mServices.setServiceForegroundLocked(className, token, id, notification, 13360 removeNotification); 13361 } 13362 } 13363 13364 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13365 boolean requireFull, String name, String callerPackage) { 13366 final int callingUserId = UserHandle.getUserId(callingUid); 13367 if (callingUserId != userId) { 13368 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13369 if ((requireFull || checkComponentPermission( 13370 android.Manifest.permission.INTERACT_ACROSS_USERS, 13371 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13372 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13373 callingPid, callingUid, -1, true) 13374 != PackageManager.PERMISSION_GRANTED) { 13375 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13376 // In this case, they would like to just execute as their 13377 // owner user instead of failing. 13378 userId = callingUserId; 13379 } else { 13380 StringBuilder builder = new StringBuilder(128); 13381 builder.append("Permission Denial: "); 13382 builder.append(name); 13383 if (callerPackage != null) { 13384 builder.append(" from "); 13385 builder.append(callerPackage); 13386 } 13387 builder.append(" asks to run as user "); 13388 builder.append(userId); 13389 builder.append(" but is calling from user "); 13390 builder.append(UserHandle.getUserId(callingUid)); 13391 builder.append("; this requires "); 13392 builder.append(INTERACT_ACROSS_USERS_FULL); 13393 if (!requireFull) { 13394 builder.append(" or "); 13395 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13396 } 13397 String msg = builder.toString(); 13398 Slog.w(TAG, msg); 13399 throw new SecurityException(msg); 13400 } 13401 } 13402 } 13403 if (userId == UserHandle.USER_CURRENT 13404 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13405 // Note that we may be accessing this outside of a lock... 13406 // shouldn't be a big deal, if this is being called outside 13407 // of a locked context there is intrinsically a race with 13408 // the value the caller will receive and someone else changing it. 13409 userId = mCurrentUserId; 13410 } 13411 if (!allowAll && userId < 0) { 13412 throw new IllegalArgumentException( 13413 "Call does not support special user #" + userId); 13414 } 13415 } 13416 return userId; 13417 } 13418 13419 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13420 String className, int flags) { 13421 boolean result = false; 13422 // For apps that don't have pre-defined UIDs, check for permission 13423 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13424 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13425 if (ActivityManager.checkUidPermission( 13426 android.Manifest.permission.INTERACT_ACROSS_USERS, 13427 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13428 ComponentName comp = new ComponentName(aInfo.packageName, className); 13429 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13430 + " requests FLAG_SINGLE_USER, but app does not hold " 13431 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13432 Slog.w(TAG, msg); 13433 throw new SecurityException(msg); 13434 } 13435 // Permission passed 13436 result = true; 13437 } 13438 } else if ("system".equals(componentProcessName)) { 13439 result = true; 13440 } else { 13441 // App with pre-defined UID, check if it's a persistent app 13442 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13443 } 13444 if (DEBUG_MU) { 13445 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13446 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13447 } 13448 return result; 13449 } 13450 13451 /** 13452 * Checks to see if the caller is in the same app as the singleton 13453 * component, or the component is in a special app. It allows special apps 13454 * to export singleton components but prevents exporting singleton 13455 * components for regular apps. 13456 */ 13457 boolean isValidSingletonCall(int callingUid, int componentUid) { 13458 int componentAppId = UserHandle.getAppId(componentUid); 13459 return UserHandle.isSameApp(callingUid, componentUid) 13460 || componentAppId == Process.SYSTEM_UID 13461 || componentAppId == Process.PHONE_UID 13462 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13463 == PackageManager.PERMISSION_GRANTED; 13464 } 13465 13466 public int bindService(IApplicationThread caller, IBinder token, 13467 Intent service, String resolvedType, 13468 IServiceConnection connection, int flags, int userId) { 13469 enforceNotIsolatedCaller("bindService"); 13470 // Refuse possible leaked file descriptors 13471 if (service != null && service.hasFileDescriptors() == true) { 13472 throw new IllegalArgumentException("File descriptors passed in Intent"); 13473 } 13474 13475 synchronized(this) { 13476 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13477 connection, flags, userId); 13478 } 13479 } 13480 13481 public boolean unbindService(IServiceConnection connection) { 13482 synchronized (this) { 13483 return mServices.unbindServiceLocked(connection); 13484 } 13485 } 13486 13487 public void publishService(IBinder token, Intent intent, IBinder service) { 13488 // Refuse possible leaked file descriptors 13489 if (intent != null && intent.hasFileDescriptors() == true) { 13490 throw new IllegalArgumentException("File descriptors passed in Intent"); 13491 } 13492 13493 synchronized(this) { 13494 if (!(token instanceof ServiceRecord)) { 13495 throw new IllegalArgumentException("Invalid service token"); 13496 } 13497 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13498 } 13499 } 13500 13501 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13502 // Refuse possible leaked file descriptors 13503 if (intent != null && intent.hasFileDescriptors() == true) { 13504 throw new IllegalArgumentException("File descriptors passed in Intent"); 13505 } 13506 13507 synchronized(this) { 13508 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13509 } 13510 } 13511 13512 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13513 synchronized(this) { 13514 if (!(token instanceof ServiceRecord)) { 13515 throw new IllegalArgumentException("Invalid service token"); 13516 } 13517 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13518 } 13519 } 13520 13521 // ========================================================= 13522 // BACKUP AND RESTORE 13523 // ========================================================= 13524 13525 // Cause the target app to be launched if necessary and its backup agent 13526 // instantiated. The backup agent will invoke backupAgentCreated() on the 13527 // activity manager to announce its creation. 13528 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13529 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13530 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13531 13532 synchronized(this) { 13533 // !!! TODO: currently no check here that we're already bound 13534 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13535 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13536 synchronized (stats) { 13537 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13538 } 13539 13540 // Backup agent is now in use, its package can't be stopped. 13541 try { 13542 AppGlobals.getPackageManager().setPackageStoppedState( 13543 app.packageName, false, UserHandle.getUserId(app.uid)); 13544 } catch (RemoteException e) { 13545 } catch (IllegalArgumentException e) { 13546 Slog.w(TAG, "Failed trying to unstop package " 13547 + app.packageName + ": " + e); 13548 } 13549 13550 BackupRecord r = new BackupRecord(ss, app, backupMode); 13551 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13552 ? new ComponentName(app.packageName, app.backupAgentName) 13553 : new ComponentName("android", "FullBackupAgent"); 13554 // startProcessLocked() returns existing proc's record if it's already running 13555 ProcessRecord proc = startProcessLocked(app.processName, app, 13556 false, 0, "backup", hostingName, false, false, false); 13557 if (proc == null) { 13558 Slog.e(TAG, "Unable to start backup agent process " + r); 13559 return false; 13560 } 13561 13562 r.app = proc; 13563 mBackupTarget = r; 13564 mBackupAppName = app.packageName; 13565 13566 // Try not to kill the process during backup 13567 updateOomAdjLocked(proc); 13568 13569 // If the process is already attached, schedule the creation of the backup agent now. 13570 // If it is not yet live, this will be done when it attaches to the framework. 13571 if (proc.thread != null) { 13572 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13573 try { 13574 proc.thread.scheduleCreateBackupAgent(app, 13575 compatibilityInfoForPackageLocked(app), backupMode); 13576 } catch (RemoteException e) { 13577 // Will time out on the backup manager side 13578 } 13579 } else { 13580 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13581 } 13582 // Invariants: at this point, the target app process exists and the application 13583 // is either already running or in the process of coming up. mBackupTarget and 13584 // mBackupAppName describe the app, so that when it binds back to the AM we 13585 // know that it's scheduled for a backup-agent operation. 13586 } 13587 13588 return true; 13589 } 13590 13591 @Override 13592 public void clearPendingBackup() { 13593 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13594 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13595 13596 synchronized (this) { 13597 mBackupTarget = null; 13598 mBackupAppName = null; 13599 } 13600 } 13601 13602 // A backup agent has just come up 13603 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13604 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13605 + " = " + agent); 13606 13607 synchronized(this) { 13608 if (!agentPackageName.equals(mBackupAppName)) { 13609 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13610 return; 13611 } 13612 } 13613 13614 long oldIdent = Binder.clearCallingIdentity(); 13615 try { 13616 IBackupManager bm = IBackupManager.Stub.asInterface( 13617 ServiceManager.getService(Context.BACKUP_SERVICE)); 13618 bm.agentConnected(agentPackageName, agent); 13619 } catch (RemoteException e) { 13620 // can't happen; the backup manager service is local 13621 } catch (Exception e) { 13622 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13623 e.printStackTrace(); 13624 } finally { 13625 Binder.restoreCallingIdentity(oldIdent); 13626 } 13627 } 13628 13629 // done with this agent 13630 public void unbindBackupAgent(ApplicationInfo appInfo) { 13631 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13632 if (appInfo == null) { 13633 Slog.w(TAG, "unbind backup agent for null app"); 13634 return; 13635 } 13636 13637 synchronized(this) { 13638 try { 13639 if (mBackupAppName == null) { 13640 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13641 return; 13642 } 13643 13644 if (!mBackupAppName.equals(appInfo.packageName)) { 13645 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13646 return; 13647 } 13648 13649 // Not backing this app up any more; reset its OOM adjustment 13650 final ProcessRecord proc = mBackupTarget.app; 13651 updateOomAdjLocked(proc); 13652 13653 // If the app crashed during backup, 'thread' will be null here 13654 if (proc.thread != null) { 13655 try { 13656 proc.thread.scheduleDestroyBackupAgent(appInfo, 13657 compatibilityInfoForPackageLocked(appInfo)); 13658 } catch (Exception e) { 13659 Slog.e(TAG, "Exception when unbinding backup agent:"); 13660 e.printStackTrace(); 13661 } 13662 } 13663 } finally { 13664 mBackupTarget = null; 13665 mBackupAppName = null; 13666 } 13667 } 13668 } 13669 // ========================================================= 13670 // BROADCASTS 13671 // ========================================================= 13672 13673 private final List getStickiesLocked(String action, IntentFilter filter, 13674 List cur, int userId) { 13675 final ContentResolver resolver = mContext.getContentResolver(); 13676 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13677 if (stickies == null) { 13678 return cur; 13679 } 13680 final ArrayList<Intent> list = stickies.get(action); 13681 if (list == null) { 13682 return cur; 13683 } 13684 int N = list.size(); 13685 for (int i=0; i<N; i++) { 13686 Intent intent = list.get(i); 13687 if (filter.match(resolver, intent, true, TAG) >= 0) { 13688 if (cur == null) { 13689 cur = new ArrayList<Intent>(); 13690 } 13691 cur.add(intent); 13692 } 13693 } 13694 return cur; 13695 } 13696 13697 boolean isPendingBroadcastProcessLocked(int pid) { 13698 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13699 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13700 } 13701 13702 void skipPendingBroadcastLocked(int pid) { 13703 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13704 for (BroadcastQueue queue : mBroadcastQueues) { 13705 queue.skipPendingBroadcastLocked(pid); 13706 } 13707 } 13708 13709 // The app just attached; send any pending broadcasts that it should receive 13710 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13711 boolean didSomething = false; 13712 for (BroadcastQueue queue : mBroadcastQueues) { 13713 didSomething |= queue.sendPendingBroadcastsLocked(app); 13714 } 13715 return didSomething; 13716 } 13717 13718 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13719 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13720 enforceNotIsolatedCaller("registerReceiver"); 13721 int callingUid; 13722 int callingPid; 13723 synchronized(this) { 13724 ProcessRecord callerApp = null; 13725 if (caller != null) { 13726 callerApp = getRecordForAppLocked(caller); 13727 if (callerApp == null) { 13728 throw new SecurityException( 13729 "Unable to find app for caller " + caller 13730 + " (pid=" + Binder.getCallingPid() 13731 + ") when registering receiver " + receiver); 13732 } 13733 if (callerApp.info.uid != Process.SYSTEM_UID && 13734 !callerApp.pkgList.containsKey(callerPackage) && 13735 !"android".equals(callerPackage)) { 13736 throw new SecurityException("Given caller package " + callerPackage 13737 + " is not running in process " + callerApp); 13738 } 13739 callingUid = callerApp.info.uid; 13740 callingPid = callerApp.pid; 13741 } else { 13742 callerPackage = null; 13743 callingUid = Binder.getCallingUid(); 13744 callingPid = Binder.getCallingPid(); 13745 } 13746 13747 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13748 true, true, "registerReceiver", callerPackage); 13749 13750 List allSticky = null; 13751 13752 // Look for any matching sticky broadcasts... 13753 Iterator actions = filter.actionsIterator(); 13754 if (actions != null) { 13755 while (actions.hasNext()) { 13756 String action = (String)actions.next(); 13757 allSticky = getStickiesLocked(action, filter, allSticky, 13758 UserHandle.USER_ALL); 13759 allSticky = getStickiesLocked(action, filter, allSticky, 13760 UserHandle.getUserId(callingUid)); 13761 } 13762 } else { 13763 allSticky = getStickiesLocked(null, filter, allSticky, 13764 UserHandle.USER_ALL); 13765 allSticky = getStickiesLocked(null, filter, allSticky, 13766 UserHandle.getUserId(callingUid)); 13767 } 13768 13769 // The first sticky in the list is returned directly back to 13770 // the client. 13771 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13772 13773 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13774 + ": " + sticky); 13775 13776 if (receiver == null) { 13777 return sticky; 13778 } 13779 13780 ReceiverList rl 13781 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13782 if (rl == null) { 13783 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13784 userId, receiver); 13785 if (rl.app != null) { 13786 rl.app.receivers.add(rl); 13787 } else { 13788 try { 13789 receiver.asBinder().linkToDeath(rl, 0); 13790 } catch (RemoteException e) { 13791 return sticky; 13792 } 13793 rl.linkedToDeath = true; 13794 } 13795 mRegisteredReceivers.put(receiver.asBinder(), rl); 13796 } else if (rl.uid != callingUid) { 13797 throw new IllegalArgumentException( 13798 "Receiver requested to register for uid " + callingUid 13799 + " was previously registered for uid " + rl.uid); 13800 } else if (rl.pid != callingPid) { 13801 throw new IllegalArgumentException( 13802 "Receiver requested to register for pid " + callingPid 13803 + " was previously registered for pid " + rl.pid); 13804 } else if (rl.userId != userId) { 13805 throw new IllegalArgumentException( 13806 "Receiver requested to register for user " + userId 13807 + " was previously registered for user " + rl.userId); 13808 } 13809 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13810 permission, callingUid, userId); 13811 rl.add(bf); 13812 if (!bf.debugCheck()) { 13813 Slog.w(TAG, "==> For Dynamic broadast"); 13814 } 13815 mReceiverResolver.addFilter(bf); 13816 13817 // Enqueue broadcasts for all existing stickies that match 13818 // this filter. 13819 if (allSticky != null) { 13820 ArrayList receivers = new ArrayList(); 13821 receivers.add(bf); 13822 13823 int N = allSticky.size(); 13824 for (int i=0; i<N; i++) { 13825 Intent intent = (Intent)allSticky.get(i); 13826 BroadcastQueue queue = broadcastQueueForIntent(intent); 13827 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13828 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13829 null, null, false, true, true, -1); 13830 queue.enqueueParallelBroadcastLocked(r); 13831 queue.scheduleBroadcastsLocked(); 13832 } 13833 } 13834 13835 return sticky; 13836 } 13837 } 13838 13839 public void unregisterReceiver(IIntentReceiver receiver) { 13840 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13841 13842 final long origId = Binder.clearCallingIdentity(); 13843 try { 13844 boolean doTrim = false; 13845 13846 synchronized(this) { 13847 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13848 if (rl != null) { 13849 if (rl.curBroadcast != null) { 13850 BroadcastRecord r = rl.curBroadcast; 13851 final boolean doNext = finishReceiverLocked( 13852 receiver.asBinder(), r.resultCode, r.resultData, 13853 r.resultExtras, r.resultAbort); 13854 if (doNext) { 13855 doTrim = true; 13856 r.queue.processNextBroadcast(false); 13857 } 13858 } 13859 13860 if (rl.app != null) { 13861 rl.app.receivers.remove(rl); 13862 } 13863 removeReceiverLocked(rl); 13864 if (rl.linkedToDeath) { 13865 rl.linkedToDeath = false; 13866 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13867 } 13868 } 13869 } 13870 13871 // If we actually concluded any broadcasts, we might now be able 13872 // to trim the recipients' apps from our working set 13873 if (doTrim) { 13874 trimApplications(); 13875 return; 13876 } 13877 13878 } finally { 13879 Binder.restoreCallingIdentity(origId); 13880 } 13881 } 13882 13883 void removeReceiverLocked(ReceiverList rl) { 13884 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13885 int N = rl.size(); 13886 for (int i=0; i<N; i++) { 13887 mReceiverResolver.removeFilter(rl.get(i)); 13888 } 13889 } 13890 13891 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13892 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13893 ProcessRecord r = mLruProcesses.get(i); 13894 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13895 try { 13896 r.thread.dispatchPackageBroadcast(cmd, packages); 13897 } catch (RemoteException ex) { 13898 } 13899 } 13900 } 13901 } 13902 13903 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13904 int[] users) { 13905 List<ResolveInfo> receivers = null; 13906 try { 13907 HashSet<ComponentName> singleUserReceivers = null; 13908 boolean scannedFirstReceivers = false; 13909 for (int user : users) { 13910 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13911 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13912 if (user != 0 && newReceivers != null) { 13913 // If this is not the primary user, we need to check for 13914 // any receivers that should be filtered out. 13915 for (int i=0; i<newReceivers.size(); i++) { 13916 ResolveInfo ri = newReceivers.get(i); 13917 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13918 newReceivers.remove(i); 13919 i--; 13920 } 13921 } 13922 } 13923 if (newReceivers != null && newReceivers.size() == 0) { 13924 newReceivers = null; 13925 } 13926 if (receivers == null) { 13927 receivers = newReceivers; 13928 } else if (newReceivers != null) { 13929 // We need to concatenate the additional receivers 13930 // found with what we have do far. This would be easy, 13931 // but we also need to de-dup any receivers that are 13932 // singleUser. 13933 if (!scannedFirstReceivers) { 13934 // Collect any single user receivers we had already retrieved. 13935 scannedFirstReceivers = true; 13936 for (int i=0; i<receivers.size(); i++) { 13937 ResolveInfo ri = receivers.get(i); 13938 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13939 ComponentName cn = new ComponentName( 13940 ri.activityInfo.packageName, ri.activityInfo.name); 13941 if (singleUserReceivers == null) { 13942 singleUserReceivers = new HashSet<ComponentName>(); 13943 } 13944 singleUserReceivers.add(cn); 13945 } 13946 } 13947 } 13948 // Add the new results to the existing results, tracking 13949 // and de-dupping single user receivers. 13950 for (int i=0; i<newReceivers.size(); i++) { 13951 ResolveInfo ri = newReceivers.get(i); 13952 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13953 ComponentName cn = new ComponentName( 13954 ri.activityInfo.packageName, ri.activityInfo.name); 13955 if (singleUserReceivers == null) { 13956 singleUserReceivers = new HashSet<ComponentName>(); 13957 } 13958 if (!singleUserReceivers.contains(cn)) { 13959 singleUserReceivers.add(cn); 13960 receivers.add(ri); 13961 } 13962 } else { 13963 receivers.add(ri); 13964 } 13965 } 13966 } 13967 } 13968 } catch (RemoteException ex) { 13969 // pm is in same process, this will never happen. 13970 } 13971 return receivers; 13972 } 13973 13974 private final int broadcastIntentLocked(ProcessRecord callerApp, 13975 String callerPackage, Intent intent, String resolvedType, 13976 IIntentReceiver resultTo, int resultCode, String resultData, 13977 Bundle map, String requiredPermission, int appOp, 13978 boolean ordered, boolean sticky, int callingPid, int callingUid, 13979 int userId) { 13980 intent = new Intent(intent); 13981 13982 // By default broadcasts do not go to stopped apps. 13983 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13984 13985 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13986 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13987 + " ordered=" + ordered + " userid=" + userId); 13988 if ((resultTo != null) && !ordered) { 13989 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13990 } 13991 13992 userId = handleIncomingUser(callingPid, callingUid, userId, 13993 true, false, "broadcast", callerPackage); 13994 13995 // Make sure that the user who is receiving this broadcast is started. 13996 // If not, we will just skip it. 13997 13998 13999 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14000 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14001 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14002 Slog.w(TAG, "Skipping broadcast of " + intent 14003 + ": user " + userId + " is stopped"); 14004 return ActivityManager.BROADCAST_SUCCESS; 14005 } 14006 } 14007 14008 /* 14009 * Prevent non-system code (defined here to be non-persistent 14010 * processes) from sending protected broadcasts. 14011 */ 14012 int callingAppId = UserHandle.getAppId(callingUid); 14013 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14014 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14015 || callingAppId == Process.NFC_UID || callingUid == 0) { 14016 // Always okay. 14017 } else if (callerApp == null || !callerApp.persistent) { 14018 try { 14019 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14020 intent.getAction())) { 14021 String msg = "Permission Denial: not allowed to send broadcast " 14022 + intent.getAction() + " from pid=" 14023 + callingPid + ", uid=" + callingUid; 14024 Slog.w(TAG, msg); 14025 throw new SecurityException(msg); 14026 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14027 // Special case for compatibility: we don't want apps to send this, 14028 // but historically it has not been protected and apps may be using it 14029 // to poke their own app widget. So, instead of making it protected, 14030 // just limit it to the caller. 14031 if (callerApp == null) { 14032 String msg = "Permission Denial: not allowed to send broadcast " 14033 + intent.getAction() + " from unknown caller."; 14034 Slog.w(TAG, msg); 14035 throw new SecurityException(msg); 14036 } else if (intent.getComponent() != null) { 14037 // They are good enough to send to an explicit component... verify 14038 // it is being sent to the calling app. 14039 if (!intent.getComponent().getPackageName().equals( 14040 callerApp.info.packageName)) { 14041 String msg = "Permission Denial: not allowed to send broadcast " 14042 + intent.getAction() + " to " 14043 + intent.getComponent().getPackageName() + " from " 14044 + callerApp.info.packageName; 14045 Slog.w(TAG, msg); 14046 throw new SecurityException(msg); 14047 } 14048 } else { 14049 // Limit broadcast to their own package. 14050 intent.setPackage(callerApp.info.packageName); 14051 } 14052 } 14053 } catch (RemoteException e) { 14054 Slog.w(TAG, "Remote exception", e); 14055 return ActivityManager.BROADCAST_SUCCESS; 14056 } 14057 } 14058 14059 // Handle special intents: if this broadcast is from the package 14060 // manager about a package being removed, we need to remove all of 14061 // its activities from the history stack. 14062 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14063 intent.getAction()); 14064 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14065 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14066 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14067 || uidRemoved) { 14068 if (checkComponentPermission( 14069 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14070 callingPid, callingUid, -1, true) 14071 == PackageManager.PERMISSION_GRANTED) { 14072 if (uidRemoved) { 14073 final Bundle intentExtras = intent.getExtras(); 14074 final int uid = intentExtras != null 14075 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14076 if (uid >= 0) { 14077 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14078 synchronized (bs) { 14079 bs.removeUidStatsLocked(uid); 14080 } 14081 mAppOpsService.uidRemoved(uid); 14082 } 14083 } else { 14084 // If resources are unavailable just force stop all 14085 // those packages and flush the attribute cache as well. 14086 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14087 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14088 if (list != null && (list.length > 0)) { 14089 for (String pkg : list) { 14090 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14091 "storage unmount"); 14092 } 14093 sendPackageBroadcastLocked( 14094 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14095 } 14096 } else { 14097 Uri data = intent.getData(); 14098 String ssp; 14099 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14100 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14101 intent.getAction()); 14102 boolean fullUninstall = removed && 14103 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14104 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14105 forceStopPackageLocked(ssp, UserHandle.getAppId( 14106 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14107 false, fullUninstall, userId, 14108 removed ? "pkg removed" : "pkg changed"); 14109 } 14110 if (removed) { 14111 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14112 new String[] {ssp}, userId); 14113 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14114 mAppOpsService.packageRemoved( 14115 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14116 14117 // Remove all permissions granted from/to this package 14118 removeUriPermissionsForPackageLocked(ssp, userId, true); 14119 } 14120 } 14121 } 14122 } 14123 } 14124 } else { 14125 String msg = "Permission Denial: " + intent.getAction() 14126 + " broadcast from " + callerPackage + " (pid=" + callingPid 14127 + ", uid=" + callingUid + ")" 14128 + " requires " 14129 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14130 Slog.w(TAG, msg); 14131 throw new SecurityException(msg); 14132 } 14133 14134 // Special case for adding a package: by default turn on compatibility 14135 // mode. 14136 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14137 Uri data = intent.getData(); 14138 String ssp; 14139 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14140 mCompatModePackages.handlePackageAddedLocked(ssp, 14141 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14142 } 14143 } 14144 14145 /* 14146 * If this is the time zone changed action, queue up a message that will reset the timezone 14147 * of all currently running processes. This message will get queued up before the broadcast 14148 * happens. 14149 */ 14150 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14151 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14152 } 14153 14154 /* 14155 * If the user set the time, let all running processes know. 14156 */ 14157 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14158 final int is24Hour = intent.getBooleanExtra( 14159 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14160 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14161 } 14162 14163 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14164 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14165 } 14166 14167 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14168 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14169 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14170 } 14171 14172 // Add to the sticky list if requested. 14173 if (sticky) { 14174 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14175 callingPid, callingUid) 14176 != PackageManager.PERMISSION_GRANTED) { 14177 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14178 + callingPid + ", uid=" + callingUid 14179 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14180 Slog.w(TAG, msg); 14181 throw new SecurityException(msg); 14182 } 14183 if (requiredPermission != null) { 14184 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14185 + " and enforce permission " + requiredPermission); 14186 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14187 } 14188 if (intent.getComponent() != null) { 14189 throw new SecurityException( 14190 "Sticky broadcasts can't target a specific component"); 14191 } 14192 // We use userId directly here, since the "all" target is maintained 14193 // as a separate set of sticky broadcasts. 14194 if (userId != UserHandle.USER_ALL) { 14195 // But first, if this is not a broadcast to all users, then 14196 // make sure it doesn't conflict with an existing broadcast to 14197 // all users. 14198 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14199 UserHandle.USER_ALL); 14200 if (stickies != null) { 14201 ArrayList<Intent> list = stickies.get(intent.getAction()); 14202 if (list != null) { 14203 int N = list.size(); 14204 int i; 14205 for (i=0; i<N; i++) { 14206 if (intent.filterEquals(list.get(i))) { 14207 throw new IllegalArgumentException( 14208 "Sticky broadcast " + intent + " for user " 14209 + userId + " conflicts with existing global broadcast"); 14210 } 14211 } 14212 } 14213 } 14214 } 14215 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14216 if (stickies == null) { 14217 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14218 mStickyBroadcasts.put(userId, stickies); 14219 } 14220 ArrayList<Intent> list = stickies.get(intent.getAction()); 14221 if (list == null) { 14222 list = new ArrayList<Intent>(); 14223 stickies.put(intent.getAction(), list); 14224 } 14225 int N = list.size(); 14226 int i; 14227 for (i=0; i<N; i++) { 14228 if (intent.filterEquals(list.get(i))) { 14229 // This sticky already exists, replace it. 14230 list.set(i, new Intent(intent)); 14231 break; 14232 } 14233 } 14234 if (i >= N) { 14235 list.add(new Intent(intent)); 14236 } 14237 } 14238 14239 int[] users; 14240 if (userId == UserHandle.USER_ALL) { 14241 // Caller wants broadcast to go to all started users. 14242 users = mStartedUserArray; 14243 } else { 14244 // Caller wants broadcast to go to one specific user. 14245 users = new int[] {userId}; 14246 } 14247 14248 // Figure out who all will receive this broadcast. 14249 List receivers = null; 14250 List<BroadcastFilter> registeredReceivers = null; 14251 // Need to resolve the intent to interested receivers... 14252 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14253 == 0) { 14254 receivers = collectReceiverComponents(intent, resolvedType, users); 14255 } 14256 if (intent.getComponent() == null) { 14257 registeredReceivers = mReceiverResolver.queryIntent(intent, 14258 resolvedType, false, userId); 14259 } 14260 14261 final boolean replacePending = 14262 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14263 14264 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14265 + " replacePending=" + replacePending); 14266 14267 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14268 if (!ordered && NR > 0) { 14269 // If we are not serializing this broadcast, then send the 14270 // registered receivers separately so they don't wait for the 14271 // components to be launched. 14272 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14273 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14274 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14275 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14276 ordered, sticky, false, userId); 14277 if (DEBUG_BROADCAST) Slog.v( 14278 TAG, "Enqueueing parallel broadcast " + r); 14279 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14280 if (!replaced) { 14281 queue.enqueueParallelBroadcastLocked(r); 14282 queue.scheduleBroadcastsLocked(); 14283 } 14284 registeredReceivers = null; 14285 NR = 0; 14286 } 14287 14288 // Merge into one list. 14289 int ir = 0; 14290 if (receivers != null) { 14291 // A special case for PACKAGE_ADDED: do not allow the package 14292 // being added to see this broadcast. This prevents them from 14293 // using this as a back door to get run as soon as they are 14294 // installed. Maybe in the future we want to have a special install 14295 // broadcast or such for apps, but we'd like to deliberately make 14296 // this decision. 14297 String skipPackages[] = null; 14298 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14299 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14300 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14301 Uri data = intent.getData(); 14302 if (data != null) { 14303 String pkgName = data.getSchemeSpecificPart(); 14304 if (pkgName != null) { 14305 skipPackages = new String[] { pkgName }; 14306 } 14307 } 14308 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14309 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14310 } 14311 if (skipPackages != null && (skipPackages.length > 0)) { 14312 for (String skipPackage : skipPackages) { 14313 if (skipPackage != null) { 14314 int NT = receivers.size(); 14315 for (int it=0; it<NT; it++) { 14316 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14317 if (curt.activityInfo.packageName.equals(skipPackage)) { 14318 receivers.remove(it); 14319 it--; 14320 NT--; 14321 } 14322 } 14323 } 14324 } 14325 } 14326 14327 int NT = receivers != null ? receivers.size() : 0; 14328 int it = 0; 14329 ResolveInfo curt = null; 14330 BroadcastFilter curr = null; 14331 while (it < NT && ir < NR) { 14332 if (curt == null) { 14333 curt = (ResolveInfo)receivers.get(it); 14334 } 14335 if (curr == null) { 14336 curr = registeredReceivers.get(ir); 14337 } 14338 if (curr.getPriority() >= curt.priority) { 14339 // Insert this broadcast record into the final list. 14340 receivers.add(it, curr); 14341 ir++; 14342 curr = null; 14343 it++; 14344 NT++; 14345 } else { 14346 // Skip to the next ResolveInfo in the final list. 14347 it++; 14348 curt = null; 14349 } 14350 } 14351 } 14352 while (ir < NR) { 14353 if (receivers == null) { 14354 receivers = new ArrayList(); 14355 } 14356 receivers.add(registeredReceivers.get(ir)); 14357 ir++; 14358 } 14359 14360 if ((receivers != null && receivers.size() > 0) 14361 || resultTo != null) { 14362 BroadcastQueue queue = broadcastQueueForIntent(intent); 14363 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14364 callerPackage, callingPid, callingUid, resolvedType, 14365 requiredPermission, appOp, receivers, resultTo, resultCode, 14366 resultData, map, ordered, sticky, false, userId); 14367 if (DEBUG_BROADCAST) Slog.v( 14368 TAG, "Enqueueing ordered broadcast " + r 14369 + ": prev had " + queue.mOrderedBroadcasts.size()); 14370 if (DEBUG_BROADCAST) { 14371 int seq = r.intent.getIntExtra("seq", -1); 14372 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14373 } 14374 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14375 if (!replaced) { 14376 queue.enqueueOrderedBroadcastLocked(r); 14377 queue.scheduleBroadcastsLocked(); 14378 } 14379 } 14380 14381 return ActivityManager.BROADCAST_SUCCESS; 14382 } 14383 14384 final Intent verifyBroadcastLocked(Intent intent) { 14385 // Refuse possible leaked file descriptors 14386 if (intent != null && intent.hasFileDescriptors() == true) { 14387 throw new IllegalArgumentException("File descriptors passed in Intent"); 14388 } 14389 14390 int flags = intent.getFlags(); 14391 14392 if (!mProcessesReady) { 14393 // if the caller really truly claims to know what they're doing, go 14394 // ahead and allow the broadcast without launching any receivers 14395 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14396 intent = new Intent(intent); 14397 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14398 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14399 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14400 + " before boot completion"); 14401 throw new IllegalStateException("Cannot broadcast before boot completed"); 14402 } 14403 } 14404 14405 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14406 throw new IllegalArgumentException( 14407 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14408 } 14409 14410 return intent; 14411 } 14412 14413 public final int broadcastIntent(IApplicationThread caller, 14414 Intent intent, String resolvedType, IIntentReceiver resultTo, 14415 int resultCode, String resultData, Bundle map, 14416 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14417 enforceNotIsolatedCaller("broadcastIntent"); 14418 synchronized(this) { 14419 intent = verifyBroadcastLocked(intent); 14420 14421 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14422 final int callingPid = Binder.getCallingPid(); 14423 final int callingUid = Binder.getCallingUid(); 14424 final long origId = Binder.clearCallingIdentity(); 14425 int res = broadcastIntentLocked(callerApp, 14426 callerApp != null ? callerApp.info.packageName : null, 14427 intent, resolvedType, resultTo, 14428 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14429 callingPid, callingUid, userId); 14430 Binder.restoreCallingIdentity(origId); 14431 return res; 14432 } 14433 } 14434 14435 int broadcastIntentInPackage(String packageName, int uid, 14436 Intent intent, String resolvedType, IIntentReceiver resultTo, 14437 int resultCode, String resultData, Bundle map, 14438 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14439 synchronized(this) { 14440 intent = verifyBroadcastLocked(intent); 14441 14442 final long origId = Binder.clearCallingIdentity(); 14443 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14444 resultTo, resultCode, resultData, map, requiredPermission, 14445 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14446 Binder.restoreCallingIdentity(origId); 14447 return res; 14448 } 14449 } 14450 14451 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14452 // Refuse possible leaked file descriptors 14453 if (intent != null && intent.hasFileDescriptors() == true) { 14454 throw new IllegalArgumentException("File descriptors passed in Intent"); 14455 } 14456 14457 userId = handleIncomingUser(Binder.getCallingPid(), 14458 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14459 14460 synchronized(this) { 14461 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14462 != PackageManager.PERMISSION_GRANTED) { 14463 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14464 + Binder.getCallingPid() 14465 + ", uid=" + Binder.getCallingUid() 14466 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14467 Slog.w(TAG, msg); 14468 throw new SecurityException(msg); 14469 } 14470 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14471 if (stickies != null) { 14472 ArrayList<Intent> list = stickies.get(intent.getAction()); 14473 if (list != null) { 14474 int N = list.size(); 14475 int i; 14476 for (i=0; i<N; i++) { 14477 if (intent.filterEquals(list.get(i))) { 14478 list.remove(i); 14479 break; 14480 } 14481 } 14482 if (list.size() <= 0) { 14483 stickies.remove(intent.getAction()); 14484 } 14485 } 14486 if (stickies.size() <= 0) { 14487 mStickyBroadcasts.remove(userId); 14488 } 14489 } 14490 } 14491 } 14492 14493 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14494 String resultData, Bundle resultExtras, boolean resultAbort) { 14495 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14496 if (r == null) { 14497 Slog.w(TAG, "finishReceiver called but not found on queue"); 14498 return false; 14499 } 14500 14501 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14502 } 14503 14504 void backgroundServicesFinishedLocked(int userId) { 14505 for (BroadcastQueue queue : mBroadcastQueues) { 14506 queue.backgroundServicesFinishedLocked(userId); 14507 } 14508 } 14509 14510 public void finishReceiver(IBinder who, int resultCode, String resultData, 14511 Bundle resultExtras, boolean resultAbort) { 14512 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14513 14514 // Refuse possible leaked file descriptors 14515 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14516 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14517 } 14518 14519 final long origId = Binder.clearCallingIdentity(); 14520 try { 14521 boolean doNext = false; 14522 BroadcastRecord r; 14523 14524 synchronized(this) { 14525 r = broadcastRecordForReceiverLocked(who); 14526 if (r != null) { 14527 doNext = r.queue.finishReceiverLocked(r, resultCode, 14528 resultData, resultExtras, resultAbort, true); 14529 } 14530 } 14531 14532 if (doNext) { 14533 r.queue.processNextBroadcast(false); 14534 } 14535 trimApplications(); 14536 } finally { 14537 Binder.restoreCallingIdentity(origId); 14538 } 14539 } 14540 14541 // ========================================================= 14542 // INSTRUMENTATION 14543 // ========================================================= 14544 14545 public boolean startInstrumentation(ComponentName className, 14546 String profileFile, int flags, Bundle arguments, 14547 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14548 int userId, String abiOverride) { 14549 enforceNotIsolatedCaller("startInstrumentation"); 14550 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14551 userId, false, true, "startInstrumentation", null); 14552 // Refuse possible leaked file descriptors 14553 if (arguments != null && arguments.hasFileDescriptors()) { 14554 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14555 } 14556 14557 synchronized(this) { 14558 InstrumentationInfo ii = null; 14559 ApplicationInfo ai = null; 14560 try { 14561 ii = mContext.getPackageManager().getInstrumentationInfo( 14562 className, STOCK_PM_FLAGS); 14563 ai = AppGlobals.getPackageManager().getApplicationInfo( 14564 ii.targetPackage, STOCK_PM_FLAGS, userId); 14565 } catch (PackageManager.NameNotFoundException e) { 14566 } catch (RemoteException e) { 14567 } 14568 if (ii == null) { 14569 reportStartInstrumentationFailure(watcher, className, 14570 "Unable to find instrumentation info for: " + className); 14571 return false; 14572 } 14573 if (ai == null) { 14574 reportStartInstrumentationFailure(watcher, className, 14575 "Unable to find instrumentation target package: " + ii.targetPackage); 14576 return false; 14577 } 14578 14579 int match = mContext.getPackageManager().checkSignatures( 14580 ii.targetPackage, ii.packageName); 14581 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14582 String msg = "Permission Denial: starting instrumentation " 14583 + className + " from pid=" 14584 + Binder.getCallingPid() 14585 + ", uid=" + Binder.getCallingPid() 14586 + " not allowed because package " + ii.packageName 14587 + " does not have a signature matching the target " 14588 + ii.targetPackage; 14589 reportStartInstrumentationFailure(watcher, className, msg); 14590 throw new SecurityException(msg); 14591 } 14592 14593 final long origId = Binder.clearCallingIdentity(); 14594 // Instrumentation can kill and relaunch even persistent processes 14595 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14596 "start instr"); 14597 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14598 app.instrumentationClass = className; 14599 app.instrumentationInfo = ai; 14600 app.instrumentationProfileFile = profileFile; 14601 app.instrumentationArguments = arguments; 14602 app.instrumentationWatcher = watcher; 14603 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14604 app.instrumentationResultClass = className; 14605 Binder.restoreCallingIdentity(origId); 14606 } 14607 14608 return true; 14609 } 14610 14611 /** 14612 * Report errors that occur while attempting to start Instrumentation. Always writes the 14613 * error to the logs, but if somebody is watching, send the report there too. This enables 14614 * the "am" command to report errors with more information. 14615 * 14616 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14617 * @param cn The component name of the instrumentation. 14618 * @param report The error report. 14619 */ 14620 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14621 ComponentName cn, String report) { 14622 Slog.w(TAG, report); 14623 try { 14624 if (watcher != null) { 14625 Bundle results = new Bundle(); 14626 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14627 results.putString("Error", report); 14628 watcher.instrumentationStatus(cn, -1, results); 14629 } 14630 } catch (RemoteException e) { 14631 Slog.w(TAG, e); 14632 } 14633 } 14634 14635 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14636 if (app.instrumentationWatcher != null) { 14637 try { 14638 // NOTE: IInstrumentationWatcher *must* be oneway here 14639 app.instrumentationWatcher.instrumentationFinished( 14640 app.instrumentationClass, 14641 resultCode, 14642 results); 14643 } catch (RemoteException e) { 14644 } 14645 } 14646 if (app.instrumentationUiAutomationConnection != null) { 14647 try { 14648 app.instrumentationUiAutomationConnection.shutdown(); 14649 } catch (RemoteException re) { 14650 /* ignore */ 14651 } 14652 // Only a UiAutomation can set this flag and now that 14653 // it is finished we make sure it is reset to its default. 14654 mUserIsMonkey = false; 14655 } 14656 app.instrumentationWatcher = null; 14657 app.instrumentationUiAutomationConnection = null; 14658 app.instrumentationClass = null; 14659 app.instrumentationInfo = null; 14660 app.instrumentationProfileFile = null; 14661 app.instrumentationArguments = null; 14662 14663 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14664 "finished inst"); 14665 } 14666 14667 public void finishInstrumentation(IApplicationThread target, 14668 int resultCode, Bundle results) { 14669 int userId = UserHandle.getCallingUserId(); 14670 // Refuse possible leaked file descriptors 14671 if (results != null && results.hasFileDescriptors()) { 14672 throw new IllegalArgumentException("File descriptors passed in Intent"); 14673 } 14674 14675 synchronized(this) { 14676 ProcessRecord app = getRecordForAppLocked(target); 14677 if (app == null) { 14678 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14679 return; 14680 } 14681 final long origId = Binder.clearCallingIdentity(); 14682 finishInstrumentationLocked(app, resultCode, results); 14683 Binder.restoreCallingIdentity(origId); 14684 } 14685 } 14686 14687 // ========================================================= 14688 // CONFIGURATION 14689 // ========================================================= 14690 14691 public ConfigurationInfo getDeviceConfigurationInfo() { 14692 ConfigurationInfo config = new ConfigurationInfo(); 14693 synchronized (this) { 14694 config.reqTouchScreen = mConfiguration.touchscreen; 14695 config.reqKeyboardType = mConfiguration.keyboard; 14696 config.reqNavigation = mConfiguration.navigation; 14697 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14698 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14699 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14700 } 14701 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14702 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14703 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14704 } 14705 config.reqGlEsVersion = GL_ES_VERSION; 14706 } 14707 return config; 14708 } 14709 14710 ActivityStack getFocusedStack() { 14711 return mStackSupervisor.getFocusedStack(); 14712 } 14713 14714 public Configuration getConfiguration() { 14715 Configuration ci; 14716 synchronized(this) { 14717 ci = new Configuration(mConfiguration); 14718 } 14719 return ci; 14720 } 14721 14722 public void updatePersistentConfiguration(Configuration values) { 14723 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14724 "updateConfiguration()"); 14725 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14726 "updateConfiguration()"); 14727 if (values == null) { 14728 throw new NullPointerException("Configuration must not be null"); 14729 } 14730 14731 synchronized(this) { 14732 final long origId = Binder.clearCallingIdentity(); 14733 updateConfigurationLocked(values, null, true, false); 14734 Binder.restoreCallingIdentity(origId); 14735 } 14736 } 14737 14738 public void updateConfiguration(Configuration values) { 14739 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14740 "updateConfiguration()"); 14741 14742 synchronized(this) { 14743 if (values == null && mWindowManager != null) { 14744 // sentinel: fetch the current configuration from the window manager 14745 values = mWindowManager.computeNewConfiguration(); 14746 } 14747 14748 if (mWindowManager != null) { 14749 mProcessList.applyDisplaySize(mWindowManager); 14750 } 14751 14752 final long origId = Binder.clearCallingIdentity(); 14753 if (values != null) { 14754 Settings.System.clearConfiguration(values); 14755 } 14756 updateConfigurationLocked(values, null, false, false); 14757 Binder.restoreCallingIdentity(origId); 14758 } 14759 } 14760 14761 /** 14762 * Do either or both things: (1) change the current configuration, and (2) 14763 * make sure the given activity is running with the (now) current 14764 * configuration. Returns true if the activity has been left running, or 14765 * false if <var>starting</var> is being destroyed to match the new 14766 * configuration. 14767 * @param persistent TODO 14768 */ 14769 boolean updateConfigurationLocked(Configuration values, 14770 ActivityRecord starting, boolean persistent, boolean initLocale) { 14771 int changes = 0; 14772 14773 if (values != null) { 14774 Configuration newConfig = new Configuration(mConfiguration); 14775 changes = newConfig.updateFrom(values); 14776 if (changes != 0) { 14777 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14778 Slog.i(TAG, "Updating configuration to: " + values); 14779 } 14780 14781 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14782 14783 if (values.locale != null && !initLocale) { 14784 saveLocaleLocked(values.locale, 14785 !values.locale.equals(mConfiguration.locale), 14786 values.userSetLocale); 14787 } 14788 14789 mConfigurationSeq++; 14790 if (mConfigurationSeq <= 0) { 14791 mConfigurationSeq = 1; 14792 } 14793 newConfig.seq = mConfigurationSeq; 14794 mConfiguration = newConfig; 14795 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14796 mUsageStatsService.noteStartConfig(newConfig); 14797 14798 final Configuration configCopy = new Configuration(mConfiguration); 14799 14800 // TODO: If our config changes, should we auto dismiss any currently 14801 // showing dialogs? 14802 mShowDialogs = shouldShowDialogs(newConfig); 14803 14804 AttributeCache ac = AttributeCache.instance(); 14805 if (ac != null) { 14806 ac.updateConfiguration(configCopy); 14807 } 14808 14809 // Make sure all resources in our process are updated 14810 // right now, so that anyone who is going to retrieve 14811 // resource values after we return will be sure to get 14812 // the new ones. This is especially important during 14813 // boot, where the first config change needs to guarantee 14814 // all resources have that config before following boot 14815 // code is executed. 14816 mSystemThread.applyConfigurationToResources(configCopy); 14817 14818 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14819 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14820 msg.obj = new Configuration(configCopy); 14821 mHandler.sendMessage(msg); 14822 } 14823 14824 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14825 ProcessRecord app = mLruProcesses.get(i); 14826 try { 14827 if (app.thread != null) { 14828 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14829 + app.processName + " new config " + mConfiguration); 14830 app.thread.scheduleConfigurationChanged(configCopy); 14831 } 14832 } catch (Exception e) { 14833 } 14834 } 14835 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14836 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14837 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14838 | Intent.FLAG_RECEIVER_FOREGROUND); 14839 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14840 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14841 Process.SYSTEM_UID, UserHandle.USER_ALL); 14842 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14843 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14844 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14845 broadcastIntentLocked(null, null, intent, 14846 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14847 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14848 } 14849 } 14850 } 14851 14852 boolean kept = true; 14853 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14854 // mainStack is null during startup. 14855 if (mainStack != null) { 14856 if (changes != 0 && starting == null) { 14857 // If the configuration changed, and the caller is not already 14858 // in the process of starting an activity, then find the top 14859 // activity to check if its configuration needs to change. 14860 starting = mainStack.topRunningActivityLocked(null); 14861 } 14862 14863 if (starting != null) { 14864 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14865 // And we need to make sure at this point that all other activities 14866 // are made visible with the correct configuration. 14867 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14868 } 14869 } 14870 14871 if (values != null && mWindowManager != null) { 14872 mWindowManager.setNewConfiguration(mConfiguration); 14873 } 14874 14875 return kept; 14876 } 14877 14878 /** 14879 * Decide based on the configuration whether we should shouw the ANR, 14880 * crash, etc dialogs. The idea is that if there is no affordnace to 14881 * press the on-screen buttons, we shouldn't show the dialog. 14882 * 14883 * A thought: SystemUI might also want to get told about this, the Power 14884 * dialog / global actions also might want different behaviors. 14885 */ 14886 private static final boolean shouldShowDialogs(Configuration config) { 14887 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14888 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14889 } 14890 14891 /** 14892 * Save the locale. You must be inside a synchronized (this) block. 14893 */ 14894 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14895 if(isDiff) { 14896 SystemProperties.set("user.language", l.getLanguage()); 14897 SystemProperties.set("user.region", l.getCountry()); 14898 } 14899 14900 if(isPersist) { 14901 SystemProperties.set("persist.sys.language", l.getLanguage()); 14902 SystemProperties.set("persist.sys.country", l.getCountry()); 14903 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14904 } 14905 } 14906 14907 @Override 14908 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14909 ActivityRecord srec = ActivityRecord.forToken(token); 14910 return srec != null && srec.task.affinity != null && 14911 srec.task.affinity.equals(destAffinity); 14912 } 14913 14914 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14915 Intent resultData) { 14916 14917 synchronized (this) { 14918 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14919 if (stack != null) { 14920 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14921 } 14922 return false; 14923 } 14924 } 14925 14926 public int getLaunchedFromUid(IBinder activityToken) { 14927 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14928 if (srec == null) { 14929 return -1; 14930 } 14931 return srec.launchedFromUid; 14932 } 14933 14934 public String getLaunchedFromPackage(IBinder activityToken) { 14935 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14936 if (srec == null) { 14937 return null; 14938 } 14939 return srec.launchedFromPackage; 14940 } 14941 14942 // ========================================================= 14943 // LIFETIME MANAGEMENT 14944 // ========================================================= 14945 14946 // Returns which broadcast queue the app is the current [or imminent] receiver 14947 // on, or 'null' if the app is not an active broadcast recipient. 14948 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14949 BroadcastRecord r = app.curReceiver; 14950 if (r != null) { 14951 return r.queue; 14952 } 14953 14954 // It's not the current receiver, but it might be starting up to become one 14955 synchronized (this) { 14956 for (BroadcastQueue queue : mBroadcastQueues) { 14957 r = queue.mPendingBroadcast; 14958 if (r != null && r.curApp == app) { 14959 // found it; report which queue it's in 14960 return queue; 14961 } 14962 } 14963 } 14964 14965 return null; 14966 } 14967 14968 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14969 boolean doingAll, long now) { 14970 if (mAdjSeq == app.adjSeq) { 14971 // This adjustment has already been computed. 14972 return app.curRawAdj; 14973 } 14974 14975 if (app.thread == null) { 14976 app.adjSeq = mAdjSeq; 14977 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14978 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14979 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14980 } 14981 14982 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14983 app.adjSource = null; 14984 app.adjTarget = null; 14985 app.empty = false; 14986 app.cached = false; 14987 14988 final int activitiesSize = app.activities.size(); 14989 14990 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14991 // The max adjustment doesn't allow this app to be anything 14992 // below foreground, so it is not worth doing work for it. 14993 app.adjType = "fixed"; 14994 app.adjSeq = mAdjSeq; 14995 app.curRawAdj = app.maxAdj; 14996 app.foregroundActivities = false; 14997 app.keeping = true; 14998 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14999 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15000 // System processes can do UI, and when they do we want to have 15001 // them trim their memory after the user leaves the UI. To 15002 // facilitate this, here we need to determine whether or not it 15003 // is currently showing UI. 15004 app.systemNoUi = true; 15005 if (app == TOP_APP) { 15006 app.systemNoUi = false; 15007 } else if (activitiesSize > 0) { 15008 for (int j = 0; j < activitiesSize; j++) { 15009 final ActivityRecord r = app.activities.get(j); 15010 if (r.visible) { 15011 app.systemNoUi = false; 15012 } 15013 } 15014 } 15015 if (!app.systemNoUi) { 15016 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15017 } 15018 return (app.curAdj=app.maxAdj); 15019 } 15020 15021 app.keeping = false; 15022 app.systemNoUi = false; 15023 15024 // Determine the importance of the process, starting with most 15025 // important to least, and assign an appropriate OOM adjustment. 15026 int adj; 15027 int schedGroup; 15028 int procState; 15029 boolean foregroundActivities = false; 15030 BroadcastQueue queue; 15031 if (app == TOP_APP) { 15032 // The last app on the list is the foreground app. 15033 adj = ProcessList.FOREGROUND_APP_ADJ; 15034 schedGroup = Process.THREAD_GROUP_DEFAULT; 15035 app.adjType = "top-activity"; 15036 foregroundActivities = true; 15037 procState = ActivityManager.PROCESS_STATE_TOP; 15038 } else if (app.instrumentationClass != null) { 15039 // Don't want to kill running instrumentation. 15040 adj = ProcessList.FOREGROUND_APP_ADJ; 15041 schedGroup = Process.THREAD_GROUP_DEFAULT; 15042 app.adjType = "instrumentation"; 15043 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15044 } else if ((queue = isReceivingBroadcast(app)) != null) { 15045 // An app that is currently receiving a broadcast also 15046 // counts as being in the foreground for OOM killer purposes. 15047 // It's placed in a sched group based on the nature of the 15048 // broadcast as reflected by which queue it's active in. 15049 adj = ProcessList.FOREGROUND_APP_ADJ; 15050 schedGroup = (queue == mFgBroadcastQueue) 15051 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15052 app.adjType = "broadcast"; 15053 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15054 } else if (app.executingServices.size() > 0) { 15055 // An app that is currently executing a service callback also 15056 // counts as being in the foreground. 15057 adj = ProcessList.FOREGROUND_APP_ADJ; 15058 schedGroup = app.execServicesFg ? 15059 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15060 app.adjType = "exec-service"; 15061 procState = ActivityManager.PROCESS_STATE_SERVICE; 15062 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15063 } else { 15064 // As far as we know the process is empty. We may change our mind later. 15065 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15066 // At this point we don't actually know the adjustment. Use the cached adj 15067 // value that the caller wants us to. 15068 adj = cachedAdj; 15069 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15070 app.cached = true; 15071 app.empty = true; 15072 app.adjType = "cch-empty"; 15073 } 15074 15075 // Examine all activities if not already foreground. 15076 if (!foregroundActivities && activitiesSize > 0) { 15077 for (int j = 0; j < activitiesSize; j++) { 15078 final ActivityRecord r = app.activities.get(j); 15079 if (r.app != app) { 15080 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15081 + app + "?!?"); 15082 continue; 15083 } 15084 if (r.visible) { 15085 // App has a visible activity; only upgrade adjustment. 15086 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15087 adj = ProcessList.VISIBLE_APP_ADJ; 15088 app.adjType = "visible"; 15089 } 15090 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15091 procState = ActivityManager.PROCESS_STATE_TOP; 15092 } 15093 schedGroup = Process.THREAD_GROUP_DEFAULT; 15094 app.cached = false; 15095 app.empty = false; 15096 foregroundActivities = true; 15097 break; 15098 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15099 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15100 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15101 app.adjType = "pausing"; 15102 } 15103 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15104 procState = ActivityManager.PROCESS_STATE_TOP; 15105 } 15106 schedGroup = Process.THREAD_GROUP_DEFAULT; 15107 app.cached = false; 15108 app.empty = false; 15109 foregroundActivities = true; 15110 } else if (r.state == ActivityState.STOPPING) { 15111 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15112 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15113 app.adjType = "stopping"; 15114 } 15115 // For the process state, we will at this point consider the 15116 // process to be cached. It will be cached either as an activity 15117 // or empty depending on whether the activity is finishing. We do 15118 // this so that we can treat the process as cached for purposes of 15119 // memory trimming (determing current memory level, trim command to 15120 // send to process) since there can be an arbitrary number of stopping 15121 // processes and they should soon all go into the cached state. 15122 if (!r.finishing) { 15123 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15124 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15125 } 15126 } 15127 app.cached = false; 15128 app.empty = false; 15129 foregroundActivities = true; 15130 } else { 15131 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15132 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15133 app.adjType = "cch-act"; 15134 } 15135 } 15136 } 15137 } 15138 15139 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15140 if (app.foregroundServices) { 15141 // The user is aware of this app, so make it visible. 15142 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15143 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15144 app.cached = false; 15145 app.adjType = "fg-service"; 15146 schedGroup = Process.THREAD_GROUP_DEFAULT; 15147 } else if (app.forcingToForeground != null) { 15148 // The user is aware of this app, so make it visible. 15149 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15150 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15151 app.cached = false; 15152 app.adjType = "force-fg"; 15153 app.adjSource = app.forcingToForeground; 15154 schedGroup = Process.THREAD_GROUP_DEFAULT; 15155 } 15156 } 15157 15158 if (app == mHeavyWeightProcess) { 15159 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15160 // We don't want to kill the current heavy-weight process. 15161 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15162 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15163 app.cached = false; 15164 app.adjType = "heavy"; 15165 } 15166 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15167 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15168 } 15169 } 15170 15171 if (app == mHomeProcess) { 15172 if (adj > ProcessList.HOME_APP_ADJ) { 15173 // This process is hosting what we currently consider to be the 15174 // home app, so we don't want to let it go into the background. 15175 adj = ProcessList.HOME_APP_ADJ; 15176 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15177 app.cached = false; 15178 app.adjType = "home"; 15179 } 15180 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15181 procState = ActivityManager.PROCESS_STATE_HOME; 15182 } 15183 } 15184 15185 if (app == mPreviousProcess && app.activities.size() > 0) { 15186 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15187 // This was the previous process that showed UI to the user. 15188 // We want to try to keep it around more aggressively, to give 15189 // a good experience around switching between two apps. 15190 adj = ProcessList.PREVIOUS_APP_ADJ; 15191 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15192 app.cached = false; 15193 app.adjType = "previous"; 15194 } 15195 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15196 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15197 } 15198 } 15199 15200 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15201 + " reason=" + app.adjType); 15202 15203 // By default, we use the computed adjustment. It may be changed if 15204 // there are applications dependent on our services or providers, but 15205 // this gives us a baseline and makes sure we don't get into an 15206 // infinite recursion. 15207 app.adjSeq = mAdjSeq; 15208 app.curRawAdj = adj; 15209 app.hasStartedServices = false; 15210 15211 if (mBackupTarget != null && app == mBackupTarget.app) { 15212 // If possible we want to avoid killing apps while they're being backed up 15213 if (adj > ProcessList.BACKUP_APP_ADJ) { 15214 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15215 adj = ProcessList.BACKUP_APP_ADJ; 15216 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15217 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15218 } 15219 app.adjType = "backup"; 15220 app.cached = false; 15221 } 15222 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15223 procState = ActivityManager.PROCESS_STATE_BACKUP; 15224 } 15225 } 15226 15227 boolean mayBeTop = false; 15228 15229 for (int is = app.services.size()-1; 15230 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15231 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15232 || procState > ActivityManager.PROCESS_STATE_TOP); 15233 is--) { 15234 ServiceRecord s = app.services.valueAt(is); 15235 if (s.startRequested) { 15236 app.hasStartedServices = true; 15237 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15238 procState = ActivityManager.PROCESS_STATE_SERVICE; 15239 } 15240 if (app.hasShownUi && app != mHomeProcess) { 15241 // If this process has shown some UI, let it immediately 15242 // go to the LRU list because it may be pretty heavy with 15243 // UI stuff. We'll tag it with a label just to help 15244 // debug and understand what is going on. 15245 if (adj > ProcessList.SERVICE_ADJ) { 15246 app.adjType = "cch-started-ui-services"; 15247 } 15248 } else { 15249 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15250 // This service has seen some activity within 15251 // recent memory, so we will keep its process ahead 15252 // of the background processes. 15253 if (adj > ProcessList.SERVICE_ADJ) { 15254 adj = ProcessList.SERVICE_ADJ; 15255 app.adjType = "started-services"; 15256 app.cached = false; 15257 } 15258 } 15259 // If we have let the service slide into the background 15260 // state, still have some text describing what it is doing 15261 // even though the service no longer has an impact. 15262 if (adj > ProcessList.SERVICE_ADJ) { 15263 app.adjType = "cch-started-services"; 15264 } 15265 } 15266 // Don't kill this process because it is doing work; it 15267 // has said it is doing work. 15268 app.keeping = true; 15269 } 15270 for (int conni = s.connections.size()-1; 15271 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15272 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15273 || procState > ActivityManager.PROCESS_STATE_TOP); 15274 conni--) { 15275 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15276 for (int i = 0; 15277 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15278 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15279 || procState > ActivityManager.PROCESS_STATE_TOP); 15280 i++) { 15281 // XXX should compute this based on the max of 15282 // all connected clients. 15283 ConnectionRecord cr = clist.get(i); 15284 if (cr.binding.client == app) { 15285 // Binding to ourself is not interesting. 15286 continue; 15287 } 15288 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15289 ProcessRecord client = cr.binding.client; 15290 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15291 TOP_APP, doingAll, now); 15292 int clientProcState = client.curProcState; 15293 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15294 // If the other app is cached for any reason, for purposes here 15295 // we are going to consider it empty. The specific cached state 15296 // doesn't propagate except under certain conditions. 15297 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15298 } 15299 String adjType = null; 15300 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15301 // Not doing bind OOM management, so treat 15302 // this guy more like a started service. 15303 if (app.hasShownUi && app != mHomeProcess) { 15304 // If this process has shown some UI, let it immediately 15305 // go to the LRU list because it may be pretty heavy with 15306 // UI stuff. We'll tag it with a label just to help 15307 // debug and understand what is going on. 15308 if (adj > clientAdj) { 15309 adjType = "cch-bound-ui-services"; 15310 } 15311 app.cached = false; 15312 clientAdj = adj; 15313 clientProcState = procState; 15314 } else { 15315 if (now >= (s.lastActivity 15316 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15317 // This service has not seen activity within 15318 // recent memory, so allow it to drop to the 15319 // LRU list if there is no other reason to keep 15320 // it around. We'll also tag it with a label just 15321 // to help debug and undertand what is going on. 15322 if (adj > clientAdj) { 15323 adjType = "cch-bound-services"; 15324 } 15325 clientAdj = adj; 15326 } 15327 } 15328 } 15329 if (adj > clientAdj) { 15330 // If this process has recently shown UI, and 15331 // the process that is binding to it is less 15332 // important than being visible, then we don't 15333 // care about the binding as much as we care 15334 // about letting this process get into the LRU 15335 // list to be killed and restarted if needed for 15336 // memory. 15337 if (app.hasShownUi && app != mHomeProcess 15338 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15339 adjType = "cch-bound-ui-services"; 15340 } else { 15341 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15342 |Context.BIND_IMPORTANT)) != 0) { 15343 adj = clientAdj; 15344 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15345 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15346 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15347 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15348 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15349 adj = clientAdj; 15350 } else { 15351 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15352 adj = ProcessList.VISIBLE_APP_ADJ; 15353 } 15354 } 15355 if (!client.cached) { 15356 app.cached = false; 15357 } 15358 if (client.keeping) { 15359 app.keeping = true; 15360 } 15361 adjType = "service"; 15362 } 15363 } 15364 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15365 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15366 schedGroup = Process.THREAD_GROUP_DEFAULT; 15367 } 15368 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15369 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15370 // Special handling of clients who are in the top state. 15371 // We *may* want to consider this process to be in the 15372 // top state as well, but only if there is not another 15373 // reason for it to be running. Being on the top is a 15374 // special state, meaning you are specifically running 15375 // for the current top app. If the process is already 15376 // running in the background for some other reason, it 15377 // is more important to continue considering it to be 15378 // in the background state. 15379 mayBeTop = true; 15380 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15381 } else { 15382 // Special handling for above-top states (persistent 15383 // processes). These should not bring the current process 15384 // into the top state, since they are not on top. Instead 15385 // give them the best state after that. 15386 clientProcState = 15387 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15388 } 15389 } 15390 } else { 15391 if (clientProcState < 15392 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15393 clientProcState = 15394 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15395 } 15396 } 15397 if (procState > clientProcState) { 15398 procState = clientProcState; 15399 } 15400 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15401 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15402 app.pendingUiClean = true; 15403 } 15404 if (adjType != null) { 15405 app.adjType = adjType; 15406 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15407 .REASON_SERVICE_IN_USE; 15408 app.adjSource = cr.binding.client; 15409 app.adjSourceOom = clientAdj; 15410 app.adjTarget = s.name; 15411 } 15412 } 15413 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15414 app.treatLikeActivity = true; 15415 } 15416 final ActivityRecord a = cr.activity; 15417 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15418 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15419 (a.visible || a.state == ActivityState.RESUMED 15420 || a.state == ActivityState.PAUSING)) { 15421 adj = ProcessList.FOREGROUND_APP_ADJ; 15422 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15423 schedGroup = Process.THREAD_GROUP_DEFAULT; 15424 } 15425 app.cached = false; 15426 app.adjType = "service"; 15427 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15428 .REASON_SERVICE_IN_USE; 15429 app.adjSource = a; 15430 app.adjSourceOom = adj; 15431 app.adjTarget = s.name; 15432 } 15433 } 15434 } 15435 } 15436 } 15437 15438 for (int provi = app.pubProviders.size()-1; 15439 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15440 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15441 || procState > ActivityManager.PROCESS_STATE_TOP); 15442 provi--) { 15443 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15444 for (int i = cpr.connections.size()-1; 15445 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15446 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15447 || procState > ActivityManager.PROCESS_STATE_TOP); 15448 i--) { 15449 ContentProviderConnection conn = cpr.connections.get(i); 15450 ProcessRecord client = conn.client; 15451 if (client == app) { 15452 // Being our own client is not interesting. 15453 continue; 15454 } 15455 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15456 int clientProcState = client.curProcState; 15457 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15458 // If the other app is cached for any reason, for purposes here 15459 // we are going to consider it empty. 15460 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15461 } 15462 if (adj > clientAdj) { 15463 if (app.hasShownUi && app != mHomeProcess 15464 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15465 app.adjType = "cch-ui-provider"; 15466 } else { 15467 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15468 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15469 app.adjType = "provider"; 15470 } 15471 app.cached &= client.cached; 15472 app.keeping |= client.keeping; 15473 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15474 .REASON_PROVIDER_IN_USE; 15475 app.adjSource = client; 15476 app.adjSourceOom = clientAdj; 15477 app.adjTarget = cpr.name; 15478 } 15479 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15480 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15481 // Special handling of clients who are in the top state. 15482 // We *may* want to consider this process to be in the 15483 // top state as well, but only if there is not another 15484 // reason for it to be running. Being on the top is a 15485 // special state, meaning you are specifically running 15486 // for the current top app. If the process is already 15487 // running in the background for some other reason, it 15488 // is more important to continue considering it to be 15489 // in the background state. 15490 mayBeTop = true; 15491 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15492 } else { 15493 // Special handling for above-top states (persistent 15494 // processes). These should not bring the current process 15495 // into the top state, since they are not on top. Instead 15496 // give them the best state after that. 15497 clientProcState = 15498 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15499 } 15500 } 15501 if (procState > clientProcState) { 15502 procState = clientProcState; 15503 } 15504 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15505 schedGroup = Process.THREAD_GROUP_DEFAULT; 15506 } 15507 } 15508 // If the provider has external (non-framework) process 15509 // dependencies, ensure that its adjustment is at least 15510 // FOREGROUND_APP_ADJ. 15511 if (cpr.hasExternalProcessHandles()) { 15512 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15513 adj = ProcessList.FOREGROUND_APP_ADJ; 15514 schedGroup = Process.THREAD_GROUP_DEFAULT; 15515 app.cached = false; 15516 app.keeping = true; 15517 app.adjType = "provider"; 15518 app.adjTarget = cpr.name; 15519 } 15520 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15521 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15522 } 15523 } 15524 } 15525 15526 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15527 // A client of one of our services or providers is in the top state. We 15528 // *may* want to be in the top state, but not if we are already running in 15529 // the background for some other reason. For the decision here, we are going 15530 // to pick out a few specific states that we want to remain in when a client 15531 // is top (states that tend to be longer-term) and otherwise allow it to go 15532 // to the top state. 15533 switch (procState) { 15534 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15535 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15536 case ActivityManager.PROCESS_STATE_SERVICE: 15537 // These all are longer-term states, so pull them up to the top 15538 // of the background states, but not all the way to the top state. 15539 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15540 break; 15541 default: 15542 // Otherwise, top is a better choice, so take it. 15543 procState = ActivityManager.PROCESS_STATE_TOP; 15544 break; 15545 } 15546 } 15547 15548 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15549 if (app.hasClientActivities) { 15550 // This is a cached process, but with client activities. Mark it so. 15551 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15552 app.adjType = "cch-client-act"; 15553 } else if (app.treatLikeActivity) { 15554 // This is a cached process, but somebody wants us to treat it like it has 15555 // an activity, okay! 15556 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15557 app.adjType = "cch-as-act"; 15558 } 15559 } 15560 15561 if (adj == ProcessList.SERVICE_ADJ) { 15562 if (doingAll) { 15563 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15564 mNewNumServiceProcs++; 15565 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15566 if (!app.serviceb) { 15567 // This service isn't far enough down on the LRU list to 15568 // normally be a B service, but if we are low on RAM and it 15569 // is large we want to force it down since we would prefer to 15570 // keep launcher over it. 15571 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15572 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15573 app.serviceHighRam = true; 15574 app.serviceb = true; 15575 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15576 } else { 15577 mNewNumAServiceProcs++; 15578 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15579 } 15580 } else { 15581 app.serviceHighRam = false; 15582 } 15583 } 15584 if (app.serviceb) { 15585 adj = ProcessList.SERVICE_B_ADJ; 15586 } 15587 } 15588 15589 app.curRawAdj = adj; 15590 15591 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15592 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15593 if (adj > app.maxAdj) { 15594 adj = app.maxAdj; 15595 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15596 schedGroup = Process.THREAD_GROUP_DEFAULT; 15597 } 15598 } 15599 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15600 app.keeping = true; 15601 } 15602 15603 // Do final modification to adj. Everything we do between here and applying 15604 // the final setAdj must be done in this function, because we will also use 15605 // it when computing the final cached adj later. Note that we don't need to 15606 // worry about this for max adj above, since max adj will always be used to 15607 // keep it out of the cached vaues. 15608 app.curAdj = app.modifyRawOomAdj(adj); 15609 app.curSchedGroup = schedGroup; 15610 app.curProcState = procState; 15611 app.foregroundActivities = foregroundActivities; 15612 15613 return app.curRawAdj; 15614 } 15615 15616 /** 15617 * Schedule PSS collection of a process. 15618 */ 15619 void requestPssLocked(ProcessRecord proc, int procState) { 15620 if (mPendingPssProcesses.contains(proc)) { 15621 return; 15622 } 15623 if (mPendingPssProcesses.size() == 0) { 15624 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15625 } 15626 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15627 proc.pssProcState = procState; 15628 mPendingPssProcesses.add(proc); 15629 } 15630 15631 /** 15632 * Schedule PSS collection of all processes. 15633 */ 15634 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15635 if (!always) { 15636 if (now < (mLastFullPssTime + 15637 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15638 return; 15639 } 15640 } 15641 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15642 mLastFullPssTime = now; 15643 mFullPssPending = true; 15644 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15645 mPendingPssProcesses.clear(); 15646 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15647 ProcessRecord app = mLruProcesses.get(i); 15648 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15649 app.pssProcState = app.setProcState; 15650 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15651 isSleeping(), now); 15652 mPendingPssProcesses.add(app); 15653 } 15654 } 15655 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15656 } 15657 15658 /** 15659 * Ask a given process to GC right now. 15660 */ 15661 final void performAppGcLocked(ProcessRecord app) { 15662 try { 15663 app.lastRequestedGc = SystemClock.uptimeMillis(); 15664 if (app.thread != null) { 15665 if (app.reportLowMemory) { 15666 app.reportLowMemory = false; 15667 app.thread.scheduleLowMemory(); 15668 } else { 15669 app.thread.processInBackground(); 15670 } 15671 } 15672 } catch (Exception e) { 15673 // whatever. 15674 } 15675 } 15676 15677 /** 15678 * Returns true if things are idle enough to perform GCs. 15679 */ 15680 private final boolean canGcNowLocked() { 15681 boolean processingBroadcasts = false; 15682 for (BroadcastQueue q : mBroadcastQueues) { 15683 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15684 processingBroadcasts = true; 15685 } 15686 } 15687 return !processingBroadcasts 15688 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15689 } 15690 15691 /** 15692 * Perform GCs on all processes that are waiting for it, but only 15693 * if things are idle. 15694 */ 15695 final void performAppGcsLocked() { 15696 final int N = mProcessesToGc.size(); 15697 if (N <= 0) { 15698 return; 15699 } 15700 if (canGcNowLocked()) { 15701 while (mProcessesToGc.size() > 0) { 15702 ProcessRecord proc = mProcessesToGc.remove(0); 15703 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15704 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15705 <= SystemClock.uptimeMillis()) { 15706 // To avoid spamming the system, we will GC processes one 15707 // at a time, waiting a few seconds between each. 15708 performAppGcLocked(proc); 15709 scheduleAppGcsLocked(); 15710 return; 15711 } else { 15712 // It hasn't been long enough since we last GCed this 15713 // process... put it in the list to wait for its time. 15714 addProcessToGcListLocked(proc); 15715 break; 15716 } 15717 } 15718 } 15719 15720 scheduleAppGcsLocked(); 15721 } 15722 } 15723 15724 /** 15725 * If all looks good, perform GCs on all processes waiting for them. 15726 */ 15727 final void performAppGcsIfAppropriateLocked() { 15728 if (canGcNowLocked()) { 15729 performAppGcsLocked(); 15730 return; 15731 } 15732 // Still not idle, wait some more. 15733 scheduleAppGcsLocked(); 15734 } 15735 15736 /** 15737 * Schedule the execution of all pending app GCs. 15738 */ 15739 final void scheduleAppGcsLocked() { 15740 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15741 15742 if (mProcessesToGc.size() > 0) { 15743 // Schedule a GC for the time to the next process. 15744 ProcessRecord proc = mProcessesToGc.get(0); 15745 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15746 15747 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15748 long now = SystemClock.uptimeMillis(); 15749 if (when < (now+GC_TIMEOUT)) { 15750 when = now + GC_TIMEOUT; 15751 } 15752 mHandler.sendMessageAtTime(msg, when); 15753 } 15754 } 15755 15756 /** 15757 * Add a process to the array of processes waiting to be GCed. Keeps the 15758 * list in sorted order by the last GC time. The process can't already be 15759 * on the list. 15760 */ 15761 final void addProcessToGcListLocked(ProcessRecord proc) { 15762 boolean added = false; 15763 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15764 if (mProcessesToGc.get(i).lastRequestedGc < 15765 proc.lastRequestedGc) { 15766 added = true; 15767 mProcessesToGc.add(i+1, proc); 15768 break; 15769 } 15770 } 15771 if (!added) { 15772 mProcessesToGc.add(0, proc); 15773 } 15774 } 15775 15776 /** 15777 * Set up to ask a process to GC itself. This will either do it 15778 * immediately, or put it on the list of processes to gc the next 15779 * time things are idle. 15780 */ 15781 final void scheduleAppGcLocked(ProcessRecord app) { 15782 long now = SystemClock.uptimeMillis(); 15783 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15784 return; 15785 } 15786 if (!mProcessesToGc.contains(app)) { 15787 addProcessToGcListLocked(app); 15788 scheduleAppGcsLocked(); 15789 } 15790 } 15791 15792 final void checkExcessivePowerUsageLocked(boolean doKills) { 15793 updateCpuStatsNow(); 15794 15795 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15796 boolean doWakeKills = doKills; 15797 boolean doCpuKills = doKills; 15798 if (mLastPowerCheckRealtime == 0) { 15799 doWakeKills = false; 15800 } 15801 if (mLastPowerCheckUptime == 0) { 15802 doCpuKills = false; 15803 } 15804 if (stats.isScreenOn()) { 15805 doWakeKills = false; 15806 } 15807 final long curRealtime = SystemClock.elapsedRealtime(); 15808 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15809 final long curUptime = SystemClock.uptimeMillis(); 15810 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15811 mLastPowerCheckRealtime = curRealtime; 15812 mLastPowerCheckUptime = curUptime; 15813 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15814 doWakeKills = false; 15815 } 15816 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15817 doCpuKills = false; 15818 } 15819 int i = mLruProcesses.size(); 15820 while (i > 0) { 15821 i--; 15822 ProcessRecord app = mLruProcesses.get(i); 15823 if (!app.keeping) { 15824 long wtime; 15825 synchronized (stats) { 15826 wtime = stats.getProcessWakeTime(app.info.uid, 15827 app.pid, curRealtime); 15828 } 15829 long wtimeUsed = wtime - app.lastWakeTime; 15830 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15831 if (DEBUG_POWER) { 15832 StringBuilder sb = new StringBuilder(128); 15833 sb.append("Wake for "); 15834 app.toShortString(sb); 15835 sb.append(": over "); 15836 TimeUtils.formatDuration(realtimeSince, sb); 15837 sb.append(" used "); 15838 TimeUtils.formatDuration(wtimeUsed, sb); 15839 sb.append(" ("); 15840 sb.append((wtimeUsed*100)/realtimeSince); 15841 sb.append("%)"); 15842 Slog.i(TAG, sb.toString()); 15843 sb.setLength(0); 15844 sb.append("CPU for "); 15845 app.toShortString(sb); 15846 sb.append(": over "); 15847 TimeUtils.formatDuration(uptimeSince, sb); 15848 sb.append(" used "); 15849 TimeUtils.formatDuration(cputimeUsed, sb); 15850 sb.append(" ("); 15851 sb.append((cputimeUsed*100)/uptimeSince); 15852 sb.append("%)"); 15853 Slog.i(TAG, sb.toString()); 15854 } 15855 // If a process has held a wake lock for more 15856 // than 50% of the time during this period, 15857 // that sounds bad. Kill! 15858 if (doWakeKills && realtimeSince > 0 15859 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15860 synchronized (stats) { 15861 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15862 realtimeSince, wtimeUsed); 15863 } 15864 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15865 + " during " + realtimeSince); 15866 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15867 } else if (doCpuKills && uptimeSince > 0 15868 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15869 synchronized (stats) { 15870 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15871 uptimeSince, cputimeUsed); 15872 } 15873 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15874 + " during " + uptimeSince); 15875 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15876 } else { 15877 app.lastWakeTime = wtime; 15878 app.lastCpuTime = app.curCpuTime; 15879 } 15880 } 15881 } 15882 } 15883 15884 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15885 ProcessRecord TOP_APP, boolean doingAll, long now) { 15886 boolean success = true; 15887 15888 if (app.curRawAdj != app.setRawAdj) { 15889 if (wasKeeping && !app.keeping) { 15890 // This app is no longer something we want to keep. Note 15891 // its current wake lock time to later know to kill it if 15892 // it is not behaving well. 15893 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15894 synchronized (stats) { 15895 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15896 app.pid, SystemClock.elapsedRealtime()); 15897 } 15898 app.lastCpuTime = app.curCpuTime; 15899 } 15900 15901 app.setRawAdj = app.curRawAdj; 15902 } 15903 15904 int changes = 0; 15905 15906 if (app.curAdj != app.setAdj) { 15907 ProcessList.setOomAdj(app.pid, app.curAdj); 15908 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15909 TAG, "Set " + app.pid + " " + app.processName + 15910 " adj " + app.curAdj + ": " + app.adjType); 15911 app.setAdj = app.curAdj; 15912 } 15913 15914 if (app.setSchedGroup != app.curSchedGroup) { 15915 app.setSchedGroup = app.curSchedGroup; 15916 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15917 "Setting process group of " + app.processName 15918 + " to " + app.curSchedGroup); 15919 if (app.waitingToKill != null && 15920 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15921 killUnneededProcessLocked(app, app.waitingToKill); 15922 success = false; 15923 } else { 15924 if (true) { 15925 long oldId = Binder.clearCallingIdentity(); 15926 try { 15927 Process.setProcessGroup(app.pid, app.curSchedGroup); 15928 } catch (Exception e) { 15929 Slog.w(TAG, "Failed setting process group of " + app.pid 15930 + " to " + app.curSchedGroup); 15931 e.printStackTrace(); 15932 } finally { 15933 Binder.restoreCallingIdentity(oldId); 15934 } 15935 } else { 15936 if (app.thread != null) { 15937 try { 15938 app.thread.setSchedulingGroup(app.curSchedGroup); 15939 } catch (RemoteException e) { 15940 } 15941 } 15942 } 15943 Process.setSwappiness(app.pid, 15944 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15945 } 15946 } 15947 if (app.repForegroundActivities != app.foregroundActivities) { 15948 app.repForegroundActivities = app.foregroundActivities; 15949 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15950 } 15951 if (app.repProcState != app.curProcState) { 15952 app.repProcState = app.curProcState; 15953 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15954 if (app.thread != null) { 15955 try { 15956 if (false) { 15957 //RuntimeException h = new RuntimeException("here"); 15958 Slog.i(TAG, "Sending new process state " + app.repProcState 15959 + " to " + app /*, h*/); 15960 } 15961 app.thread.setProcessState(app.repProcState); 15962 } catch (RemoteException e) { 15963 } 15964 } 15965 } 15966 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15967 app.setProcState)) { 15968 app.lastStateTime = now; 15969 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15970 isSleeping(), now); 15971 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15972 + ProcessList.makeProcStateString(app.setProcState) + " to " 15973 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15974 + (app.nextPssTime-now) + ": " + app); 15975 } else { 15976 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15977 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15978 requestPssLocked(app, app.setProcState); 15979 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15980 isSleeping(), now); 15981 } else if (false && DEBUG_PSS) { 15982 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15983 } 15984 } 15985 if (app.setProcState != app.curProcState) { 15986 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15987 "Proc state change of " + app.processName 15988 + " to " + app.curProcState); 15989 app.setProcState = app.curProcState; 15990 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15991 app.notCachedSinceIdle = false; 15992 } 15993 if (!doingAll) { 15994 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15995 } else { 15996 app.procStateChanged = true; 15997 } 15998 } 15999 16000 if (changes != 0) { 16001 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16002 int i = mPendingProcessChanges.size()-1; 16003 ProcessChangeItem item = null; 16004 while (i >= 0) { 16005 item = mPendingProcessChanges.get(i); 16006 if (item.pid == app.pid) { 16007 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16008 break; 16009 } 16010 i--; 16011 } 16012 if (i < 0) { 16013 // No existing item in pending changes; need a new one. 16014 final int NA = mAvailProcessChanges.size(); 16015 if (NA > 0) { 16016 item = mAvailProcessChanges.remove(NA-1); 16017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16018 } else { 16019 item = new ProcessChangeItem(); 16020 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16021 } 16022 item.changes = 0; 16023 item.pid = app.pid; 16024 item.uid = app.info.uid; 16025 if (mPendingProcessChanges.size() == 0) { 16026 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16027 "*** Enqueueing dispatch processes changed!"); 16028 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16029 } 16030 mPendingProcessChanges.add(item); 16031 } 16032 item.changes |= changes; 16033 item.processState = app.repProcState; 16034 item.foregroundActivities = app.repForegroundActivities; 16035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16036 + Integer.toHexString(System.identityHashCode(item)) 16037 + " " + app.toShortString() + ": changes=" + item.changes 16038 + " procState=" + item.processState 16039 + " foreground=" + item.foregroundActivities 16040 + " type=" + app.adjType + " source=" + app.adjSource 16041 + " target=" + app.adjTarget); 16042 } 16043 16044 return success; 16045 } 16046 16047 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16048 if (proc.thread != null && proc.baseProcessTracker != null) { 16049 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16050 } 16051 } 16052 16053 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16054 ProcessRecord TOP_APP, boolean doingAll, long now) { 16055 if (app.thread == null) { 16056 return false; 16057 } 16058 16059 final boolean wasKeeping = app.keeping; 16060 16061 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16062 16063 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16064 } 16065 16066 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16067 boolean oomAdj) { 16068 if (isForeground != proc.foregroundServices) { 16069 proc.foregroundServices = isForeground; 16070 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16071 proc.info.uid); 16072 if (isForeground) { 16073 if (curProcs == null) { 16074 curProcs = new ArrayList<ProcessRecord>(); 16075 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16076 } 16077 if (!curProcs.contains(proc)) { 16078 curProcs.add(proc); 16079 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16080 proc.info.packageName, proc.info.uid); 16081 } 16082 } else { 16083 if (curProcs != null) { 16084 if (curProcs.remove(proc)) { 16085 mBatteryStatsService.noteEvent( 16086 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16087 proc.info.packageName, proc.info.uid); 16088 if (curProcs.size() <= 0) { 16089 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16090 } 16091 } 16092 } 16093 } 16094 if (oomAdj) { 16095 updateOomAdjLocked(); 16096 } 16097 } 16098 } 16099 16100 private final ActivityRecord resumedAppLocked() { 16101 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16102 String pkg; 16103 int uid; 16104 if (act != null && !act.sleeping) { 16105 pkg = act.packageName; 16106 uid = act.info.applicationInfo.uid; 16107 } else { 16108 pkg = null; 16109 uid = -1; 16110 } 16111 // Has the UID or resumed package name changed? 16112 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16113 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16114 if (mCurResumedPackage != null) { 16115 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16116 mCurResumedPackage, mCurResumedUid); 16117 } 16118 mCurResumedPackage = pkg; 16119 mCurResumedUid = uid; 16120 if (mCurResumedPackage != null) { 16121 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16122 mCurResumedPackage, mCurResumedUid); 16123 } 16124 } 16125 return act; 16126 } 16127 16128 final boolean updateOomAdjLocked(ProcessRecord app) { 16129 final ActivityRecord TOP_ACT = resumedAppLocked(); 16130 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16131 final boolean wasCached = app.cached; 16132 16133 mAdjSeq++; 16134 16135 // This is the desired cached adjusment we want to tell it to use. 16136 // If our app is currently cached, we know it, and that is it. Otherwise, 16137 // we don't know it yet, and it needs to now be cached we will then 16138 // need to do a complete oom adj. 16139 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16140 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16141 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16142 SystemClock.uptimeMillis()); 16143 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16144 // Changed to/from cached state, so apps after it in the LRU 16145 // list may also be changed. 16146 updateOomAdjLocked(); 16147 } 16148 return success; 16149 } 16150 16151 final void updateOomAdjLocked() { 16152 final ActivityRecord TOP_ACT = resumedAppLocked(); 16153 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16154 final long now = SystemClock.uptimeMillis(); 16155 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16156 final int N = mLruProcesses.size(); 16157 16158 if (false) { 16159 RuntimeException e = new RuntimeException(); 16160 e.fillInStackTrace(); 16161 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16162 } 16163 16164 mAdjSeq++; 16165 mNewNumServiceProcs = 0; 16166 mNewNumAServiceProcs = 0; 16167 16168 final int emptyProcessLimit; 16169 final int cachedProcessLimit; 16170 if (mProcessLimit <= 0) { 16171 emptyProcessLimit = cachedProcessLimit = 0; 16172 } else if (mProcessLimit == 1) { 16173 emptyProcessLimit = 1; 16174 cachedProcessLimit = 0; 16175 } else { 16176 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16177 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16178 } 16179 16180 // Let's determine how many processes we have running vs. 16181 // how many slots we have for background processes; we may want 16182 // to put multiple processes in a slot of there are enough of 16183 // them. 16184 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16185 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16186 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16187 if (numEmptyProcs > cachedProcessLimit) { 16188 // If there are more empty processes than our limit on cached 16189 // processes, then use the cached process limit for the factor. 16190 // This ensures that the really old empty processes get pushed 16191 // down to the bottom, so if we are running low on memory we will 16192 // have a better chance at keeping around more cached processes 16193 // instead of a gazillion empty processes. 16194 numEmptyProcs = cachedProcessLimit; 16195 } 16196 int emptyFactor = numEmptyProcs/numSlots; 16197 if (emptyFactor < 1) emptyFactor = 1; 16198 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16199 if (cachedFactor < 1) cachedFactor = 1; 16200 int stepCached = 0; 16201 int stepEmpty = 0; 16202 int numCached = 0; 16203 int numEmpty = 0; 16204 int numTrimming = 0; 16205 16206 mNumNonCachedProcs = 0; 16207 mNumCachedHiddenProcs = 0; 16208 16209 // First update the OOM adjustment for each of the 16210 // application processes based on their current state. 16211 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16212 int nextCachedAdj = curCachedAdj+1; 16213 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16214 int nextEmptyAdj = curEmptyAdj+2; 16215 for (int i=N-1; i>=0; i--) { 16216 ProcessRecord app = mLruProcesses.get(i); 16217 if (!app.killedByAm && app.thread != null) { 16218 app.procStateChanged = false; 16219 final boolean wasKeeping = app.keeping; 16220 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16221 16222 // If we haven't yet assigned the final cached adj 16223 // to the process, do that now. 16224 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16225 switch (app.curProcState) { 16226 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16227 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16228 // This process is a cached process holding activities... 16229 // assign it the next cached value for that type, and then 16230 // step that cached level. 16231 app.curRawAdj = curCachedAdj; 16232 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16233 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16234 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16235 + ")"); 16236 if (curCachedAdj != nextCachedAdj) { 16237 stepCached++; 16238 if (stepCached >= cachedFactor) { 16239 stepCached = 0; 16240 curCachedAdj = nextCachedAdj; 16241 nextCachedAdj += 2; 16242 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16243 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16244 } 16245 } 16246 } 16247 break; 16248 default: 16249 // For everything else, assign next empty cached process 16250 // level and bump that up. Note that this means that 16251 // long-running services that have dropped down to the 16252 // cached level will be treated as empty (since their process 16253 // state is still as a service), which is what we want. 16254 app.curRawAdj = curEmptyAdj; 16255 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16256 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16257 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16258 + ")"); 16259 if (curEmptyAdj != nextEmptyAdj) { 16260 stepEmpty++; 16261 if (stepEmpty >= emptyFactor) { 16262 stepEmpty = 0; 16263 curEmptyAdj = nextEmptyAdj; 16264 nextEmptyAdj += 2; 16265 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16266 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16267 } 16268 } 16269 } 16270 break; 16271 } 16272 } 16273 16274 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16275 16276 // Count the number of process types. 16277 switch (app.curProcState) { 16278 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16279 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16280 mNumCachedHiddenProcs++; 16281 numCached++; 16282 if (numCached > cachedProcessLimit) { 16283 killUnneededProcessLocked(app, "cached #" + numCached); 16284 } 16285 break; 16286 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16287 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16288 && app.lastActivityTime < oldTime) { 16289 killUnneededProcessLocked(app, "empty for " 16290 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16291 / 1000) + "s"); 16292 } else { 16293 numEmpty++; 16294 if (numEmpty > emptyProcessLimit) { 16295 killUnneededProcessLocked(app, "empty #" + numEmpty); 16296 } 16297 } 16298 break; 16299 default: 16300 mNumNonCachedProcs++; 16301 break; 16302 } 16303 16304 if (app.isolated && app.services.size() <= 0) { 16305 // If this is an isolated process, and there are no 16306 // services running in it, then the process is no longer 16307 // needed. We agressively kill these because we can by 16308 // definition not re-use the same process again, and it is 16309 // good to avoid having whatever code was running in them 16310 // left sitting around after no longer needed. 16311 killUnneededProcessLocked(app, "isolated not needed"); 16312 } 16313 16314 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16315 && !app.killedByAm) { 16316 numTrimming++; 16317 } 16318 } 16319 } 16320 16321 mNumServiceProcs = mNewNumServiceProcs; 16322 16323 // Now determine the memory trimming level of background processes. 16324 // Unfortunately we need to start at the back of the list to do this 16325 // properly. We only do this if the number of background apps we 16326 // are managing to keep around is less than half the maximum we desire; 16327 // if we are keeping a good number around, we'll let them use whatever 16328 // memory they want. 16329 final int numCachedAndEmpty = numCached + numEmpty; 16330 int memFactor; 16331 if (numCached <= ProcessList.TRIM_CACHED_APPS 16332 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16333 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16334 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16335 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16336 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16337 } else { 16338 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16339 } 16340 } else { 16341 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16342 } 16343 // We always allow the memory level to go up (better). We only allow it to go 16344 // down if we are in a state where that is allowed, *and* the total number of processes 16345 // has gone down since last time. 16346 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16347 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16348 + " last=" + mLastNumProcesses); 16349 if (memFactor > mLastMemoryLevel) { 16350 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16351 memFactor = mLastMemoryLevel; 16352 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16353 } 16354 } 16355 mLastMemoryLevel = memFactor; 16356 mLastNumProcesses = mLruProcesses.size(); 16357 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16358 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16359 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16360 if (mLowRamStartTime == 0) { 16361 mLowRamStartTime = now; 16362 } 16363 int step = 0; 16364 int fgTrimLevel; 16365 switch (memFactor) { 16366 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16367 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16368 break; 16369 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16370 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16371 break; 16372 default: 16373 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16374 break; 16375 } 16376 int factor = numTrimming/3; 16377 int minFactor = 2; 16378 if (mHomeProcess != null) minFactor++; 16379 if (mPreviousProcess != null) minFactor++; 16380 if (factor < minFactor) factor = minFactor; 16381 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16382 for (int i=N-1; i>=0; i--) { 16383 ProcessRecord app = mLruProcesses.get(i); 16384 if (allChanged || app.procStateChanged) { 16385 setProcessTrackerState(app, trackerMemFactor, now); 16386 app.procStateChanged = false; 16387 } 16388 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16389 && !app.killedByAm) { 16390 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16391 try { 16392 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16393 "Trimming memory of " + app.processName 16394 + " to " + curLevel); 16395 app.thread.scheduleTrimMemory(curLevel); 16396 } catch (RemoteException e) { 16397 } 16398 if (false) { 16399 // For now we won't do this; our memory trimming seems 16400 // to be good enough at this point that destroying 16401 // activities causes more harm than good. 16402 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16403 && app != mHomeProcess && app != mPreviousProcess) { 16404 // Need to do this on its own message because the stack may not 16405 // be in a consistent state at this point. 16406 // For these apps we will also finish their activities 16407 // to help them free memory. 16408 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16409 } 16410 } 16411 } 16412 app.trimMemoryLevel = curLevel; 16413 step++; 16414 if (step >= factor) { 16415 step = 0; 16416 switch (curLevel) { 16417 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16418 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16419 break; 16420 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16421 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16422 break; 16423 } 16424 } 16425 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16426 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16427 && app.thread != null) { 16428 try { 16429 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16430 "Trimming memory of heavy-weight " + app.processName 16431 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16432 app.thread.scheduleTrimMemory( 16433 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16434 } catch (RemoteException e) { 16435 } 16436 } 16437 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16438 } else { 16439 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16440 || app.systemNoUi) && app.pendingUiClean) { 16441 // If this application is now in the background and it 16442 // had done UI, then give it the special trim level to 16443 // have it free UI resources. 16444 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16445 if (app.trimMemoryLevel < level && app.thread != null) { 16446 try { 16447 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16448 "Trimming memory of bg-ui " + app.processName 16449 + " to " + level); 16450 app.thread.scheduleTrimMemory(level); 16451 } catch (RemoteException e) { 16452 } 16453 } 16454 app.pendingUiClean = false; 16455 } 16456 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16457 try { 16458 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16459 "Trimming memory of fg " + app.processName 16460 + " to " + fgTrimLevel); 16461 app.thread.scheduleTrimMemory(fgTrimLevel); 16462 } catch (RemoteException e) { 16463 } 16464 } 16465 app.trimMemoryLevel = fgTrimLevel; 16466 } 16467 } 16468 } else { 16469 if (mLowRamStartTime != 0) { 16470 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16471 mLowRamStartTime = 0; 16472 } 16473 for (int i=N-1; i>=0; i--) { 16474 ProcessRecord app = mLruProcesses.get(i); 16475 if (allChanged || app.procStateChanged) { 16476 setProcessTrackerState(app, trackerMemFactor, now); 16477 app.procStateChanged = false; 16478 } 16479 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16480 || app.systemNoUi) && app.pendingUiClean) { 16481 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16482 && app.thread != null) { 16483 try { 16484 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16485 "Trimming memory of ui hidden " + app.processName 16486 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16487 app.thread.scheduleTrimMemory( 16488 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16489 } catch (RemoteException e) { 16490 } 16491 } 16492 app.pendingUiClean = false; 16493 } 16494 app.trimMemoryLevel = 0; 16495 } 16496 } 16497 16498 if (mAlwaysFinishActivities) { 16499 // Need to do this on its own message because the stack may not 16500 // be in a consistent state at this point. 16501 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16502 } 16503 16504 if (allChanged) { 16505 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16506 } 16507 16508 if (mProcessStats.shouldWriteNowLocked(now)) { 16509 mHandler.post(new Runnable() { 16510 @Override public void run() { 16511 synchronized (ActivityManagerService.this) { 16512 mProcessStats.writeStateAsyncLocked(); 16513 } 16514 } 16515 }); 16516 } 16517 16518 if (DEBUG_OOM_ADJ) { 16519 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16520 } 16521 } 16522 16523 final void trimApplications() { 16524 synchronized (this) { 16525 int i; 16526 16527 // First remove any unused application processes whose package 16528 // has been removed. 16529 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16530 final ProcessRecord app = mRemovedProcesses.get(i); 16531 if (app.activities.size() == 0 16532 && app.curReceiver == null && app.services.size() == 0) { 16533 Slog.i( 16534 TAG, "Exiting empty application process " 16535 + app.processName + " (" 16536 + (app.thread != null ? app.thread.asBinder() : null) 16537 + ")\n"); 16538 if (app.pid > 0 && app.pid != MY_PID) { 16539 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16540 app.processName, app.setAdj, "empty"); 16541 app.killedByAm = true; 16542 Process.killProcessQuiet(app.pid); 16543 } else { 16544 try { 16545 app.thread.scheduleExit(); 16546 } catch (Exception e) { 16547 // Ignore exceptions. 16548 } 16549 } 16550 cleanUpApplicationRecordLocked(app, false, true, -1); 16551 mRemovedProcesses.remove(i); 16552 16553 if (app.persistent) { 16554 addAppLocked(app.info, false, null /* ABI override */); 16555 } 16556 } 16557 } 16558 16559 // Now update the oom adj for all processes. 16560 updateOomAdjLocked(); 16561 } 16562 } 16563 16564 /** This method sends the specified signal to each of the persistent apps */ 16565 public void signalPersistentProcesses(int sig) throws RemoteException { 16566 if (sig != Process.SIGNAL_USR1) { 16567 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16568 } 16569 16570 synchronized (this) { 16571 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16572 != PackageManager.PERMISSION_GRANTED) { 16573 throw new SecurityException("Requires permission " 16574 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16575 } 16576 16577 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16578 ProcessRecord r = mLruProcesses.get(i); 16579 if (r.thread != null && r.persistent) { 16580 Process.sendSignal(r.pid, sig); 16581 } 16582 } 16583 } 16584 } 16585 16586 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16587 if (proc == null || proc == mProfileProc) { 16588 proc = mProfileProc; 16589 path = mProfileFile; 16590 profileType = mProfileType; 16591 clearProfilerLocked(); 16592 } 16593 if (proc == null) { 16594 return; 16595 } 16596 try { 16597 proc.thread.profilerControl(false, path, null, profileType); 16598 } catch (RemoteException e) { 16599 throw new IllegalStateException("Process disappeared"); 16600 } 16601 } 16602 16603 private void clearProfilerLocked() { 16604 if (mProfileFd != null) { 16605 try { 16606 mProfileFd.close(); 16607 } catch (IOException e) { 16608 } 16609 } 16610 mProfileApp = null; 16611 mProfileProc = null; 16612 mProfileFile = null; 16613 mProfileType = 0; 16614 mAutoStopProfiler = false; 16615 } 16616 16617 public boolean profileControl(String process, int userId, boolean start, 16618 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16619 16620 try { 16621 synchronized (this) { 16622 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16623 // its own permission. 16624 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16625 != PackageManager.PERMISSION_GRANTED) { 16626 throw new SecurityException("Requires permission " 16627 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16628 } 16629 16630 if (start && fd == null) { 16631 throw new IllegalArgumentException("null fd"); 16632 } 16633 16634 ProcessRecord proc = null; 16635 if (process != null) { 16636 proc = findProcessLocked(process, userId, "profileControl"); 16637 } 16638 16639 if (start && (proc == null || proc.thread == null)) { 16640 throw new IllegalArgumentException("Unknown process: " + process); 16641 } 16642 16643 if (start) { 16644 stopProfilerLocked(null, null, 0); 16645 setProfileApp(proc.info, proc.processName, path, fd, false); 16646 mProfileProc = proc; 16647 mProfileType = profileType; 16648 try { 16649 fd = fd.dup(); 16650 } catch (IOException e) { 16651 fd = null; 16652 } 16653 proc.thread.profilerControl(start, path, fd, profileType); 16654 fd = null; 16655 mProfileFd = null; 16656 } else { 16657 stopProfilerLocked(proc, path, profileType); 16658 if (fd != null) { 16659 try { 16660 fd.close(); 16661 } catch (IOException e) { 16662 } 16663 } 16664 } 16665 16666 return true; 16667 } 16668 } catch (RemoteException e) { 16669 throw new IllegalStateException("Process disappeared"); 16670 } finally { 16671 if (fd != null) { 16672 try { 16673 fd.close(); 16674 } catch (IOException e) { 16675 } 16676 } 16677 } 16678 } 16679 16680 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16681 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16682 userId, true, true, callName, null); 16683 ProcessRecord proc = null; 16684 try { 16685 int pid = Integer.parseInt(process); 16686 synchronized (mPidsSelfLocked) { 16687 proc = mPidsSelfLocked.get(pid); 16688 } 16689 } catch (NumberFormatException e) { 16690 } 16691 16692 if (proc == null) { 16693 ArrayMap<String, SparseArray<ProcessRecord>> all 16694 = mProcessNames.getMap(); 16695 SparseArray<ProcessRecord> procs = all.get(process); 16696 if (procs != null && procs.size() > 0) { 16697 proc = procs.valueAt(0); 16698 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16699 for (int i=1; i<procs.size(); i++) { 16700 ProcessRecord thisProc = procs.valueAt(i); 16701 if (thisProc.userId == userId) { 16702 proc = thisProc; 16703 break; 16704 } 16705 } 16706 } 16707 } 16708 } 16709 16710 return proc; 16711 } 16712 16713 public boolean dumpHeap(String process, int userId, boolean managed, 16714 String path, ParcelFileDescriptor fd) throws RemoteException { 16715 16716 try { 16717 synchronized (this) { 16718 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16719 // its own permission (same as profileControl). 16720 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16721 != PackageManager.PERMISSION_GRANTED) { 16722 throw new SecurityException("Requires permission " 16723 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16724 } 16725 16726 if (fd == null) { 16727 throw new IllegalArgumentException("null fd"); 16728 } 16729 16730 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16731 if (proc == null || proc.thread == null) { 16732 throw new IllegalArgumentException("Unknown process: " + process); 16733 } 16734 16735 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16736 if (!isDebuggable) { 16737 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16738 throw new SecurityException("Process not debuggable: " + proc); 16739 } 16740 } 16741 16742 proc.thread.dumpHeap(managed, path, fd); 16743 fd = null; 16744 return true; 16745 } 16746 } catch (RemoteException e) { 16747 throw new IllegalStateException("Process disappeared"); 16748 } finally { 16749 if (fd != null) { 16750 try { 16751 fd.close(); 16752 } catch (IOException e) { 16753 } 16754 } 16755 } 16756 } 16757 16758 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16759 public void monitor() { 16760 synchronized (this) { } 16761 } 16762 16763 void onCoreSettingsChange(Bundle settings) { 16764 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16765 ProcessRecord processRecord = mLruProcesses.get(i); 16766 try { 16767 if (processRecord.thread != null) { 16768 processRecord.thread.setCoreSettings(settings); 16769 } 16770 } catch (RemoteException re) { 16771 /* ignore */ 16772 } 16773 } 16774 } 16775 16776 // Multi-user methods 16777 16778 /** 16779 * Start user, if its not already running, but don't bring it to foreground. 16780 */ 16781 @Override 16782 public boolean startUserInBackground(final int userId) { 16783 return startUser(userId, /* foreground */ false); 16784 } 16785 16786 /** 16787 * Refreshes the list of users related to the current user when either a 16788 * user switch happens or when a new related user is started in the 16789 * background. 16790 */ 16791 private void updateCurrentProfileIdsLocked() { 16792 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16793 mCurrentUserId, false /* enabledOnly */); 16794 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16795 for (int i = 0; i < currentProfileIds.length; i++) { 16796 currentProfileIds[i] = profiles.get(i).id; 16797 } 16798 mCurrentProfileIds = currentProfileIds; 16799 } 16800 16801 private Set getProfileIdsLocked(int userId) { 16802 Set userIds = new HashSet<Integer>(); 16803 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16804 userId, false /* enabledOnly */); 16805 for (UserInfo user : profiles) { 16806 userIds.add(Integer.valueOf(user.id)); 16807 } 16808 return userIds; 16809 } 16810 16811 @Override 16812 public boolean switchUser(final int userId) { 16813 return startUser(userId, /* foregound */ true); 16814 } 16815 16816 private boolean startUser(final int userId, boolean foreground) { 16817 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16818 != PackageManager.PERMISSION_GRANTED) { 16819 String msg = "Permission Denial: switchUser() from pid=" 16820 + Binder.getCallingPid() 16821 + ", uid=" + Binder.getCallingUid() 16822 + " requires " + INTERACT_ACROSS_USERS_FULL; 16823 Slog.w(TAG, msg); 16824 throw new SecurityException(msg); 16825 } 16826 16827 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16828 16829 final long ident = Binder.clearCallingIdentity(); 16830 try { 16831 synchronized (this) { 16832 final int oldUserId = mCurrentUserId; 16833 if (oldUserId == userId) { 16834 return true; 16835 } 16836 16837 mStackSupervisor.setLockTaskModeLocked(null, false); 16838 16839 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16840 if (userInfo == null) { 16841 Slog.w(TAG, "No user info for user #" + userId); 16842 return false; 16843 } 16844 16845 if (foreground) { 16846 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16847 R.anim.screen_user_enter); 16848 } 16849 16850 boolean needStart = false; 16851 16852 // If the user we are switching to is not currently started, then 16853 // we need to start it now. 16854 if (mStartedUsers.get(userId) == null) { 16855 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16856 updateStartedUserArrayLocked(); 16857 needStart = true; 16858 } 16859 16860 final Integer userIdInt = Integer.valueOf(userId); 16861 mUserLru.remove(userIdInt); 16862 mUserLru.add(userIdInt); 16863 16864 if (foreground) { 16865 mCurrentUserId = userId; 16866 updateCurrentProfileIdsLocked(); 16867 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16868 // Once the internal notion of the active user has switched, we lock the device 16869 // with the option to show the user switcher on the keyguard. 16870 mWindowManager.lockNow(null); 16871 } else { 16872 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16873 updateCurrentProfileIdsLocked(); 16874 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16875 mUserLru.remove(currentUserIdInt); 16876 mUserLru.add(currentUserIdInt); 16877 } 16878 16879 final UserStartedState uss = mStartedUsers.get(userId); 16880 16881 // Make sure user is in the started state. If it is currently 16882 // stopping, we need to knock that off. 16883 if (uss.mState == UserStartedState.STATE_STOPPING) { 16884 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16885 // so we can just fairly silently bring the user back from 16886 // the almost-dead. 16887 uss.mState = UserStartedState.STATE_RUNNING; 16888 updateStartedUserArrayLocked(); 16889 needStart = true; 16890 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16891 // This means ACTION_SHUTDOWN has been sent, so we will 16892 // need to treat this as a new boot of the user. 16893 uss.mState = UserStartedState.STATE_BOOTING; 16894 updateStartedUserArrayLocked(); 16895 needStart = true; 16896 } 16897 16898 if (uss.mState == UserStartedState.STATE_BOOTING) { 16899 // Booting up a new user, need to tell system services about it. 16900 // Note that this is on the same handler as scheduling of broadcasts, 16901 // which is important because it needs to go first. 16902 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16903 } 16904 16905 if (foreground) { 16906 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16907 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16908 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16909 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16910 oldUserId, userId, uss)); 16911 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16912 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16913 } 16914 16915 if (needStart) { 16916 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16917 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16918 | Intent.FLAG_RECEIVER_FOREGROUND); 16919 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16920 broadcastIntentLocked(null, null, intent, 16921 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16922 false, false, MY_PID, Process.SYSTEM_UID, userId); 16923 } 16924 16925 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16926 if (userId != UserHandle.USER_OWNER) { 16927 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16928 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16929 broadcastIntentLocked(null, null, intent, null, 16930 new IIntentReceiver.Stub() { 16931 public void performReceive(Intent intent, int resultCode, 16932 String data, Bundle extras, boolean ordered, 16933 boolean sticky, int sendingUser) { 16934 userInitialized(uss, userId); 16935 } 16936 }, 0, null, null, null, AppOpsManager.OP_NONE, 16937 true, false, MY_PID, Process.SYSTEM_UID, 16938 userId); 16939 uss.initializing = true; 16940 } else { 16941 getUserManagerLocked().makeInitialized(userInfo.id); 16942 } 16943 } 16944 16945 if (foreground) { 16946 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16947 if (homeInFront) { 16948 startHomeActivityLocked(userId); 16949 } else { 16950 mStackSupervisor.resumeTopActivitiesLocked(); 16951 } 16952 EventLogTags.writeAmSwitchUser(userId); 16953 getUserManagerLocked().userForeground(userId); 16954 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16955 } else { 16956 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16957 } 16958 16959 if (needStart) { 16960 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16961 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16962 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16963 broadcastIntentLocked(null, null, intent, 16964 null, new IIntentReceiver.Stub() { 16965 @Override 16966 public void performReceive(Intent intent, int resultCode, String data, 16967 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16968 throws RemoteException { 16969 } 16970 }, 0, null, null, 16971 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16972 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16973 } 16974 } 16975 } finally { 16976 Binder.restoreCallingIdentity(ident); 16977 } 16978 16979 return true; 16980 } 16981 16982 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16983 long ident = Binder.clearCallingIdentity(); 16984 try { 16985 Intent intent; 16986 if (oldUserId >= 0) { 16987 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16988 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16989 | Intent.FLAG_RECEIVER_FOREGROUND); 16990 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16991 broadcastIntentLocked(null, null, intent, 16992 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16993 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16994 } 16995 if (newUserId >= 0) { 16996 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16997 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16998 | Intent.FLAG_RECEIVER_FOREGROUND); 16999 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17000 broadcastIntentLocked(null, null, intent, 17001 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17002 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 17003 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17004 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17005 | Intent.FLAG_RECEIVER_FOREGROUND); 17006 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17007 broadcastIntentLocked(null, null, intent, 17008 null, null, 0, null, null, 17009 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17010 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17011 } 17012 } finally { 17013 Binder.restoreCallingIdentity(ident); 17014 } 17015 } 17016 17017 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17018 final int newUserId) { 17019 final int N = mUserSwitchObservers.beginBroadcast(); 17020 if (N > 0) { 17021 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17022 int mCount = 0; 17023 @Override 17024 public void sendResult(Bundle data) throws RemoteException { 17025 synchronized (ActivityManagerService.this) { 17026 if (mCurUserSwitchCallback == this) { 17027 mCount++; 17028 if (mCount == N) { 17029 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17030 } 17031 } 17032 } 17033 } 17034 }; 17035 synchronized (this) { 17036 uss.switching = true; 17037 mCurUserSwitchCallback = callback; 17038 } 17039 for (int i=0; i<N; i++) { 17040 try { 17041 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17042 newUserId, callback); 17043 } catch (RemoteException e) { 17044 } 17045 } 17046 } else { 17047 synchronized (this) { 17048 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17049 } 17050 } 17051 mUserSwitchObservers.finishBroadcast(); 17052 } 17053 17054 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17055 synchronized (this) { 17056 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17057 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17058 } 17059 } 17060 17061 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17062 mCurUserSwitchCallback = null; 17063 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17064 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17065 oldUserId, newUserId, uss)); 17066 } 17067 17068 void userInitialized(UserStartedState uss, int newUserId) { 17069 completeSwitchAndInitalize(uss, newUserId, true, false); 17070 } 17071 17072 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17073 completeSwitchAndInitalize(uss, newUserId, false, true); 17074 } 17075 17076 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17077 boolean clearInitializing, boolean clearSwitching) { 17078 boolean unfrozen = false; 17079 synchronized (this) { 17080 if (clearInitializing) { 17081 uss.initializing = false; 17082 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17083 } 17084 if (clearSwitching) { 17085 uss.switching = false; 17086 } 17087 if (!uss.switching && !uss.initializing) { 17088 mWindowManager.stopFreezingScreen(); 17089 unfrozen = true; 17090 } 17091 } 17092 if (unfrozen) { 17093 final int N = mUserSwitchObservers.beginBroadcast(); 17094 for (int i=0; i<N; i++) { 17095 try { 17096 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17097 } catch (RemoteException e) { 17098 } 17099 } 17100 mUserSwitchObservers.finishBroadcast(); 17101 } 17102 } 17103 17104 void scheduleStartProfilesLocked() { 17105 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17106 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17107 DateUtils.SECOND_IN_MILLIS); 17108 } 17109 } 17110 17111 void startProfilesLocked() { 17112 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17113 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17114 mCurrentUserId, false /* enabledOnly */); 17115 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17116 for (UserInfo user : profiles) { 17117 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17118 && user.id != mCurrentUserId) { 17119 toStart.add(user); 17120 } 17121 } 17122 final int n = toStart.size(); 17123 int i = 0; 17124 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17125 startUserInBackground(toStart.get(i).id); 17126 } 17127 if (i < n) { 17128 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17129 } 17130 } 17131 17132 void finishUserBoot(UserStartedState uss) { 17133 synchronized (this) { 17134 if (uss.mState == UserStartedState.STATE_BOOTING 17135 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17136 uss.mState = UserStartedState.STATE_RUNNING; 17137 final int userId = uss.mHandle.getIdentifier(); 17138 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17139 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17140 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17141 broadcastIntentLocked(null, null, intent, 17142 null, null, 0, null, null, 17143 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17144 true, false, MY_PID, Process.SYSTEM_UID, userId); 17145 } 17146 } 17147 } 17148 17149 void finishUserSwitch(UserStartedState uss) { 17150 synchronized (this) { 17151 finishUserBoot(uss); 17152 17153 startProfilesLocked(); 17154 17155 int num = mUserLru.size(); 17156 int i = 0; 17157 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17158 Integer oldUserId = mUserLru.get(i); 17159 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17160 if (oldUss == null) { 17161 // Shouldn't happen, but be sane if it does. 17162 mUserLru.remove(i); 17163 num--; 17164 continue; 17165 } 17166 if (oldUss.mState == UserStartedState.STATE_STOPPING 17167 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17168 // This user is already stopping, doesn't count. 17169 num--; 17170 i++; 17171 continue; 17172 } 17173 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17174 // Owner and current can't be stopped, but count as running. 17175 i++; 17176 continue; 17177 } 17178 // This is a user to be stopped. 17179 stopUserLocked(oldUserId, null); 17180 num--; 17181 i++; 17182 } 17183 } 17184 } 17185 17186 @Override 17187 public int stopUser(final int userId, final IStopUserCallback callback) { 17188 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17189 != PackageManager.PERMISSION_GRANTED) { 17190 String msg = "Permission Denial: switchUser() from pid=" 17191 + Binder.getCallingPid() 17192 + ", uid=" + Binder.getCallingUid() 17193 + " requires " + INTERACT_ACROSS_USERS_FULL; 17194 Slog.w(TAG, msg); 17195 throw new SecurityException(msg); 17196 } 17197 if (userId <= 0) { 17198 throw new IllegalArgumentException("Can't stop primary user " + userId); 17199 } 17200 synchronized (this) { 17201 return stopUserLocked(userId, callback); 17202 } 17203 } 17204 17205 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17206 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17207 if (mCurrentUserId == userId) { 17208 return ActivityManager.USER_OP_IS_CURRENT; 17209 } 17210 17211 final UserStartedState uss = mStartedUsers.get(userId); 17212 if (uss == null) { 17213 // User is not started, nothing to do... but we do need to 17214 // callback if requested. 17215 if (callback != null) { 17216 mHandler.post(new Runnable() { 17217 @Override 17218 public void run() { 17219 try { 17220 callback.userStopped(userId); 17221 } catch (RemoteException e) { 17222 } 17223 } 17224 }); 17225 } 17226 return ActivityManager.USER_OP_SUCCESS; 17227 } 17228 17229 if (callback != null) { 17230 uss.mStopCallbacks.add(callback); 17231 } 17232 17233 if (uss.mState != UserStartedState.STATE_STOPPING 17234 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17235 uss.mState = UserStartedState.STATE_STOPPING; 17236 updateStartedUserArrayLocked(); 17237 17238 long ident = Binder.clearCallingIdentity(); 17239 try { 17240 // We are going to broadcast ACTION_USER_STOPPING and then 17241 // once that is done send a final ACTION_SHUTDOWN and then 17242 // stop the user. 17243 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17244 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17245 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17246 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17247 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17248 // This is the result receiver for the final shutdown broadcast. 17249 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17250 @Override 17251 public void performReceive(Intent intent, int resultCode, String data, 17252 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17253 finishUserStop(uss); 17254 } 17255 }; 17256 // This is the result receiver for the initial stopping broadcast. 17257 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17258 @Override 17259 public void performReceive(Intent intent, int resultCode, String data, 17260 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17261 // On to the next. 17262 synchronized (ActivityManagerService.this) { 17263 if (uss.mState != UserStartedState.STATE_STOPPING) { 17264 // Whoops, we are being started back up. Abort, abort! 17265 return; 17266 } 17267 uss.mState = UserStartedState.STATE_SHUTDOWN; 17268 } 17269 mSystemServiceManager.stopUser(userId); 17270 broadcastIntentLocked(null, null, shutdownIntent, 17271 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17272 true, false, MY_PID, Process.SYSTEM_UID, userId); 17273 } 17274 }; 17275 // Kick things off. 17276 broadcastIntentLocked(null, null, stoppingIntent, 17277 null, stoppingReceiver, 0, null, null, 17278 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17279 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17280 } finally { 17281 Binder.restoreCallingIdentity(ident); 17282 } 17283 } 17284 17285 return ActivityManager.USER_OP_SUCCESS; 17286 } 17287 17288 void finishUserStop(UserStartedState uss) { 17289 final int userId = uss.mHandle.getIdentifier(); 17290 boolean stopped; 17291 ArrayList<IStopUserCallback> callbacks; 17292 synchronized (this) { 17293 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17294 if (mStartedUsers.get(userId) != uss) { 17295 stopped = false; 17296 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17297 stopped = false; 17298 } else { 17299 stopped = true; 17300 // User can no longer run. 17301 mStartedUsers.remove(userId); 17302 mUserLru.remove(Integer.valueOf(userId)); 17303 updateStartedUserArrayLocked(); 17304 17305 // Clean up all state and processes associated with the user. 17306 // Kill all the processes for the user. 17307 forceStopUserLocked(userId, "finish user"); 17308 } 17309 } 17310 17311 for (int i=0; i<callbacks.size(); i++) { 17312 try { 17313 if (stopped) callbacks.get(i).userStopped(userId); 17314 else callbacks.get(i).userStopAborted(userId); 17315 } catch (RemoteException e) { 17316 } 17317 } 17318 17319 if (stopped) { 17320 mSystemServiceManager.cleanupUser(userId); 17321 synchronized (this) { 17322 mStackSupervisor.removeUserLocked(userId); 17323 } 17324 } 17325 } 17326 17327 @Override 17328 public UserInfo getCurrentUser() { 17329 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17330 != PackageManager.PERMISSION_GRANTED) && ( 17331 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17332 != PackageManager.PERMISSION_GRANTED)) { 17333 String msg = "Permission Denial: getCurrentUser() from pid=" 17334 + Binder.getCallingPid() 17335 + ", uid=" + Binder.getCallingUid() 17336 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17337 Slog.w(TAG, msg); 17338 throw new SecurityException(msg); 17339 } 17340 synchronized (this) { 17341 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17342 } 17343 } 17344 17345 int getCurrentUserIdLocked() { 17346 return mCurrentUserId; 17347 } 17348 17349 @Override 17350 public boolean isUserRunning(int userId, boolean orStopped) { 17351 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17352 != PackageManager.PERMISSION_GRANTED) { 17353 String msg = "Permission Denial: isUserRunning() from pid=" 17354 + Binder.getCallingPid() 17355 + ", uid=" + Binder.getCallingUid() 17356 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17357 Slog.w(TAG, msg); 17358 throw new SecurityException(msg); 17359 } 17360 synchronized (this) { 17361 return isUserRunningLocked(userId, orStopped); 17362 } 17363 } 17364 17365 boolean isUserRunningLocked(int userId, boolean orStopped) { 17366 UserStartedState state = mStartedUsers.get(userId); 17367 if (state == null) { 17368 return false; 17369 } 17370 if (orStopped) { 17371 return true; 17372 } 17373 return state.mState != UserStartedState.STATE_STOPPING 17374 && state.mState != UserStartedState.STATE_SHUTDOWN; 17375 } 17376 17377 @Override 17378 public int[] getRunningUserIds() { 17379 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17380 != PackageManager.PERMISSION_GRANTED) { 17381 String msg = "Permission Denial: isUserRunning() from pid=" 17382 + Binder.getCallingPid() 17383 + ", uid=" + Binder.getCallingUid() 17384 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17385 Slog.w(TAG, msg); 17386 throw new SecurityException(msg); 17387 } 17388 synchronized (this) { 17389 return mStartedUserArray; 17390 } 17391 } 17392 17393 private void updateStartedUserArrayLocked() { 17394 int num = 0; 17395 for (int i=0; i<mStartedUsers.size(); i++) { 17396 UserStartedState uss = mStartedUsers.valueAt(i); 17397 // This list does not include stopping users. 17398 if (uss.mState != UserStartedState.STATE_STOPPING 17399 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17400 num++; 17401 } 17402 } 17403 mStartedUserArray = new int[num]; 17404 num = 0; 17405 for (int i=0; i<mStartedUsers.size(); i++) { 17406 UserStartedState uss = mStartedUsers.valueAt(i); 17407 if (uss.mState != UserStartedState.STATE_STOPPING 17408 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17409 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17410 num++; 17411 } 17412 } 17413 } 17414 17415 @Override 17416 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17417 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17418 != PackageManager.PERMISSION_GRANTED) { 17419 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17420 + Binder.getCallingPid() 17421 + ", uid=" + Binder.getCallingUid() 17422 + " requires " + INTERACT_ACROSS_USERS_FULL; 17423 Slog.w(TAG, msg); 17424 throw new SecurityException(msg); 17425 } 17426 17427 mUserSwitchObservers.register(observer); 17428 } 17429 17430 @Override 17431 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17432 mUserSwitchObservers.unregister(observer); 17433 } 17434 17435 private boolean userExists(int userId) { 17436 if (userId == 0) { 17437 return true; 17438 } 17439 UserManagerService ums = getUserManagerLocked(); 17440 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17441 } 17442 17443 int[] getUsersLocked() { 17444 UserManagerService ums = getUserManagerLocked(); 17445 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17446 } 17447 17448 UserManagerService getUserManagerLocked() { 17449 if (mUserManager == null) { 17450 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17451 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17452 } 17453 return mUserManager; 17454 } 17455 17456 private int applyUserId(int uid, int userId) { 17457 return UserHandle.getUid(userId, uid); 17458 } 17459 17460 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17461 if (info == null) return null; 17462 ApplicationInfo newInfo = new ApplicationInfo(info); 17463 newInfo.uid = applyUserId(info.uid, userId); 17464 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17465 + info.packageName; 17466 return newInfo; 17467 } 17468 17469 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17470 if (aInfo == null 17471 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17472 return aInfo; 17473 } 17474 17475 ActivityInfo info = new ActivityInfo(aInfo); 17476 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17477 return info; 17478 } 17479 17480 private final class LocalService extends ActivityManagerInternal { 17481 @Override 17482 public void goingToSleep() { 17483 ActivityManagerService.this.goingToSleep(); 17484 } 17485 17486 @Override 17487 public void wakingUp() { 17488 ActivityManagerService.this.wakingUp(); 17489 } 17490 } 17491 17492 /** 17493 * An implementation of IAppTask, that allows an app to manage its own tasks via 17494 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17495 * only the process that calls getAppTasks() can call the AppTask methods. 17496 */ 17497 class AppTaskImpl extends IAppTask.Stub { 17498 private int mTaskId; 17499 private int mCallingUid; 17500 17501 public AppTaskImpl(int taskId, int callingUid) { 17502 mTaskId = taskId; 17503 mCallingUid = callingUid; 17504 } 17505 17506 @Override 17507 public void finishAndRemoveTask() { 17508 // Ensure that we are called from the same process that created this AppTask 17509 if (mCallingUid != Binder.getCallingUid()) { 17510 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17511 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17512 return; 17513 } 17514 17515 synchronized (ActivityManagerService.this) { 17516 long origId = Binder.clearCallingIdentity(); 17517 try { 17518 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17519 if (tr != null) { 17520 // Only kill the process if we are not a new document 17521 int flags = tr.getBaseIntent().getFlags(); 17522 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17523 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17524 removeTaskByIdLocked(mTaskId, 17525 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17526 } 17527 } finally { 17528 Binder.restoreCallingIdentity(origId); 17529 } 17530 } 17531 } 17532 17533 @Override 17534 public ActivityManager.RecentTaskInfo getTaskInfo() { 17535 // Ensure that we are called from the same process that created this AppTask 17536 if (mCallingUid != Binder.getCallingUid()) { 17537 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17538 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17539 return null; 17540 } 17541 17542 synchronized (ActivityManagerService.this) { 17543 long origId = Binder.clearCallingIdentity(); 17544 try { 17545 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17546 if (tr != null) { 17547 return createRecentTaskInfoFromTaskRecord(tr); 17548 } 17549 } finally { 17550 Binder.restoreCallingIdentity(origId); 17551 } 17552 return null; 17553 } 17554 } 17555 } 17556} 17557