ActivityManagerService.java revision 80f74b544975900fa69fa078d424fa5cde9ad5c7
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.content.DialogInterface.OnClickListener; 40import android.content.res.Resources; 41import android.graphics.BitmapFactory; 42import android.graphics.Rect; 43import android.os.BatteryStats; 44import android.os.PersistableBundle; 45import android.service.voice.IVoiceInteractionSession; 46import android.util.ArrayMap; 47 48import com.android.internal.R; 49import com.android.internal.annotations.GuardedBy; 50import com.android.internal.app.IAppOpsService; 51import com.android.internal.app.IVoiceInteractor; 52import com.android.internal.app.ProcessMap; 53import com.android.internal.app.ProcessStats; 54import com.android.internal.content.PackageMonitor; 55import com.android.internal.os.BackgroundThread; 56import com.android.internal.os.BatteryStatsImpl; 57import com.android.internal.os.ProcessCpuTracker; 58import com.android.internal.os.TransferPipe; 59import com.android.internal.os.Zygote; 60import com.android.internal.util.FastPrintWriter; 61import com.android.internal.util.FastXmlSerializer; 62import com.android.internal.util.MemInfoReader; 63import com.android.internal.util.Preconditions; 64import com.android.server.AppOpsService; 65import com.android.server.AttributeCache; 66import com.android.server.IntentResolver; 67import com.android.server.LocalServices; 68import com.android.server.ServiceThread; 69import com.android.server.SystemService; 70import com.android.server.SystemServiceManager; 71import com.android.server.Watchdog; 72import com.android.server.am.ActivityStack.ActivityState; 73import com.android.server.firewall.IntentFirewall; 74import com.android.server.pm.UserManagerService; 75import com.android.server.wm.AppTransition; 76import com.android.server.wm.WindowManagerService; 77import com.google.android.collect.Lists; 78import com.google.android.collect.Maps; 79 80import libcore.io.IoUtils; 81 82import org.xmlpull.v1.XmlPullParser; 83import org.xmlpull.v1.XmlPullParserException; 84import org.xmlpull.v1.XmlSerializer; 85 86import android.app.Activity; 87import android.app.ActivityManager; 88import android.app.ActivityManager.RunningTaskInfo; 89import android.app.ActivityManager.StackInfo; 90import android.app.ActivityManagerInternal; 91import android.app.ActivityManagerNative; 92import android.app.ActivityOptions; 93import android.app.ActivityThread; 94import android.app.AlertDialog; 95import android.app.AppGlobals; 96import android.app.ApplicationErrorReport; 97import android.app.Dialog; 98import android.app.IActivityController; 99import android.app.IApplicationThread; 100import android.app.IInstrumentationWatcher; 101import android.app.INotificationManager; 102import android.app.IProcessObserver; 103import android.app.IServiceConnection; 104import android.app.IStopUserCallback; 105import android.app.IUiAutomationConnection; 106import android.app.IUserSwitchObserver; 107import android.app.Instrumentation; 108import android.app.Notification; 109import android.app.NotificationManager; 110import android.app.PendingIntent; 111import android.app.backup.IBackupManager; 112import android.content.ActivityNotFoundException; 113import android.content.BroadcastReceiver; 114import android.content.ClipData; 115import android.content.ComponentCallbacks2; 116import android.content.ComponentName; 117import android.content.ContentProvider; 118import android.content.ContentResolver; 119import android.content.Context; 120import android.content.DialogInterface; 121import android.content.IContentProvider; 122import android.content.IIntentReceiver; 123import android.content.IIntentSender; 124import android.content.Intent; 125import android.content.IntentFilter; 126import android.content.IntentSender; 127import android.content.pm.ActivityInfo; 128import android.content.pm.ApplicationInfo; 129import android.content.pm.ConfigurationInfo; 130import android.content.pm.IPackageDataObserver; 131import android.content.pm.IPackageManager; 132import android.content.pm.InstrumentationInfo; 133import android.content.pm.PackageInfo; 134import android.content.pm.PackageManager; 135import android.content.pm.ParceledListSlice; 136import android.content.pm.UserInfo; 137import android.content.pm.PackageManager.NameNotFoundException; 138import android.content.pm.PathPermission; 139import android.content.pm.ProviderInfo; 140import android.content.pm.ResolveInfo; 141import android.content.pm.ServiceInfo; 142import android.content.res.CompatibilityInfo; 143import android.content.res.Configuration; 144import android.graphics.Bitmap; 145import android.net.Proxy; 146import android.net.ProxyInfo; 147import android.net.Uri; 148import android.os.Binder; 149import android.os.Build; 150import android.os.Bundle; 151import android.os.Debug; 152import android.os.DropBoxManager; 153import android.os.Environment; 154import android.os.FactoryTest; 155import android.os.FileObserver; 156import android.os.FileUtils; 157import android.os.Handler; 158import android.os.IBinder; 159import android.os.IPermissionController; 160import android.os.IRemoteCallback; 161import android.os.IUserManager; 162import android.os.Looper; 163import android.os.Message; 164import android.os.Parcel; 165import android.os.ParcelFileDescriptor; 166import android.os.Process; 167import android.os.RemoteCallbackList; 168import android.os.RemoteException; 169import android.os.SELinux; 170import android.os.ServiceManager; 171import android.os.StrictMode; 172import android.os.SystemClock; 173import android.os.SystemProperties; 174import android.os.UpdateLock; 175import android.os.UserHandle; 176import android.provider.Settings; 177import android.text.Spannable; 178import android.text.SpannableString; 179import android.text.format.DateUtils; 180import android.text.format.Time; 181import android.text.style.DynamicDrawableSpan; 182import android.text.style.ImageSpan; 183import android.util.AtomicFile; 184import android.util.EventLog; 185import android.util.Log; 186import android.util.Pair; 187import android.util.PrintWriterPrinter; 188import android.util.Slog; 189import android.util.SparseArray; 190import android.util.TimeUtils; 191import android.util.Xml; 192import android.view.Gravity; 193import android.view.LayoutInflater; 194import android.view.View; 195import android.view.WindowManager; 196import android.widget.TextView; 197 198import java.io.BufferedInputStream; 199import java.io.BufferedOutputStream; 200import java.io.DataInputStream; 201import java.io.DataOutputStream; 202import java.io.File; 203import java.io.FileDescriptor; 204import java.io.FileInputStream; 205import java.io.FileNotFoundException; 206import java.io.FileOutputStream; 207import java.io.IOException; 208import java.io.InputStreamReader; 209import java.io.PrintWriter; 210import java.io.StringWriter; 211import java.lang.ref.WeakReference; 212import java.util.ArrayList; 213import java.util.Arrays; 214import java.util.Collections; 215import java.util.Comparator; 216import java.util.HashMap; 217import java.util.HashSet; 218import java.util.Iterator; 219import java.util.List; 220import java.util.Locale; 221import java.util.Map; 222import java.util.Set; 223import java.util.concurrent.atomic.AtomicBoolean; 224import java.util.concurrent.atomic.AtomicLong; 225 226public final class ActivityManagerService extends ActivityManagerNative 227 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 228 private static final String USER_DATA_DIR = "/data/user/"; 229 static final String TAG = "ActivityManager"; 230 static final String TAG_MU = "ActivityManagerServiceMU"; 231 static final boolean DEBUG = false; 232 static final boolean localLOGV = DEBUG; 233 static final boolean DEBUG_BACKUP = localLOGV || false; 234 static final boolean DEBUG_BROADCAST = localLOGV || false; 235 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 236 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 237 static final boolean DEBUG_CLEANUP = localLOGV || false; 238 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 239 static final boolean DEBUG_FOCUS = false; 240 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 241 static final boolean DEBUG_MU = localLOGV || false; 242 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 243 static final boolean DEBUG_LRU = localLOGV || false; 244 static final boolean DEBUG_PAUSE = localLOGV || false; 245 static final boolean DEBUG_POWER = localLOGV || false; 246 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 247 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 248 static final boolean DEBUG_PROCESSES = localLOGV || false; 249 static final boolean DEBUG_PROVIDER = localLOGV || false; 250 static final boolean DEBUG_RESULTS = localLOGV || false; 251 static final boolean DEBUG_SERVICE = localLOGV || false; 252 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 253 static final boolean DEBUG_STACK = localLOGV || false; 254 static final boolean DEBUG_SWITCH = localLOGV || false; 255 static final boolean DEBUG_TASKS = localLOGV || false; 256 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 257 static final boolean DEBUG_TRANSITION = localLOGV || false; 258 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 259 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 260 static final boolean DEBUG_VISBILITY = localLOGV || false; 261 static final boolean DEBUG_PSS = localLOGV || false; 262 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 263 static final boolean VALIDATE_TOKENS = false; 264 static final boolean SHOW_ACTIVITY_START_TIME = true; 265 266 // Control over CPU and battery monitoring. 267 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 268 static final boolean MONITOR_CPU_USAGE = true; 269 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 270 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 271 static final boolean MONITOR_THREAD_CPU_USAGE = false; 272 273 // The flags that are set for all calls we make to the package manager. 274 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 275 276 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 277 278 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 279 280 // Maximum number of recent tasks that we can remember. 281 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200; 282 283 // Amount of time after a call to stopAppSwitches() during which we will 284 // prevent further untrusted switches from happening. 285 static final long APP_SWITCH_DELAY_TIME = 5*1000; 286 287 // How long we wait for a launched process to attach to the activity manager 288 // before we decide it's never going to come up for real. 289 static final int PROC_START_TIMEOUT = 10*1000; 290 291 // How long we wait for a launched process to attach to the activity manager 292 // before we decide it's never going to come up for real, when the process was 293 // started with a wrapper for instrumentation (such as Valgrind) because it 294 // could take much longer than usual. 295 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 296 297 // How long to wait after going idle before forcing apps to GC. 298 static final int GC_TIMEOUT = 5*1000; 299 300 // The minimum amount of time between successive GC requests for a process. 301 static final int GC_MIN_INTERVAL = 60*1000; 302 303 // The minimum amount of time between successive PSS requests for a process. 304 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 305 306 // The minimum amount of time between successive PSS requests for a process 307 // when the request is due to the memory state being lowered. 308 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 309 310 // The rate at which we check for apps using excessive power -- 15 mins. 311 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 312 313 // The minimum sample duration we will allow before deciding we have 314 // enough data on wake locks to start killing things. 315 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 316 317 // The minimum sample duration we will allow before deciding we have 318 // enough data on CPU usage to start killing things. 319 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 320 321 // How long we allow a receiver to run before giving up on it. 322 static final int BROADCAST_FG_TIMEOUT = 10*1000; 323 static final int BROADCAST_BG_TIMEOUT = 60*1000; 324 325 // How long we wait until we timeout on key dispatching. 326 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 327 328 // How long we wait until we timeout on key dispatching during instrumentation. 329 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 330 331 // Amount of time we wait for observers to handle a user switch before 332 // giving up on them and unfreezing the screen. 333 static final int USER_SWITCH_TIMEOUT = 2*1000; 334 335 // Maximum number of users we allow to be running at a time. 336 static final int MAX_RUNNING_USERS = 3; 337 338 // How long to wait in getAssistContextExtras for the activity and foreground services 339 // to respond with the result. 340 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 341 342 // Maximum number of persisted Uri grants a package is allowed 343 static final int MAX_PERSISTED_URI_GRANTS = 128; 344 345 static final int MY_PID = Process.myPid(); 346 347 static final String[] EMPTY_STRING_ARRAY = new String[0]; 348 349 // How many bytes to write into the dropbox log before truncating 350 static final int DROPBOX_MAX_SIZE = 256 * 1024; 351 352 /** All system services */ 353 SystemServiceManager mSystemServiceManager; 354 355 /** Run all ActivityStacks through this */ 356 ActivityStackSupervisor mStackSupervisor; 357 358 public IntentFirewall mIntentFirewall; 359 360 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 361 // default actuion automatically. Important for devices without direct input 362 // devices. 363 private boolean mShowDialogs = true; 364 365 /** 366 * Description of a request to start a new activity, which has been held 367 * due to app switches being disabled. 368 */ 369 static class PendingActivityLaunch { 370 final ActivityRecord r; 371 final ActivityRecord sourceRecord; 372 final int startFlags; 373 final ActivityStack stack; 374 375 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 376 int _startFlags, ActivityStack _stack) { 377 r = _r; 378 sourceRecord = _sourceRecord; 379 startFlags = _startFlags; 380 stack = _stack; 381 } 382 } 383 384 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 385 = new ArrayList<PendingActivityLaunch>(); 386 387 BroadcastQueue mFgBroadcastQueue; 388 BroadcastQueue mBgBroadcastQueue; 389 // Convenient for easy iteration over the queues. Foreground is first 390 // so that dispatch of foreground broadcasts gets precedence. 391 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 392 393 BroadcastQueue broadcastQueueForIntent(Intent intent) { 394 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 395 if (DEBUG_BACKGROUND_BROADCAST) { 396 Slog.i(TAG, "Broadcast intent " + intent + " on " 397 + (isFg ? "foreground" : "background") 398 + " queue"); 399 } 400 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 401 } 402 403 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 404 for (BroadcastQueue queue : mBroadcastQueues) { 405 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 406 if (r != null) { 407 return r; 408 } 409 } 410 return null; 411 } 412 413 /** 414 * Activity we have told the window manager to have key focus. 415 */ 416 ActivityRecord mFocusedActivity = null; 417 418 /** 419 * List of intents that were used to start the most recent tasks. 420 */ 421 ArrayList<TaskRecord> mRecentTasks; 422 423 public class PendingAssistExtras extends Binder implements Runnable { 424 public final ActivityRecord activity; 425 public boolean haveResult = false; 426 public Bundle result = null; 427 public PendingAssistExtras(ActivityRecord _activity) { 428 activity = _activity; 429 } 430 @Override 431 public void run() { 432 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 433 synchronized (this) { 434 haveResult = true; 435 notifyAll(); 436 } 437 } 438 } 439 440 final ArrayList<PendingAssistExtras> mPendingAssistExtras 441 = new ArrayList<PendingAssistExtras>(); 442 443 /** 444 * Process management. 445 */ 446 final ProcessList mProcessList = new ProcessList(); 447 448 /** 449 * All of the applications we currently have running organized by name. 450 * The keys are strings of the application package name (as 451 * returned by the package manager), and the keys are ApplicationRecord 452 * objects. 453 */ 454 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 455 456 /** 457 * Tracking long-term execution of processes to look for abuse and other 458 * bad app behavior. 459 */ 460 final ProcessStatsService mProcessStats; 461 462 /** 463 * The currently running isolated processes. 464 */ 465 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 466 467 /** 468 * Counter for assigning isolated process uids, to avoid frequently reusing the 469 * same ones. 470 */ 471 int mNextIsolatedProcessUid = 0; 472 473 /** 474 * The currently running heavy-weight process, if any. 475 */ 476 ProcessRecord mHeavyWeightProcess = null; 477 478 /** 479 * The last time that various processes have crashed. 480 */ 481 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 482 483 /** 484 * Information about a process that is currently marked as bad. 485 */ 486 static final class BadProcessInfo { 487 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 488 this.time = time; 489 this.shortMsg = shortMsg; 490 this.longMsg = longMsg; 491 this.stack = stack; 492 } 493 494 final long time; 495 final String shortMsg; 496 final String longMsg; 497 final String stack; 498 } 499 500 /** 501 * Set of applications that we consider to be bad, and will reject 502 * incoming broadcasts from (which the user has no control over). 503 * Processes are added to this set when they have crashed twice within 504 * a minimum amount of time; they are removed from it when they are 505 * later restarted (hopefully due to some user action). The value is the 506 * time it was added to the list. 507 */ 508 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 509 510 /** 511 * All of the processes we currently have running organized by pid. 512 * The keys are the pid running the application. 513 * 514 * <p>NOTE: This object is protected by its own lock, NOT the global 515 * activity manager lock! 516 */ 517 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 518 519 /** 520 * All of the processes that have been forced to be foreground. The key 521 * is the pid of the caller who requested it (we hold a death 522 * link on it). 523 */ 524 abstract class ForegroundToken implements IBinder.DeathRecipient { 525 int pid; 526 IBinder token; 527 } 528 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 529 530 /** 531 * List of records for processes that someone had tried to start before the 532 * system was ready. We don't start them at that point, but ensure they 533 * are started by the time booting is complete. 534 */ 535 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of persistent applications that are in the process 539 * of being started. 540 */ 541 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Processes that are being forcibly torn down. 545 */ 546 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 547 548 /** 549 * List of running applications, sorted by recent usage. 550 * The first entry in the list is the least recently used. 551 */ 552 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 553 554 /** 555 * Where in mLruProcesses that the processes hosting activities start. 556 */ 557 int mLruProcessActivityStart = 0; 558 559 /** 560 * Where in mLruProcesses that the processes hosting services start. 561 * This is after (lower index) than mLruProcessesActivityStart. 562 */ 563 int mLruProcessServiceStart = 0; 564 565 /** 566 * List of processes that should gc as soon as things are idle. 567 */ 568 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 569 570 /** 571 * Processes we want to collect PSS data from. 572 */ 573 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Last time we requested PSS data of all processes. 577 */ 578 long mLastFullPssTime = SystemClock.uptimeMillis(); 579 580 /** 581 * If set, the next time we collect PSS data we should do a full collection 582 * with data from native processes and the kernel. 583 */ 584 boolean mFullPssPending = false; 585 586 /** 587 * This is the process holding what we currently consider to be 588 * the "home" activity. 589 */ 590 ProcessRecord mHomeProcess; 591 592 /** 593 * This is the process holding the activity the user last visited that 594 * is in a different process from the one they are currently in. 595 */ 596 ProcessRecord mPreviousProcess; 597 598 /** 599 * The time at which the previous process was last visible. 600 */ 601 long mPreviousProcessVisibleTime; 602 603 /** 604 * Which uses have been started, so are allowed to run code. 605 */ 606 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 607 608 /** 609 * LRU list of history of current users. Most recently current is at the end. 610 */ 611 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 612 613 /** 614 * Constant array of the users that are currently started. 615 */ 616 int[] mStartedUserArray = new int[] { 0 }; 617 618 /** 619 * Registered observers of the user switching mechanics. 620 */ 621 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 622 = new RemoteCallbackList<IUserSwitchObserver>(); 623 624 /** 625 * Currently active user switch. 626 */ 627 Object mCurUserSwitchCallback; 628 629 /** 630 * Packages that the user has asked to have run in screen size 631 * compatibility mode instead of filling the screen. 632 */ 633 final CompatModePackages mCompatModePackages; 634 635 /** 636 * Set of IntentSenderRecord objects that are currently active. 637 */ 638 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 639 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 640 641 /** 642 * Fingerprints (hashCode()) of stack traces that we've 643 * already logged DropBox entries for. Guarded by itself. If 644 * something (rogue user app) forces this over 645 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 646 */ 647 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 648 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 649 650 /** 651 * Strict Mode background batched logging state. 652 * 653 * The string buffer is guarded by itself, and its lock is also 654 * used to determine if another batched write is already 655 * in-flight. 656 */ 657 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 658 659 /** 660 * Keeps track of all IIntentReceivers that have been registered for 661 * broadcasts. Hash keys are the receiver IBinder, hash value is 662 * a ReceiverList. 663 */ 664 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 665 new HashMap<IBinder, ReceiverList>(); 666 667 /** 668 * Resolver for broadcast intents to registered receivers. 669 * Holds BroadcastFilter (subclass of IntentFilter). 670 */ 671 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 672 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 673 @Override 674 protected boolean allowFilterResult( 675 BroadcastFilter filter, List<BroadcastFilter> dest) { 676 IBinder target = filter.receiverList.receiver.asBinder(); 677 for (int i=dest.size()-1; i>=0; i--) { 678 if (dest.get(i).receiverList.receiver.asBinder() == target) { 679 return false; 680 } 681 } 682 return true; 683 } 684 685 @Override 686 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 687 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 688 || userId == filter.owningUserId) { 689 return super.newResult(filter, match, userId); 690 } 691 return null; 692 } 693 694 @Override 695 protected BroadcastFilter[] newArray(int size) { 696 return new BroadcastFilter[size]; 697 } 698 699 @Override 700 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 701 return packageName.equals(filter.packageName); 702 } 703 }; 704 705 /** 706 * State of all active sticky broadcasts per user. Keys are the action of the 707 * sticky Intent, values are an ArrayList of all broadcasted intents with 708 * that action (which should usually be one). The SparseArray is keyed 709 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 710 * for stickies that are sent to all users. 711 */ 712 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 713 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 714 715 final ActiveServices mServices; 716 717 /** 718 * Backup/restore process management 719 */ 720 String mBackupAppName = null; 721 BackupRecord mBackupTarget = null; 722 723 final ProviderMap mProviderMap; 724 725 /** 726 * List of content providers who have clients waiting for them. The 727 * application is currently being launched and the provider will be 728 * removed from this list once it is published. 729 */ 730 final ArrayList<ContentProviderRecord> mLaunchingProviders 731 = new ArrayList<ContentProviderRecord>(); 732 733 /** 734 * File storing persisted {@link #mGrantedUriPermissions}. 735 */ 736 private final AtomicFile mGrantFile; 737 738 /** XML constants used in {@link #mGrantFile} */ 739 private static final String TAG_URI_GRANTS = "uri-grants"; 740 private static final String TAG_URI_GRANT = "uri-grant"; 741 private static final String ATTR_USER_HANDLE = "userHandle"; 742 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 743 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 744 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 745 private static final String ATTR_TARGET_PKG = "targetPkg"; 746 private static final String ATTR_URI = "uri"; 747 private static final String ATTR_MODE_FLAGS = "modeFlags"; 748 private static final String ATTR_CREATED_TIME = "createdTime"; 749 private static final String ATTR_PREFIX = "prefix"; 750 751 /** 752 * Global set of specific {@link Uri} permissions that have been granted. 753 * This optimized lookup structure maps from {@link UriPermission#targetUid} 754 * to {@link UriPermission#uri} to {@link UriPermission}. 755 */ 756 @GuardedBy("this") 757 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 758 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 759 760 public static class GrantUri { 761 public final int sourceUserId; 762 public final Uri uri; 763 public boolean prefix; 764 765 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 766 this.sourceUserId = sourceUserId; 767 this.uri = uri; 768 this.prefix = prefix; 769 } 770 771 @Override 772 public int hashCode() { 773 return toString().hashCode(); 774 } 775 776 @Override 777 public boolean equals(Object o) { 778 if (o instanceof GrantUri) { 779 GrantUri other = (GrantUri) o; 780 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 781 && prefix == other.prefix; 782 } 783 return false; 784 } 785 786 @Override 787 public String toString() { 788 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 789 if (prefix) result += " [prefix]"; 790 return result; 791 } 792 793 public String toSafeString() { 794 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 795 if (prefix) result += " [prefix]"; 796 return result; 797 } 798 799 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 800 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 801 ContentProvider.getUriWithoutUserId(uri), false); 802 } 803 } 804 805 CoreSettingsObserver mCoreSettingsObserver; 806 807 /** 808 * Thread-local storage used to carry caller permissions over through 809 * indirect content-provider access. 810 */ 811 private class Identity { 812 public int pid; 813 public int uid; 814 815 Identity(int _pid, int _uid) { 816 pid = _pid; 817 uid = _uid; 818 } 819 } 820 821 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 822 823 /** 824 * All information we have collected about the runtime performance of 825 * any user id that can impact battery performance. 826 */ 827 final BatteryStatsService mBatteryStatsService; 828 829 /** 830 * Information about component usage 831 */ 832 final UsageStatsService mUsageStatsService; 833 834 /** 835 * Information about and control over application operations 836 */ 837 final AppOpsService mAppOpsService; 838 839 /** 840 * Save recent tasks information across reboots. 841 */ 842 final TaskPersister mTaskPersister; 843 844 /** 845 * Current configuration information. HistoryRecord objects are given 846 * a reference to this object to indicate which configuration they are 847 * currently running in, so this object must be kept immutable. 848 */ 849 Configuration mConfiguration = new Configuration(); 850 851 /** 852 * Current sequencing integer of the configuration, for skipping old 853 * configurations. 854 */ 855 int mConfigurationSeq = 0; 856 857 /** 858 * Hardware-reported OpenGLES version. 859 */ 860 final int GL_ES_VERSION; 861 862 /** 863 * List of initialization arguments to pass to all processes when binding applications to them. 864 * For example, references to the commonly used services. 865 */ 866 HashMap<String, IBinder> mAppBindArgs; 867 868 /** 869 * Temporary to avoid allocations. Protected by main lock. 870 */ 871 final StringBuilder mStringBuilder = new StringBuilder(256); 872 873 /** 874 * Used to control how we initialize the service. 875 */ 876 ComponentName mTopComponent; 877 String mTopAction = Intent.ACTION_MAIN; 878 String mTopData; 879 boolean mProcessesReady = false; 880 boolean mSystemReady = false; 881 boolean mBooting = false; 882 boolean mWaitingUpdate = false; 883 boolean mDidUpdate = false; 884 boolean mOnBattery = false; 885 boolean mLaunchWarningShown = false; 886 887 Context mContext; 888 889 int mFactoryTest; 890 891 boolean mCheckedForSetup; 892 893 /** 894 * The time at which we will allow normal application switches again, 895 * after a call to {@link #stopAppSwitches()}. 896 */ 897 long mAppSwitchesAllowedTime; 898 899 /** 900 * This is set to true after the first switch after mAppSwitchesAllowedTime 901 * is set; any switches after that will clear the time. 902 */ 903 boolean mDidAppSwitch; 904 905 /** 906 * Last time (in realtime) at which we checked for power usage. 907 */ 908 long mLastPowerCheckRealtime; 909 910 /** 911 * Last time (in uptime) at which we checked for power usage. 912 */ 913 long mLastPowerCheckUptime; 914 915 /** 916 * Set while we are wanting to sleep, to prevent any 917 * activities from being started/resumed. 918 */ 919 private boolean mSleeping = false; 920 921 /** 922 * Set while we are running a voice interaction. This overrides 923 * sleeping while it is active. 924 */ 925 private boolean mRunningVoice = false; 926 927 /** 928 * State of external calls telling us if the device is asleep. 929 */ 930 private boolean mWentToSleep = false; 931 932 /** 933 * State of external call telling us if the lock screen is shown. 934 */ 935 private boolean mLockScreenShown = false; 936 937 /** 938 * Set if we are shutting down the system, similar to sleeping. 939 */ 940 boolean mShuttingDown = false; 941 942 /** 943 * Current sequence id for oom_adj computation traversal. 944 */ 945 int mAdjSeq = 0; 946 947 /** 948 * Current sequence id for process LRU updating. 949 */ 950 int mLruSeq = 0; 951 952 /** 953 * Keep track of the non-cached/empty process we last found, to help 954 * determine how to distribute cached/empty processes next time. 955 */ 956 int mNumNonCachedProcs = 0; 957 958 /** 959 * Keep track of the number of cached hidden procs, to balance oom adj 960 * distribution between those and empty procs. 961 */ 962 int mNumCachedHiddenProcs = 0; 963 964 /** 965 * Keep track of the number of service processes we last found, to 966 * determine on the next iteration which should be B services. 967 */ 968 int mNumServiceProcs = 0; 969 int mNewNumAServiceProcs = 0; 970 int mNewNumServiceProcs = 0; 971 972 /** 973 * Allow the current computed overall memory level of the system to go down? 974 * This is set to false when we are killing processes for reasons other than 975 * memory management, so that the now smaller process list will not be taken as 976 * an indication that memory is tighter. 977 */ 978 boolean mAllowLowerMemLevel = false; 979 980 /** 981 * The last computed memory level, for holding when we are in a state that 982 * processes are going away for other reasons. 983 */ 984 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 985 986 /** 987 * The last total number of process we have, to determine if changes actually look 988 * like a shrinking number of process due to lower RAM. 989 */ 990 int mLastNumProcesses; 991 992 /** 993 * The uptime of the last time we performed idle maintenance. 994 */ 995 long mLastIdleTime = SystemClock.uptimeMillis(); 996 997 /** 998 * Total time spent with RAM that has been added in the past since the last idle time. 999 */ 1000 long mLowRamTimeSinceLastIdle = 0; 1001 1002 /** 1003 * If RAM is currently low, when that horrible situation started. 1004 */ 1005 long mLowRamStartTime = 0; 1006 1007 /** 1008 * For reporting to battery stats the current top application. 1009 */ 1010 private String mCurResumedPackage = null; 1011 private int mCurResumedUid = -1; 1012 1013 /** 1014 * For reporting to battery stats the apps currently running foreground 1015 * service. The ProcessMap is package/uid tuples; each of these contain 1016 * an array of the currently foreground processes. 1017 */ 1018 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1019 = new ProcessMap<ArrayList<ProcessRecord>>(); 1020 1021 /** 1022 * This is set if we had to do a delayed dexopt of an app before launching 1023 * it, to increase the ANR timeouts in that case. 1024 */ 1025 boolean mDidDexOpt; 1026 1027 /** 1028 * Set if the systemServer made a call to enterSafeMode. 1029 */ 1030 boolean mSafeMode; 1031 1032 String mDebugApp = null; 1033 boolean mWaitForDebugger = false; 1034 boolean mDebugTransient = false; 1035 String mOrigDebugApp = null; 1036 boolean mOrigWaitForDebugger = false; 1037 boolean mAlwaysFinishActivities = false; 1038 IActivityController mController = null; 1039 String mProfileApp = null; 1040 ProcessRecord mProfileProc = null; 1041 String mProfileFile; 1042 ParcelFileDescriptor mProfileFd; 1043 int mProfileType = 0; 1044 boolean mAutoStopProfiler = false; 1045 String mOpenGlTraceApp = null; 1046 1047 static class ProcessChangeItem { 1048 static final int CHANGE_ACTIVITIES = 1<<0; 1049 static final int CHANGE_PROCESS_STATE = 1<<1; 1050 int changes; 1051 int uid; 1052 int pid; 1053 int processState; 1054 boolean foregroundActivities; 1055 } 1056 1057 final RemoteCallbackList<IProcessObserver> mProcessObservers 1058 = new RemoteCallbackList<IProcessObserver>(); 1059 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1060 1061 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1062 = new ArrayList<ProcessChangeItem>(); 1063 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1064 = new ArrayList<ProcessChangeItem>(); 1065 1066 /** 1067 * Runtime CPU use collection thread. This object's lock is used to 1068 * protect all related state. 1069 */ 1070 final Thread mProcessCpuThread; 1071 1072 /** 1073 * Used to collect process stats when showing not responding dialog. 1074 * Protected by mProcessCpuThread. 1075 */ 1076 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1077 MONITOR_THREAD_CPU_USAGE); 1078 final AtomicLong mLastCpuTime = new AtomicLong(0); 1079 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1080 1081 long mLastWriteTime = 0; 1082 1083 /** 1084 * Used to retain an update lock when the foreground activity is in 1085 * immersive mode. 1086 */ 1087 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1088 1089 /** 1090 * Set to true after the system has finished booting. 1091 */ 1092 boolean mBooted = false; 1093 1094 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1095 int mProcessLimitOverride = -1; 1096 1097 WindowManagerService mWindowManager; 1098 1099 final ActivityThread mSystemThread; 1100 1101 int mCurrentUserId = 0; 1102 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1103 private UserManagerService mUserManager; 1104 1105 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1106 final ProcessRecord mApp; 1107 final int mPid; 1108 final IApplicationThread mAppThread; 1109 1110 AppDeathRecipient(ProcessRecord app, int pid, 1111 IApplicationThread thread) { 1112 if (localLOGV) Slog.v( 1113 TAG, "New death recipient " + this 1114 + " for thread " + thread.asBinder()); 1115 mApp = app; 1116 mPid = pid; 1117 mAppThread = thread; 1118 } 1119 1120 @Override 1121 public void binderDied() { 1122 if (localLOGV) Slog.v( 1123 TAG, "Death received in " + this 1124 + " for thread " + mAppThread.asBinder()); 1125 synchronized(ActivityManagerService.this) { 1126 appDiedLocked(mApp, mPid, mAppThread); 1127 } 1128 } 1129 } 1130 1131 static final int SHOW_ERROR_MSG = 1; 1132 static final int SHOW_NOT_RESPONDING_MSG = 2; 1133 static final int SHOW_FACTORY_ERROR_MSG = 3; 1134 static final int UPDATE_CONFIGURATION_MSG = 4; 1135 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1136 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1137 static final int SERVICE_TIMEOUT_MSG = 12; 1138 static final int UPDATE_TIME_ZONE = 13; 1139 static final int SHOW_UID_ERROR_MSG = 14; 1140 static final int IM_FEELING_LUCKY_MSG = 15; 1141 static final int PROC_START_TIMEOUT_MSG = 20; 1142 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1143 static final int KILL_APPLICATION_MSG = 22; 1144 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1145 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1146 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1147 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1148 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1149 static final int CLEAR_DNS_CACHE_MSG = 28; 1150 static final int UPDATE_HTTP_PROXY_MSG = 29; 1151 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1152 static final int DISPATCH_PROCESSES_CHANGED = 31; 1153 static final int DISPATCH_PROCESS_DIED = 32; 1154 static final int REPORT_MEM_USAGE_MSG = 33; 1155 static final int REPORT_USER_SWITCH_MSG = 34; 1156 static final int CONTINUE_USER_SWITCH_MSG = 35; 1157 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1158 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1159 static final int PERSIST_URI_GRANTS_MSG = 38; 1160 static final int REQUEST_ALL_PSS_MSG = 39; 1161 static final int START_PROFILES_MSG = 40; 1162 static final int UPDATE_TIME = 41; 1163 static final int SYSTEM_USER_START_MSG = 42; 1164 static final int SYSTEM_USER_CURRENT_MSG = 43; 1165 1166 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1167 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1168 static final int FIRST_COMPAT_MODE_MSG = 300; 1169 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1170 1171 AlertDialog mUidAlert; 1172 CompatModeDialog mCompatModeDialog; 1173 long mLastMemUsageReportTime = 0; 1174 1175 private LockToAppRequestDialog mLockToAppRequest; 1176 1177 /** 1178 * Flag whether the current user is a "monkey", i.e. whether 1179 * the UI is driven by a UI automation tool. 1180 */ 1181 private boolean mUserIsMonkey; 1182 1183 final ServiceThread mHandlerThread; 1184 final MainHandler mHandler; 1185 1186 final class MainHandler extends Handler { 1187 public MainHandler(Looper looper) { 1188 super(looper, null, true); 1189 } 1190 1191 @Override 1192 public void handleMessage(Message msg) { 1193 switch (msg.what) { 1194 case SHOW_ERROR_MSG: { 1195 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1196 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1197 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1198 synchronized (ActivityManagerService.this) { 1199 ProcessRecord proc = (ProcessRecord)data.get("app"); 1200 AppErrorResult res = (AppErrorResult) data.get("result"); 1201 if (proc != null && proc.crashDialog != null) { 1202 Slog.e(TAG, "App already has crash dialog: " + proc); 1203 if (res != null) { 1204 res.set(0); 1205 } 1206 return; 1207 } 1208 if (!showBackground && UserHandle.getAppId(proc.uid) 1209 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1210 && proc.pid != MY_PID) { 1211 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1212 if (res != null) { 1213 res.set(0); 1214 } 1215 return; 1216 } 1217 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1218 Dialog d = new AppErrorDialog(mContext, 1219 ActivityManagerService.this, res, proc); 1220 d.show(); 1221 proc.crashDialog = d; 1222 } else { 1223 // The device is asleep, so just pretend that the user 1224 // saw a crash dialog and hit "force quit". 1225 if (res != null) { 1226 res.set(0); 1227 } 1228 } 1229 } 1230 1231 ensureBootCompleted(); 1232 } break; 1233 case SHOW_NOT_RESPONDING_MSG: { 1234 synchronized (ActivityManagerService.this) { 1235 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1236 ProcessRecord proc = (ProcessRecord)data.get("app"); 1237 if (proc != null && proc.anrDialog != null) { 1238 Slog.e(TAG, "App already has anr dialog: " + proc); 1239 return; 1240 } 1241 1242 Intent intent = new Intent("android.intent.action.ANR"); 1243 if (!mProcessesReady) { 1244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1245 | Intent.FLAG_RECEIVER_FOREGROUND); 1246 } 1247 broadcastIntentLocked(null, null, intent, 1248 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1249 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1250 1251 if (mShowDialogs) { 1252 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1253 mContext, proc, (ActivityRecord)data.get("activity"), 1254 msg.arg1 != 0); 1255 d.show(); 1256 proc.anrDialog = d; 1257 } else { 1258 // Just kill the app if there is no dialog to be shown. 1259 killAppAtUsersRequest(proc, null); 1260 } 1261 } 1262 1263 ensureBootCompleted(); 1264 } break; 1265 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1266 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1267 synchronized (ActivityManagerService.this) { 1268 ProcessRecord proc = (ProcessRecord) data.get("app"); 1269 if (proc == null) { 1270 Slog.e(TAG, "App not found when showing strict mode dialog."); 1271 break; 1272 } 1273 if (proc.crashDialog != null) { 1274 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1275 return; 1276 } 1277 AppErrorResult res = (AppErrorResult) data.get("result"); 1278 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1279 Dialog d = new StrictModeViolationDialog(mContext, 1280 ActivityManagerService.this, res, proc); 1281 d.show(); 1282 proc.crashDialog = d; 1283 } else { 1284 // The device is asleep, so just pretend that the user 1285 // saw a crash dialog and hit "force quit". 1286 res.set(0); 1287 } 1288 } 1289 ensureBootCompleted(); 1290 } break; 1291 case SHOW_FACTORY_ERROR_MSG: { 1292 Dialog d = new FactoryErrorDialog( 1293 mContext, msg.getData().getCharSequence("msg")); 1294 d.show(); 1295 ensureBootCompleted(); 1296 } break; 1297 case UPDATE_CONFIGURATION_MSG: { 1298 final ContentResolver resolver = mContext.getContentResolver(); 1299 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1300 } break; 1301 case GC_BACKGROUND_PROCESSES_MSG: { 1302 synchronized (ActivityManagerService.this) { 1303 performAppGcsIfAppropriateLocked(); 1304 } 1305 } break; 1306 case WAIT_FOR_DEBUGGER_MSG: { 1307 synchronized (ActivityManagerService.this) { 1308 ProcessRecord app = (ProcessRecord)msg.obj; 1309 if (msg.arg1 != 0) { 1310 if (!app.waitedForDebugger) { 1311 Dialog d = new AppWaitingForDebuggerDialog( 1312 ActivityManagerService.this, 1313 mContext, app); 1314 app.waitDialog = d; 1315 app.waitedForDebugger = true; 1316 d.show(); 1317 } 1318 } else { 1319 if (app.waitDialog != null) { 1320 app.waitDialog.dismiss(); 1321 app.waitDialog = null; 1322 } 1323 } 1324 } 1325 } break; 1326 case SERVICE_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1332 return; 1333 } 1334 mServices.serviceTimeout((ProcessRecord)msg.obj); 1335 } break; 1336 case UPDATE_TIME_ZONE: { 1337 synchronized (ActivityManagerService.this) { 1338 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1339 ProcessRecord r = mLruProcesses.get(i); 1340 if (r.thread != null) { 1341 try { 1342 r.thread.updateTimeZone(); 1343 } catch (RemoteException ex) { 1344 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1345 } 1346 } 1347 } 1348 } 1349 } break; 1350 case CLEAR_DNS_CACHE_MSG: { 1351 synchronized (ActivityManagerService.this) { 1352 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1353 ProcessRecord r = mLruProcesses.get(i); 1354 if (r.thread != null) { 1355 try { 1356 r.thread.clearDnsCache(); 1357 } catch (RemoteException ex) { 1358 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1359 } 1360 } 1361 } 1362 } 1363 } break; 1364 case UPDATE_HTTP_PROXY_MSG: { 1365 ProxyInfo proxy = (ProxyInfo)msg.obj; 1366 String host = ""; 1367 String port = ""; 1368 String exclList = ""; 1369 Uri pacFileUrl = Uri.EMPTY; 1370 if (proxy != null) { 1371 host = proxy.getHost(); 1372 port = Integer.toString(proxy.getPort()); 1373 exclList = proxy.getExclusionListAsString(); 1374 pacFileUrl = proxy.getPacFileUrl(); 1375 } 1376 synchronized (ActivityManagerService.this) { 1377 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1378 ProcessRecord r = mLruProcesses.get(i); 1379 if (r.thread != null) { 1380 try { 1381 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1382 } catch (RemoteException ex) { 1383 Slog.w(TAG, "Failed to update http proxy for: " + 1384 r.info.processName); 1385 } 1386 } 1387 } 1388 } 1389 } break; 1390 case SHOW_UID_ERROR_MSG: { 1391 String title = "System UIDs Inconsistent"; 1392 String text = "UIDs on the system are inconsistent, you need to wipe your" 1393 + " data partition or your device will be unstable."; 1394 Log.e(TAG, title + ": " + text); 1395 if (mShowDialogs) { 1396 // XXX This is a temporary dialog, no need to localize. 1397 AlertDialog d = new BaseErrorDialog(mContext); 1398 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1399 d.setCancelable(false); 1400 d.setTitle(title); 1401 d.setMessage(text); 1402 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1403 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1404 mUidAlert = d; 1405 d.show(); 1406 } 1407 } break; 1408 case IM_FEELING_LUCKY_MSG: { 1409 if (mUidAlert != null) { 1410 mUidAlert.dismiss(); 1411 mUidAlert = null; 1412 } 1413 } break; 1414 case PROC_START_TIMEOUT_MSG: { 1415 if (mDidDexOpt) { 1416 mDidDexOpt = false; 1417 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1418 nmsg.obj = msg.obj; 1419 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1420 return; 1421 } 1422 ProcessRecord app = (ProcessRecord)msg.obj; 1423 synchronized (ActivityManagerService.this) { 1424 processStartTimedOutLocked(app); 1425 } 1426 } break; 1427 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1428 synchronized (ActivityManagerService.this) { 1429 doPendingActivityLaunchesLocked(true); 1430 } 1431 } break; 1432 case KILL_APPLICATION_MSG: { 1433 synchronized (ActivityManagerService.this) { 1434 int appid = msg.arg1; 1435 boolean restart = (msg.arg2 == 1); 1436 Bundle bundle = (Bundle)msg.obj; 1437 String pkg = bundle.getString("pkg"); 1438 String reason = bundle.getString("reason"); 1439 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1440 false, UserHandle.USER_ALL, reason); 1441 } 1442 } break; 1443 case FINALIZE_PENDING_INTENT_MSG: { 1444 ((PendingIntentRecord)msg.obj).completeFinalize(); 1445 } break; 1446 case POST_HEAVY_NOTIFICATION_MSG: { 1447 INotificationManager inm = NotificationManager.getService(); 1448 if (inm == null) { 1449 return; 1450 } 1451 1452 ActivityRecord root = (ActivityRecord)msg.obj; 1453 ProcessRecord process = root.app; 1454 if (process == null) { 1455 return; 1456 } 1457 1458 try { 1459 Context context = mContext.createPackageContext(process.info.packageName, 0); 1460 String text = mContext.getString(R.string.heavy_weight_notification, 1461 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1462 Notification notification = new Notification(); 1463 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1464 notification.when = 0; 1465 notification.flags = Notification.FLAG_ONGOING_EVENT; 1466 notification.tickerText = text; 1467 notification.defaults = 0; // please be quiet 1468 notification.sound = null; 1469 notification.vibrate = null; 1470 notification.setLatestEventInfo(context, text, 1471 mContext.getText(R.string.heavy_weight_notification_detail), 1472 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1473 PendingIntent.FLAG_CANCEL_CURRENT, null, 1474 new UserHandle(root.userId))); 1475 1476 try { 1477 int[] outId = new int[1]; 1478 inm.enqueueNotificationWithTag("android", "android", null, 1479 R.string.heavy_weight_notification, 1480 notification, outId, root.userId); 1481 } catch (RuntimeException e) { 1482 Slog.w(ActivityManagerService.TAG, 1483 "Error showing notification for heavy-weight app", e); 1484 } catch (RemoteException e) { 1485 } 1486 } catch (NameNotFoundException e) { 1487 Slog.w(TAG, "Unable to create context for heavy notification", e); 1488 } 1489 } break; 1490 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1491 INotificationManager inm = NotificationManager.getService(); 1492 if (inm == null) { 1493 return; 1494 } 1495 try { 1496 inm.cancelNotificationWithTag("android", null, 1497 R.string.heavy_weight_notification, msg.arg1); 1498 } catch (RuntimeException e) { 1499 Slog.w(ActivityManagerService.TAG, 1500 "Error canceling notification for service", e); 1501 } catch (RemoteException e) { 1502 } 1503 } break; 1504 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1505 synchronized (ActivityManagerService.this) { 1506 checkExcessivePowerUsageLocked(true); 1507 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1508 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1509 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1510 } 1511 } break; 1512 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1513 synchronized (ActivityManagerService.this) { 1514 ActivityRecord ar = (ActivityRecord)msg.obj; 1515 if (mCompatModeDialog != null) { 1516 if (mCompatModeDialog.mAppInfo.packageName.equals( 1517 ar.info.applicationInfo.packageName)) { 1518 return; 1519 } 1520 mCompatModeDialog.dismiss(); 1521 mCompatModeDialog = null; 1522 } 1523 if (ar != null && false) { 1524 if (mCompatModePackages.getPackageAskCompatModeLocked( 1525 ar.packageName)) { 1526 int mode = mCompatModePackages.computeCompatModeLocked( 1527 ar.info.applicationInfo); 1528 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1529 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1530 mCompatModeDialog = new CompatModeDialog( 1531 ActivityManagerService.this, mContext, 1532 ar.info.applicationInfo); 1533 mCompatModeDialog.show(); 1534 } 1535 } 1536 } 1537 } 1538 break; 1539 } 1540 case DISPATCH_PROCESSES_CHANGED: { 1541 dispatchProcessesChanged(); 1542 break; 1543 } 1544 case DISPATCH_PROCESS_DIED: { 1545 final int pid = msg.arg1; 1546 final int uid = msg.arg2; 1547 dispatchProcessDied(pid, uid); 1548 break; 1549 } 1550 case REPORT_MEM_USAGE_MSG: { 1551 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1552 Thread thread = new Thread() { 1553 @Override public void run() { 1554 final SparseArray<ProcessMemInfo> infoMap 1555 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1556 for (int i=0, N=memInfos.size(); i<N; i++) { 1557 ProcessMemInfo mi = memInfos.get(i); 1558 infoMap.put(mi.pid, mi); 1559 } 1560 updateCpuStatsNow(); 1561 synchronized (mProcessCpuThread) { 1562 final int N = mProcessCpuTracker.countStats(); 1563 for (int i=0; i<N; i++) { 1564 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1565 if (st.vsize > 0) { 1566 long pss = Debug.getPss(st.pid, null); 1567 if (pss > 0) { 1568 if (infoMap.indexOfKey(st.pid) < 0) { 1569 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1570 ProcessList.NATIVE_ADJ, -1, "native", null); 1571 mi.pss = pss; 1572 memInfos.add(mi); 1573 } 1574 } 1575 } 1576 } 1577 } 1578 1579 long totalPss = 0; 1580 for (int i=0, N=memInfos.size(); i<N; i++) { 1581 ProcessMemInfo mi = memInfos.get(i); 1582 if (mi.pss == 0) { 1583 mi.pss = Debug.getPss(mi.pid, null); 1584 } 1585 totalPss += mi.pss; 1586 } 1587 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1588 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1589 if (lhs.oomAdj != rhs.oomAdj) { 1590 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1591 } 1592 if (lhs.pss != rhs.pss) { 1593 return lhs.pss < rhs.pss ? 1 : -1; 1594 } 1595 return 0; 1596 } 1597 }); 1598 1599 StringBuilder tag = new StringBuilder(128); 1600 StringBuilder stack = new StringBuilder(128); 1601 tag.append("Low on memory -- "); 1602 appendMemBucket(tag, totalPss, "total", false); 1603 appendMemBucket(stack, totalPss, "total", true); 1604 1605 StringBuilder logBuilder = new StringBuilder(1024); 1606 logBuilder.append("Low on memory:\n"); 1607 1608 boolean firstLine = true; 1609 int lastOomAdj = Integer.MIN_VALUE; 1610 for (int i=0, N=memInfos.size(); i<N; i++) { 1611 ProcessMemInfo mi = memInfos.get(i); 1612 1613 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1614 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1615 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1616 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1617 if (lastOomAdj != mi.oomAdj) { 1618 lastOomAdj = mi.oomAdj; 1619 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1620 tag.append(" / "); 1621 } 1622 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1623 if (firstLine) { 1624 stack.append(":"); 1625 firstLine = false; 1626 } 1627 stack.append("\n\t at "); 1628 } else { 1629 stack.append("$"); 1630 } 1631 } else { 1632 tag.append(" "); 1633 stack.append("$"); 1634 } 1635 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1636 appendMemBucket(tag, mi.pss, mi.name, false); 1637 } 1638 appendMemBucket(stack, mi.pss, mi.name, true); 1639 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1640 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1641 stack.append("("); 1642 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1643 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1644 stack.append(DUMP_MEM_OOM_LABEL[k]); 1645 stack.append(":"); 1646 stack.append(DUMP_MEM_OOM_ADJ[k]); 1647 } 1648 } 1649 stack.append(")"); 1650 } 1651 } 1652 1653 logBuilder.append(" "); 1654 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1655 logBuilder.append(' '); 1656 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1657 logBuilder.append(' '); 1658 ProcessList.appendRamKb(logBuilder, mi.pss); 1659 logBuilder.append(" kB: "); 1660 logBuilder.append(mi.name); 1661 logBuilder.append(" ("); 1662 logBuilder.append(mi.pid); 1663 logBuilder.append(") "); 1664 logBuilder.append(mi.adjType); 1665 logBuilder.append('\n'); 1666 if (mi.adjReason != null) { 1667 logBuilder.append(" "); 1668 logBuilder.append(mi.adjReason); 1669 logBuilder.append('\n'); 1670 } 1671 } 1672 1673 logBuilder.append(" "); 1674 ProcessList.appendRamKb(logBuilder, totalPss); 1675 logBuilder.append(" kB: TOTAL\n"); 1676 1677 long[] infos = new long[Debug.MEMINFO_COUNT]; 1678 Debug.getMemInfo(infos); 1679 logBuilder.append(" MemInfo: "); 1680 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1681 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1682 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1683 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1684 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1685 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1686 logBuilder.append(" ZRAM: "); 1687 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1688 logBuilder.append(" kB RAM, "); 1689 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1690 logBuilder.append(" kB swap total, "); 1691 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1692 logBuilder.append(" kB swap free\n"); 1693 } 1694 Slog.i(TAG, logBuilder.toString()); 1695 1696 StringBuilder dropBuilder = new StringBuilder(1024); 1697 /* 1698 StringWriter oomSw = new StringWriter(); 1699 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1700 StringWriter catSw = new StringWriter(); 1701 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1702 String[] emptyArgs = new String[] { }; 1703 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1704 oomPw.flush(); 1705 String oomString = oomSw.toString(); 1706 */ 1707 dropBuilder.append(stack); 1708 dropBuilder.append('\n'); 1709 dropBuilder.append('\n'); 1710 dropBuilder.append(logBuilder); 1711 dropBuilder.append('\n'); 1712 /* 1713 dropBuilder.append(oomString); 1714 dropBuilder.append('\n'); 1715 */ 1716 StringWriter catSw = new StringWriter(); 1717 synchronized (ActivityManagerService.this) { 1718 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1719 String[] emptyArgs = new String[] { }; 1720 catPw.println(); 1721 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1722 catPw.println(); 1723 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1724 false, false, null); 1725 catPw.println(); 1726 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1727 catPw.flush(); 1728 } 1729 dropBuilder.append(catSw.toString()); 1730 addErrorToDropBox("lowmem", null, "system_server", null, 1731 null, tag.toString(), dropBuilder.toString(), null, null); 1732 //Slog.i(TAG, "Sent to dropbox:"); 1733 //Slog.i(TAG, dropBuilder.toString()); 1734 synchronized (ActivityManagerService.this) { 1735 long now = SystemClock.uptimeMillis(); 1736 if (mLastMemUsageReportTime < now) { 1737 mLastMemUsageReportTime = now; 1738 } 1739 } 1740 } 1741 }; 1742 thread.start(); 1743 break; 1744 } 1745 case REPORT_USER_SWITCH_MSG: { 1746 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1747 break; 1748 } 1749 case CONTINUE_USER_SWITCH_MSG: { 1750 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1751 break; 1752 } 1753 case USER_SWITCH_TIMEOUT_MSG: { 1754 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1755 break; 1756 } 1757 case IMMERSIVE_MODE_LOCK_MSG: { 1758 final boolean nextState = (msg.arg1 != 0); 1759 if (mUpdateLock.isHeld() != nextState) { 1760 if (DEBUG_IMMERSIVE) { 1761 final ActivityRecord r = (ActivityRecord) msg.obj; 1762 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1763 } 1764 if (nextState) { 1765 mUpdateLock.acquire(); 1766 } else { 1767 mUpdateLock.release(); 1768 } 1769 } 1770 break; 1771 } 1772 case PERSIST_URI_GRANTS_MSG: { 1773 writeGrantedUriPermissions(); 1774 break; 1775 } 1776 case REQUEST_ALL_PSS_MSG: { 1777 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1778 break; 1779 } 1780 case START_PROFILES_MSG: { 1781 synchronized (ActivityManagerService.this) { 1782 startProfilesLocked(); 1783 } 1784 break; 1785 } 1786 case UPDATE_TIME: { 1787 synchronized (ActivityManagerService.this) { 1788 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1789 ProcessRecord r = mLruProcesses.get(i); 1790 if (r.thread != null) { 1791 try { 1792 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1793 } catch (RemoteException ex) { 1794 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1795 } 1796 } 1797 } 1798 } 1799 break; 1800 } 1801 case SYSTEM_USER_START_MSG: { 1802 mSystemServiceManager.startUser(msg.arg1); 1803 break; 1804 } 1805 case SYSTEM_USER_CURRENT_MSG: { 1806 mSystemServiceManager.switchUser(msg.arg1); 1807 break; 1808 } 1809 } 1810 } 1811 }; 1812 1813 static final int COLLECT_PSS_BG_MSG = 1; 1814 1815 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1816 @Override 1817 public void handleMessage(Message msg) { 1818 switch (msg.what) { 1819 case COLLECT_PSS_BG_MSG: { 1820 long start = SystemClock.uptimeMillis(); 1821 MemInfoReader memInfo = null; 1822 synchronized (ActivityManagerService.this) { 1823 if (mFullPssPending) { 1824 mFullPssPending = false; 1825 memInfo = new MemInfoReader(); 1826 } 1827 } 1828 if (memInfo != null) { 1829 updateCpuStatsNow(); 1830 long nativeTotalPss = 0; 1831 synchronized (mProcessCpuThread) { 1832 final int N = mProcessCpuTracker.countStats(); 1833 for (int j=0; j<N; j++) { 1834 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1835 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1836 // This is definitely an application process; skip it. 1837 continue; 1838 } 1839 synchronized (mPidsSelfLocked) { 1840 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1841 // This is one of our own processes; skip it. 1842 continue; 1843 } 1844 } 1845 nativeTotalPss += Debug.getPss(st.pid, null); 1846 } 1847 } 1848 memInfo.readMemInfo(); 1849 synchronized (this) { 1850 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1851 + (SystemClock.uptimeMillis()-start) + "ms"); 1852 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1853 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1854 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1855 +memInfo.getSlabSizeKb(), 1856 nativeTotalPss); 1857 } 1858 } 1859 1860 int i=0, num=0; 1861 long[] tmp = new long[1]; 1862 do { 1863 ProcessRecord proc; 1864 int procState; 1865 int pid; 1866 synchronized (ActivityManagerService.this) { 1867 if (i >= mPendingPssProcesses.size()) { 1868 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1869 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1870 mPendingPssProcesses.clear(); 1871 return; 1872 } 1873 proc = mPendingPssProcesses.get(i); 1874 procState = proc.pssProcState; 1875 if (proc.thread != null && procState == proc.setProcState) { 1876 pid = proc.pid; 1877 } else { 1878 proc = null; 1879 pid = 0; 1880 } 1881 i++; 1882 } 1883 if (proc != null) { 1884 long pss = Debug.getPss(pid, tmp); 1885 synchronized (ActivityManagerService.this) { 1886 if (proc.thread != null && proc.setProcState == procState 1887 && proc.pid == pid) { 1888 num++; 1889 proc.lastPssTime = SystemClock.uptimeMillis(); 1890 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1891 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1892 + ": " + pss + " lastPss=" + proc.lastPss 1893 + " state=" + ProcessList.makeProcStateString(procState)); 1894 if (proc.initialIdlePss == 0) { 1895 proc.initialIdlePss = pss; 1896 } 1897 proc.lastPss = pss; 1898 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1899 proc.lastCachedPss = pss; 1900 } 1901 } 1902 } 1903 } 1904 } while (true); 1905 } 1906 } 1907 } 1908 }; 1909 1910 /** 1911 * Monitor for package changes and update our internal state. 1912 */ 1913 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1914 @Override 1915 public void onPackageRemoved(String packageName, int uid) { 1916 // Remove all tasks with activities in the specified package from the list of recent tasks 1917 synchronized (ActivityManagerService.this) { 1918 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1919 TaskRecord tr = mRecentTasks.get(i); 1920 ComponentName cn = tr.intent.getComponent(); 1921 if (cn != null && cn.getPackageName().equals(packageName)) { 1922 // If the package name matches, remove the task and kill the process 1923 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1924 } 1925 } 1926 } 1927 } 1928 1929 @Override 1930 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1931 onPackageModified(packageName); 1932 return true; 1933 } 1934 1935 @Override 1936 public void onPackageModified(String packageName) { 1937 final PackageManager pm = mContext.getPackageManager(); 1938 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1939 new ArrayList<Pair<Intent, Integer>>(); 1940 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1941 // Copy the list of recent tasks so that we don't hold onto the lock on 1942 // ActivityManagerService for long periods while checking if components exist. 1943 synchronized (ActivityManagerService.this) { 1944 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1945 TaskRecord tr = mRecentTasks.get(i); 1946 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1947 } 1948 } 1949 // Check the recent tasks and filter out all tasks with components that no longer exist. 1950 Intent tmpI = new Intent(); 1951 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1952 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1953 ComponentName cn = p.first.getComponent(); 1954 if (cn != null && cn.getPackageName().equals(packageName)) { 1955 try { 1956 // Add the task to the list to remove if the component no longer exists 1957 tmpI.setComponent(cn); 1958 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1959 tasksToRemove.add(p.second); 1960 } 1961 } catch (Exception e) {} 1962 } 1963 } 1964 // Prune all the tasks with removed components from the list of recent tasks 1965 synchronized (ActivityManagerService.this) { 1966 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1967 // Remove the task but don't kill the process (since other components in that 1968 // package may still be running and in the background) 1969 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1970 } 1971 } 1972 } 1973 1974 @Override 1975 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1976 // Force stop the specified packages 1977 if (packages != null) { 1978 for (String pkg : packages) { 1979 synchronized (ActivityManagerService.this) { 1980 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1981 "finished booting")) { 1982 return true; 1983 } 1984 } 1985 } 1986 } 1987 return false; 1988 } 1989 }; 1990 1991 public void setSystemProcess() { 1992 try { 1993 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1994 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1995 ServiceManager.addService("meminfo", new MemBinder(this)); 1996 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1997 ServiceManager.addService("dbinfo", new DbBinder(this)); 1998 if (MONITOR_CPU_USAGE) { 1999 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2000 } 2001 ServiceManager.addService("permission", new PermissionController(this)); 2002 2003 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2004 "android", STOCK_PM_FLAGS); 2005 mSystemThread.installSystemApplicationInfo(info); 2006 2007 synchronized (this) { 2008 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2009 app.persistent = true; 2010 app.pid = MY_PID; 2011 app.maxAdj = ProcessList.SYSTEM_ADJ; 2012 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2013 mProcessNames.put(app.processName, app.uid, app); 2014 synchronized (mPidsSelfLocked) { 2015 mPidsSelfLocked.put(app.pid, app); 2016 } 2017 updateLruProcessLocked(app, false, null); 2018 updateOomAdjLocked(); 2019 } 2020 } catch (PackageManager.NameNotFoundException e) { 2021 throw new RuntimeException( 2022 "Unable to find android system package", e); 2023 } 2024 } 2025 2026 public void setWindowManager(WindowManagerService wm) { 2027 mWindowManager = wm; 2028 mStackSupervisor.setWindowManager(wm); 2029 } 2030 2031 public void startObservingNativeCrashes() { 2032 final NativeCrashListener ncl = new NativeCrashListener(this); 2033 ncl.start(); 2034 } 2035 2036 public IAppOpsService getAppOpsService() { 2037 return mAppOpsService; 2038 } 2039 2040 static class MemBinder extends Binder { 2041 ActivityManagerService mActivityManagerService; 2042 MemBinder(ActivityManagerService activityManagerService) { 2043 mActivityManagerService = activityManagerService; 2044 } 2045 2046 @Override 2047 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2048 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2049 != PackageManager.PERMISSION_GRANTED) { 2050 pw.println("Permission Denial: can't dump meminfo from from pid=" 2051 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2052 + " without permission " + android.Manifest.permission.DUMP); 2053 return; 2054 } 2055 2056 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2057 } 2058 } 2059 2060 static class GraphicsBinder extends Binder { 2061 ActivityManagerService mActivityManagerService; 2062 GraphicsBinder(ActivityManagerService activityManagerService) { 2063 mActivityManagerService = activityManagerService; 2064 } 2065 2066 @Override 2067 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2068 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2069 != PackageManager.PERMISSION_GRANTED) { 2070 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2071 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2072 + " without permission " + android.Manifest.permission.DUMP); 2073 return; 2074 } 2075 2076 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2077 } 2078 } 2079 2080 static class DbBinder extends Binder { 2081 ActivityManagerService mActivityManagerService; 2082 DbBinder(ActivityManagerService activityManagerService) { 2083 mActivityManagerService = activityManagerService; 2084 } 2085 2086 @Override 2087 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2088 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2089 != PackageManager.PERMISSION_GRANTED) { 2090 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2091 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2092 + " without permission " + android.Manifest.permission.DUMP); 2093 return; 2094 } 2095 2096 mActivityManagerService.dumpDbInfo(fd, pw, args); 2097 } 2098 } 2099 2100 static class CpuBinder extends Binder { 2101 ActivityManagerService mActivityManagerService; 2102 CpuBinder(ActivityManagerService activityManagerService) { 2103 mActivityManagerService = activityManagerService; 2104 } 2105 2106 @Override 2107 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2108 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2109 != PackageManager.PERMISSION_GRANTED) { 2110 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2111 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2112 + " without permission " + android.Manifest.permission.DUMP); 2113 return; 2114 } 2115 2116 synchronized (mActivityManagerService.mProcessCpuThread) { 2117 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2118 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2119 SystemClock.uptimeMillis())); 2120 } 2121 } 2122 } 2123 2124 public static final class Lifecycle extends SystemService { 2125 private final ActivityManagerService mService; 2126 2127 public Lifecycle(Context context) { 2128 super(context); 2129 mService = new ActivityManagerService(context); 2130 } 2131 2132 @Override 2133 public void onStart() { 2134 mService.start(); 2135 } 2136 2137 public ActivityManagerService getService() { 2138 return mService; 2139 } 2140 } 2141 2142 // Note: This method is invoked on the main thread but may need to attach various 2143 // handlers to other threads. So take care to be explicit about the looper. 2144 public ActivityManagerService(Context systemContext) { 2145 mContext = systemContext; 2146 mFactoryTest = FactoryTest.getMode(); 2147 mSystemThread = ActivityThread.currentActivityThread(); 2148 2149 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2150 2151 mHandlerThread = new ServiceThread(TAG, 2152 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2153 mHandlerThread.start(); 2154 mHandler = new MainHandler(mHandlerThread.getLooper()); 2155 2156 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2157 "foreground", BROADCAST_FG_TIMEOUT, false); 2158 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2159 "background", BROADCAST_BG_TIMEOUT, true); 2160 mBroadcastQueues[0] = mFgBroadcastQueue; 2161 mBroadcastQueues[1] = mBgBroadcastQueue; 2162 2163 mServices = new ActiveServices(this); 2164 mProviderMap = new ProviderMap(this); 2165 2166 // TODO: Move creation of battery stats service outside of activity manager service. 2167 File dataDir = Environment.getDataDirectory(); 2168 File systemDir = new File(dataDir, "system"); 2169 systemDir.mkdirs(); 2170 mBatteryStatsService = new BatteryStatsService(new File( 2171 systemDir, "batterystats.bin").toString(), mHandler); 2172 mBatteryStatsService.getActiveStatistics().readLocked(); 2173 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2174 mOnBattery = DEBUG_POWER ? true 2175 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2176 mBatteryStatsService.getActiveStatistics().setCallback(this); 2177 2178 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2179 2180 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2181 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2182 2183 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2184 2185 // User 0 is the first and only user that runs at boot. 2186 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2187 mUserLru.add(Integer.valueOf(0)); 2188 updateStartedUserArrayLocked(); 2189 2190 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2191 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2192 2193 mConfiguration.setToDefaults(); 2194 mConfiguration.setLocale(Locale.getDefault()); 2195 2196 mConfigurationSeq = mConfiguration.seq = 1; 2197 mProcessCpuTracker.init(); 2198 2199 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2200 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2201 mStackSupervisor = new ActivityStackSupervisor(this); 2202 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2203 2204 mProcessCpuThread = new Thread("CpuTracker") { 2205 @Override 2206 public void run() { 2207 while (true) { 2208 try { 2209 try { 2210 synchronized(this) { 2211 final long now = SystemClock.uptimeMillis(); 2212 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2213 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2214 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2215 // + ", write delay=" + nextWriteDelay); 2216 if (nextWriteDelay < nextCpuDelay) { 2217 nextCpuDelay = nextWriteDelay; 2218 } 2219 if (nextCpuDelay > 0) { 2220 mProcessCpuMutexFree.set(true); 2221 this.wait(nextCpuDelay); 2222 } 2223 } 2224 } catch (InterruptedException e) { 2225 } 2226 updateCpuStatsNow(); 2227 } catch (Exception e) { 2228 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2229 } 2230 } 2231 } 2232 }; 2233 2234 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2235 2236 Watchdog.getInstance().addMonitor(this); 2237 Watchdog.getInstance().addThread(mHandler); 2238 } 2239 2240 public void setSystemServiceManager(SystemServiceManager mgr) { 2241 mSystemServiceManager = mgr; 2242 } 2243 2244 private void start() { 2245 mProcessCpuThread.start(); 2246 2247 mBatteryStatsService.publish(mContext); 2248 mUsageStatsService.publish(mContext); 2249 mAppOpsService.publish(mContext); 2250 Slog.d("AppOps", "AppOpsService published"); 2251 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2252 } 2253 2254 public void initPowerManagement() { 2255 mStackSupervisor.initPowerManagement(); 2256 mBatteryStatsService.initPowerManagement(); 2257 } 2258 2259 @Override 2260 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2261 throws RemoteException { 2262 if (code == SYSPROPS_TRANSACTION) { 2263 // We need to tell all apps about the system property change. 2264 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2265 synchronized(this) { 2266 final int NP = mProcessNames.getMap().size(); 2267 for (int ip=0; ip<NP; ip++) { 2268 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2269 final int NA = apps.size(); 2270 for (int ia=0; ia<NA; ia++) { 2271 ProcessRecord app = apps.valueAt(ia); 2272 if (app.thread != null) { 2273 procs.add(app.thread.asBinder()); 2274 } 2275 } 2276 } 2277 } 2278 2279 int N = procs.size(); 2280 for (int i=0; i<N; i++) { 2281 Parcel data2 = Parcel.obtain(); 2282 try { 2283 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2284 } catch (RemoteException e) { 2285 } 2286 data2.recycle(); 2287 } 2288 } 2289 try { 2290 return super.onTransact(code, data, reply, flags); 2291 } catch (RuntimeException e) { 2292 // The activity manager only throws security exceptions, so let's 2293 // log all others. 2294 if (!(e instanceof SecurityException)) { 2295 Slog.wtf(TAG, "Activity Manager Crash", e); 2296 } 2297 throw e; 2298 } 2299 } 2300 2301 void updateCpuStats() { 2302 final long now = SystemClock.uptimeMillis(); 2303 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2304 return; 2305 } 2306 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2307 synchronized (mProcessCpuThread) { 2308 mProcessCpuThread.notify(); 2309 } 2310 } 2311 } 2312 2313 void updateCpuStatsNow() { 2314 synchronized (mProcessCpuThread) { 2315 mProcessCpuMutexFree.set(false); 2316 final long now = SystemClock.uptimeMillis(); 2317 boolean haveNewCpuStats = false; 2318 2319 if (MONITOR_CPU_USAGE && 2320 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2321 mLastCpuTime.set(now); 2322 haveNewCpuStats = true; 2323 mProcessCpuTracker.update(); 2324 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2325 //Slog.i(TAG, "Total CPU usage: " 2326 // + mProcessCpu.getTotalCpuPercent() + "%"); 2327 2328 // Slog the cpu usage if the property is set. 2329 if ("true".equals(SystemProperties.get("events.cpu"))) { 2330 int user = mProcessCpuTracker.getLastUserTime(); 2331 int system = mProcessCpuTracker.getLastSystemTime(); 2332 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2333 int irq = mProcessCpuTracker.getLastIrqTime(); 2334 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2335 int idle = mProcessCpuTracker.getLastIdleTime(); 2336 2337 int total = user + system + iowait + irq + softIrq + idle; 2338 if (total == 0) total = 1; 2339 2340 EventLog.writeEvent(EventLogTags.CPU, 2341 ((user+system+iowait+irq+softIrq) * 100) / total, 2342 (user * 100) / total, 2343 (system * 100) / total, 2344 (iowait * 100) / total, 2345 (irq * 100) / total, 2346 (softIrq * 100) / total); 2347 } 2348 } 2349 2350 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2351 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2352 synchronized(bstats) { 2353 synchronized(mPidsSelfLocked) { 2354 if (haveNewCpuStats) { 2355 if (mOnBattery) { 2356 int perc = bstats.startAddingCpuLocked(); 2357 int totalUTime = 0; 2358 int totalSTime = 0; 2359 final int N = mProcessCpuTracker.countStats(); 2360 for (int i=0; i<N; i++) { 2361 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2362 if (!st.working) { 2363 continue; 2364 } 2365 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2366 int otherUTime = (st.rel_utime*perc)/100; 2367 int otherSTime = (st.rel_stime*perc)/100; 2368 totalUTime += otherUTime; 2369 totalSTime += otherSTime; 2370 if (pr != null) { 2371 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2372 if (ps == null || !ps.isActive()) { 2373 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2374 pr.info.uid, pr.processName); 2375 } 2376 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2377 st.rel_stime-otherSTime); 2378 ps.addSpeedStepTimes(cpuSpeedTimes); 2379 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2380 } else { 2381 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2382 if (ps == null || !ps.isActive()) { 2383 st.batteryStats = ps = bstats.getProcessStatsLocked( 2384 bstats.mapUid(st.uid), st.name); 2385 } 2386 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2387 st.rel_stime-otherSTime); 2388 ps.addSpeedStepTimes(cpuSpeedTimes); 2389 } 2390 } 2391 bstats.finishAddingCpuLocked(perc, totalUTime, 2392 totalSTime, cpuSpeedTimes); 2393 } 2394 } 2395 } 2396 2397 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2398 mLastWriteTime = now; 2399 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2400 } 2401 } 2402 } 2403 } 2404 2405 @Override 2406 public void batteryNeedsCpuUpdate() { 2407 updateCpuStatsNow(); 2408 } 2409 2410 @Override 2411 public void batteryPowerChanged(boolean onBattery) { 2412 // When plugging in, update the CPU stats first before changing 2413 // the plug state. 2414 updateCpuStatsNow(); 2415 synchronized (this) { 2416 synchronized(mPidsSelfLocked) { 2417 mOnBattery = DEBUG_POWER ? true : onBattery; 2418 } 2419 } 2420 } 2421 2422 /** 2423 * Initialize the application bind args. These are passed to each 2424 * process when the bindApplication() IPC is sent to the process. They're 2425 * lazily setup to make sure the services are running when they're asked for. 2426 */ 2427 private HashMap<String, IBinder> getCommonServicesLocked() { 2428 if (mAppBindArgs == null) { 2429 mAppBindArgs = new HashMap<String, IBinder>(); 2430 2431 // Setup the application init args 2432 mAppBindArgs.put("package", ServiceManager.getService("package")); 2433 mAppBindArgs.put("window", ServiceManager.getService("window")); 2434 mAppBindArgs.put(Context.ALARM_SERVICE, 2435 ServiceManager.getService(Context.ALARM_SERVICE)); 2436 } 2437 return mAppBindArgs; 2438 } 2439 2440 final void setFocusedActivityLocked(ActivityRecord r) { 2441 if (mFocusedActivity != r) { 2442 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2443 mFocusedActivity = r; 2444 if (r.task != null && r.task.voiceInteractor != null) { 2445 startRunningVoiceLocked(); 2446 } else { 2447 finishRunningVoiceLocked(); 2448 } 2449 mStackSupervisor.setFocusedStack(r); 2450 if (r != null) { 2451 mWindowManager.setFocusedApp(r.appToken, true); 2452 } 2453 applyUpdateLockStateLocked(r); 2454 } 2455 } 2456 2457 final void clearFocusedActivity(ActivityRecord r) { 2458 if (mFocusedActivity == r) { 2459 mFocusedActivity = null; 2460 } 2461 } 2462 2463 @Override 2464 public void setFocusedStack(int stackId) { 2465 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2466 synchronized (ActivityManagerService.this) { 2467 ActivityStack stack = mStackSupervisor.getStack(stackId); 2468 if (stack != null) { 2469 ActivityRecord r = stack.topRunningActivityLocked(null); 2470 if (r != null) { 2471 setFocusedActivityLocked(r); 2472 } 2473 } 2474 } 2475 } 2476 2477 @Override 2478 public void notifyActivityDrawn(IBinder token) { 2479 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2480 synchronized (this) { 2481 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2482 if (r != null) { 2483 r.task.stack.notifyActivityDrawnLocked(r); 2484 } 2485 } 2486 } 2487 2488 final void applyUpdateLockStateLocked(ActivityRecord r) { 2489 // Modifications to the UpdateLock state are done on our handler, outside 2490 // the activity manager's locks. The new state is determined based on the 2491 // state *now* of the relevant activity record. The object is passed to 2492 // the handler solely for logging detail, not to be consulted/modified. 2493 final boolean nextState = r != null && r.immersive; 2494 mHandler.sendMessage( 2495 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2496 } 2497 2498 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2499 Message msg = Message.obtain(); 2500 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2501 msg.obj = r.task.askedCompatMode ? null : r; 2502 mHandler.sendMessage(msg); 2503 } 2504 2505 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2506 String what, Object obj, ProcessRecord srcApp) { 2507 app.lastActivityTime = now; 2508 2509 if (app.activities.size() > 0) { 2510 // Don't want to touch dependent processes that are hosting activities. 2511 return index; 2512 } 2513 2514 int lrui = mLruProcesses.lastIndexOf(app); 2515 if (lrui < 0) { 2516 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2517 + what + " " + obj + " from " + srcApp); 2518 return index; 2519 } 2520 2521 if (lrui >= index) { 2522 // Don't want to cause this to move dependent processes *back* in the 2523 // list as if they were less frequently used. 2524 return index; 2525 } 2526 2527 if (lrui >= mLruProcessActivityStart) { 2528 // Don't want to touch dependent processes that are hosting activities. 2529 return index; 2530 } 2531 2532 mLruProcesses.remove(lrui); 2533 if (index > 0) { 2534 index--; 2535 } 2536 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2537 + " in LRU list: " + app); 2538 mLruProcesses.add(index, app); 2539 return index; 2540 } 2541 2542 final void removeLruProcessLocked(ProcessRecord app) { 2543 int lrui = mLruProcesses.lastIndexOf(app); 2544 if (lrui >= 0) { 2545 if (lrui <= mLruProcessActivityStart) { 2546 mLruProcessActivityStart--; 2547 } 2548 if (lrui <= mLruProcessServiceStart) { 2549 mLruProcessServiceStart--; 2550 } 2551 mLruProcesses.remove(lrui); 2552 } 2553 } 2554 2555 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2556 ProcessRecord client) { 2557 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2558 || app.treatLikeActivity; 2559 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2560 if (!activityChange && hasActivity) { 2561 // The process has activities, so we are only allowing activity-based adjustments 2562 // to move it. It should be kept in the front of the list with other 2563 // processes that have activities, and we don't want those to change their 2564 // order except due to activity operations. 2565 return; 2566 } 2567 2568 mLruSeq++; 2569 final long now = SystemClock.uptimeMillis(); 2570 app.lastActivityTime = now; 2571 2572 // First a quick reject: if the app is already at the position we will 2573 // put it, then there is nothing to do. 2574 if (hasActivity) { 2575 final int N = mLruProcesses.size(); 2576 if (N > 0 && mLruProcesses.get(N-1) == app) { 2577 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2578 return; 2579 } 2580 } else { 2581 if (mLruProcessServiceStart > 0 2582 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2583 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2584 return; 2585 } 2586 } 2587 2588 int lrui = mLruProcesses.lastIndexOf(app); 2589 2590 if (app.persistent && lrui >= 0) { 2591 // We don't care about the position of persistent processes, as long as 2592 // they are in the list. 2593 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2594 return; 2595 } 2596 2597 /* In progress: compute new position first, so we can avoid doing work 2598 if the process is not actually going to move. Not yet working. 2599 int addIndex; 2600 int nextIndex; 2601 boolean inActivity = false, inService = false; 2602 if (hasActivity) { 2603 // Process has activities, put it at the very tipsy-top. 2604 addIndex = mLruProcesses.size(); 2605 nextIndex = mLruProcessServiceStart; 2606 inActivity = true; 2607 } else if (hasService) { 2608 // Process has services, put it at the top of the service list. 2609 addIndex = mLruProcessActivityStart; 2610 nextIndex = mLruProcessServiceStart; 2611 inActivity = true; 2612 inService = true; 2613 } else { 2614 // Process not otherwise of interest, it goes to the top of the non-service area. 2615 addIndex = mLruProcessServiceStart; 2616 if (client != null) { 2617 int clientIndex = mLruProcesses.lastIndexOf(client); 2618 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2619 + app); 2620 if (clientIndex >= 0 && addIndex > clientIndex) { 2621 addIndex = clientIndex; 2622 } 2623 } 2624 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2625 } 2626 2627 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2628 + mLruProcessActivityStart + "): " + app); 2629 */ 2630 2631 if (lrui >= 0) { 2632 if (lrui < mLruProcessActivityStart) { 2633 mLruProcessActivityStart--; 2634 } 2635 if (lrui < mLruProcessServiceStart) { 2636 mLruProcessServiceStart--; 2637 } 2638 /* 2639 if (addIndex > lrui) { 2640 addIndex--; 2641 } 2642 if (nextIndex > lrui) { 2643 nextIndex--; 2644 } 2645 */ 2646 mLruProcesses.remove(lrui); 2647 } 2648 2649 /* 2650 mLruProcesses.add(addIndex, app); 2651 if (inActivity) { 2652 mLruProcessActivityStart++; 2653 } 2654 if (inService) { 2655 mLruProcessActivityStart++; 2656 } 2657 */ 2658 2659 int nextIndex; 2660 if (hasActivity) { 2661 final int N = mLruProcesses.size(); 2662 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2663 // Process doesn't have activities, but has clients with 2664 // activities... move it up, but one below the top (the top 2665 // should always have a real activity). 2666 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2667 mLruProcesses.add(N-1, app); 2668 // To keep it from spamming the LRU list (by making a bunch of clients), 2669 // we will push down any other entries owned by the app. 2670 final int uid = app.info.uid; 2671 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2672 ProcessRecord subProc = mLruProcesses.get(i); 2673 if (subProc.info.uid == uid) { 2674 // We want to push this one down the list. If the process after 2675 // it is for the same uid, however, don't do so, because we don't 2676 // want them internally to be re-ordered. 2677 if (mLruProcesses.get(i-1).info.uid != uid) { 2678 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2679 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2680 ProcessRecord tmp = mLruProcesses.get(i); 2681 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2682 mLruProcesses.set(i-1, tmp); 2683 i--; 2684 } 2685 } else { 2686 // A gap, we can stop here. 2687 break; 2688 } 2689 } 2690 } else { 2691 // Process has activities, put it at the very tipsy-top. 2692 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2693 mLruProcesses.add(app); 2694 } 2695 nextIndex = mLruProcessServiceStart; 2696 } else if (hasService) { 2697 // Process has services, put it at the top of the service list. 2698 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2699 mLruProcesses.add(mLruProcessActivityStart, app); 2700 nextIndex = mLruProcessServiceStart; 2701 mLruProcessActivityStart++; 2702 } else { 2703 // Process not otherwise of interest, it goes to the top of the non-service area. 2704 int index = mLruProcessServiceStart; 2705 if (client != null) { 2706 // If there is a client, don't allow the process to be moved up higher 2707 // in the list than that client. 2708 int clientIndex = mLruProcesses.lastIndexOf(client); 2709 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2710 + " when updating " + app); 2711 if (clientIndex <= lrui) { 2712 // Don't allow the client index restriction to push it down farther in the 2713 // list than it already is. 2714 clientIndex = lrui; 2715 } 2716 if (clientIndex >= 0 && index > clientIndex) { 2717 index = clientIndex; 2718 } 2719 } 2720 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2721 mLruProcesses.add(index, app); 2722 nextIndex = index-1; 2723 mLruProcessActivityStart++; 2724 mLruProcessServiceStart++; 2725 } 2726 2727 // If the app is currently using a content provider or service, 2728 // bump those processes as well. 2729 for (int j=app.connections.size()-1; j>=0; j--) { 2730 ConnectionRecord cr = app.connections.valueAt(j); 2731 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2732 && cr.binding.service.app != null 2733 && cr.binding.service.app.lruSeq != mLruSeq 2734 && !cr.binding.service.app.persistent) { 2735 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2736 "service connection", cr, app); 2737 } 2738 } 2739 for (int j=app.conProviders.size()-1; j>=0; j--) { 2740 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2741 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2742 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2743 "provider reference", cpr, app); 2744 } 2745 } 2746 } 2747 2748 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2749 if (uid == Process.SYSTEM_UID) { 2750 // The system gets to run in any process. If there are multiple 2751 // processes with the same uid, just pick the first (this 2752 // should never happen). 2753 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2754 if (procs == null) return null; 2755 final int N = procs.size(); 2756 for (int i = 0; i < N; i++) { 2757 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2758 } 2759 } 2760 ProcessRecord proc = mProcessNames.get(processName, uid); 2761 if (false && proc != null && !keepIfLarge 2762 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2763 && proc.lastCachedPss >= 4000) { 2764 // Turn this condition on to cause killing to happen regularly, for testing. 2765 if (proc.baseProcessTracker != null) { 2766 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2767 } 2768 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2769 + "k from cached"); 2770 } else if (proc != null && !keepIfLarge 2771 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2772 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2773 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2774 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2775 if (proc.baseProcessTracker != null) { 2776 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2777 } 2778 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2779 + "k from cached"); 2780 } 2781 } 2782 return proc; 2783 } 2784 2785 void ensurePackageDexOpt(String packageName) { 2786 IPackageManager pm = AppGlobals.getPackageManager(); 2787 try { 2788 if (pm.performDexOpt(packageName)) { 2789 mDidDexOpt = true; 2790 } 2791 } catch (RemoteException e) { 2792 } 2793 } 2794 2795 boolean isNextTransitionForward() { 2796 int transit = mWindowManager.getPendingAppTransition(); 2797 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2798 || transit == AppTransition.TRANSIT_TASK_OPEN 2799 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2800 } 2801 2802 final ProcessRecord startProcessLocked(String processName, 2803 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2804 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2805 boolean isolated, boolean keepIfLarge) { 2806 ProcessRecord app; 2807 if (!isolated) { 2808 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2809 } else { 2810 // If this is an isolated process, it can't re-use an existing process. 2811 app = null; 2812 } 2813 // We don't have to do anything more if: 2814 // (1) There is an existing application record; and 2815 // (2) The caller doesn't think it is dead, OR there is no thread 2816 // object attached to it so we know it couldn't have crashed; and 2817 // (3) There is a pid assigned to it, so it is either starting or 2818 // already running. 2819 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2820 + " app=" + app + " knownToBeDead=" + knownToBeDead 2821 + " thread=" + (app != null ? app.thread : null) 2822 + " pid=" + (app != null ? app.pid : -1)); 2823 if (app != null && app.pid > 0) { 2824 if (!knownToBeDead || app.thread == null) { 2825 // We already have the app running, or are waiting for it to 2826 // come up (we have a pid but not yet its thread), so keep it. 2827 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2828 // If this is a new package in the process, add the package to the list 2829 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2830 return app; 2831 } 2832 2833 // An application record is attached to a previous process, 2834 // clean it up now. 2835 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2836 handleAppDiedLocked(app, true, true); 2837 } 2838 2839 String hostingNameStr = hostingName != null 2840 ? hostingName.flattenToShortString() : null; 2841 2842 if (!isolated) { 2843 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2844 // If we are in the background, then check to see if this process 2845 // is bad. If so, we will just silently fail. 2846 if (mBadProcesses.get(info.processName, info.uid) != null) { 2847 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2848 + "/" + info.processName); 2849 return null; 2850 } 2851 } else { 2852 // When the user is explicitly starting a process, then clear its 2853 // crash count so that we won't make it bad until they see at 2854 // least one crash dialog again, and make the process good again 2855 // if it had been bad. 2856 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2857 + "/" + info.processName); 2858 mProcessCrashTimes.remove(info.processName, info.uid); 2859 if (mBadProcesses.get(info.processName, info.uid) != null) { 2860 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2861 UserHandle.getUserId(info.uid), info.uid, 2862 info.processName); 2863 mBadProcesses.remove(info.processName, info.uid); 2864 if (app != null) { 2865 app.bad = false; 2866 } 2867 } 2868 } 2869 } 2870 2871 if (app == null) { 2872 app = newProcessRecordLocked(info, processName, isolated); 2873 if (app == null) { 2874 Slog.w(TAG, "Failed making new process record for " 2875 + processName + "/" + info.uid + " isolated=" + isolated); 2876 return null; 2877 } 2878 mProcessNames.put(processName, app.uid, app); 2879 if (isolated) { 2880 mIsolatedProcesses.put(app.uid, app); 2881 } 2882 } else { 2883 // If this is a new package in the process, add the package to the list 2884 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2885 } 2886 2887 // If the system is not ready yet, then hold off on starting this 2888 // process until it is. 2889 if (!mProcessesReady 2890 && !isAllowedWhileBooting(info) 2891 && !allowWhileBooting) { 2892 if (!mProcessesOnHold.contains(app)) { 2893 mProcessesOnHold.add(app); 2894 } 2895 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2896 return app; 2897 } 2898 2899 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2900 return (app.pid != 0) ? app : null; 2901 } 2902 2903 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2904 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2905 } 2906 2907 private final void startProcessLocked(ProcessRecord app, 2908 String hostingType, String hostingNameStr, String abiOverride) { 2909 if (app.pid > 0 && app.pid != MY_PID) { 2910 synchronized (mPidsSelfLocked) { 2911 mPidsSelfLocked.remove(app.pid); 2912 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2913 } 2914 app.setPid(0); 2915 } 2916 2917 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2918 "startProcessLocked removing on hold: " + app); 2919 mProcessesOnHold.remove(app); 2920 2921 updateCpuStats(); 2922 2923 try { 2924 int uid = app.uid; 2925 2926 int[] gids = null; 2927 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2928 if (!app.isolated) { 2929 int[] permGids = null; 2930 try { 2931 final PackageManager pm = mContext.getPackageManager(); 2932 permGids = pm.getPackageGids(app.info.packageName); 2933 2934 if (Environment.isExternalStorageEmulated()) { 2935 if (pm.checkPermission( 2936 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2937 app.info.packageName) == PERMISSION_GRANTED) { 2938 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2939 } else { 2940 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2941 } 2942 } 2943 } catch (PackageManager.NameNotFoundException e) { 2944 Slog.w(TAG, "Unable to retrieve gids", e); 2945 } 2946 2947 /* 2948 * Add shared application and profile GIDs so applications can share some 2949 * resources like shared libraries and access user-wide resources 2950 */ 2951 if (permGids == null) { 2952 gids = new int[2]; 2953 } else { 2954 gids = new int[permGids.length + 2]; 2955 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2956 } 2957 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2958 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2959 } 2960 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2961 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2962 && mTopComponent != null 2963 && app.processName.equals(mTopComponent.getPackageName())) { 2964 uid = 0; 2965 } 2966 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2967 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2968 uid = 0; 2969 } 2970 } 2971 int debugFlags = 0; 2972 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2973 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2974 // Also turn on CheckJNI for debuggable apps. It's quite 2975 // awkward to turn on otherwise. 2976 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2977 } 2978 // Run the app in safe mode if its manifest requests so or the 2979 // system is booted in safe mode. 2980 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2981 mSafeMode == true) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2989 } 2990 if ("1".equals(SystemProperties.get("debug.assert"))) { 2991 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2992 } 2993 2994 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi; 2995 if (requiredAbi == null) { 2996 requiredAbi = Build.SUPPORTED_ABIS[0]; 2997 } 2998 2999 // Start the process. It will either succeed and return a result containing 3000 // the PID of the new process, or else throw a RuntimeException. 3001 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 3002 app.processName, uid, uid, gids, debugFlags, mountExternal, 3003 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3004 3005 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 3006 synchronized (bs) { 3007 if (bs.isOnBattery()) { 3008 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 3009 } 3010 } 3011 3012 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3013 UserHandle.getUserId(uid), startResult.pid, uid, 3014 app.processName, hostingType, 3015 hostingNameStr != null ? hostingNameStr : ""); 3016 3017 if (app.persistent) { 3018 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3019 } 3020 3021 StringBuilder buf = mStringBuilder; 3022 buf.setLength(0); 3023 buf.append("Start proc "); 3024 buf.append(app.processName); 3025 buf.append(" for "); 3026 buf.append(hostingType); 3027 if (hostingNameStr != null) { 3028 buf.append(" "); 3029 buf.append(hostingNameStr); 3030 } 3031 buf.append(": pid="); 3032 buf.append(startResult.pid); 3033 buf.append(" uid="); 3034 buf.append(uid); 3035 buf.append(" gids={"); 3036 if (gids != null) { 3037 for (int gi=0; gi<gids.length; gi++) { 3038 if (gi != 0) buf.append(", "); 3039 buf.append(gids[gi]); 3040 3041 } 3042 } 3043 buf.append("}"); 3044 if (requiredAbi != null) { 3045 buf.append(" abi="); 3046 buf.append(requiredAbi); 3047 } 3048 Slog.i(TAG, buf.toString()); 3049 app.setPid(startResult.pid); 3050 app.usingWrapper = startResult.usingWrapper; 3051 app.removed = false; 3052 synchronized (mPidsSelfLocked) { 3053 this.mPidsSelfLocked.put(startResult.pid, app); 3054 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3055 msg.obj = app; 3056 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3057 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3058 } 3059 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 3060 app.processName, app.info.uid); 3061 if (app.isolated) { 3062 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3063 } 3064 } catch (RuntimeException e) { 3065 // XXX do better error recovery. 3066 app.setPid(0); 3067 Slog.e(TAG, "Failure starting process " + app.processName, e); 3068 } 3069 } 3070 3071 void updateUsageStats(ActivityRecord component, boolean resumed) { 3072 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3073 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3074 if (resumed) { 3075 mUsageStatsService.noteResumeComponent(component.realActivity); 3076 synchronized (stats) { 3077 stats.noteActivityResumedLocked(component.app.uid); 3078 } 3079 } else { 3080 mUsageStatsService.notePauseComponent(component.realActivity); 3081 synchronized (stats) { 3082 stats.noteActivityPausedLocked(component.app.uid); 3083 } 3084 } 3085 } 3086 3087 Intent getHomeIntent() { 3088 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3089 intent.setComponent(mTopComponent); 3090 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3091 intent.addCategory(Intent.CATEGORY_HOME); 3092 } 3093 return intent; 3094 } 3095 3096 boolean startHomeActivityLocked(int userId) { 3097 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3098 && mTopAction == null) { 3099 // We are running in factory test mode, but unable to find 3100 // the factory test app, so just sit around displaying the 3101 // error message and don't try to start anything. 3102 return false; 3103 } 3104 Intent intent = getHomeIntent(); 3105 ActivityInfo aInfo = 3106 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3107 if (aInfo != null) { 3108 intent.setComponent(new ComponentName( 3109 aInfo.applicationInfo.packageName, aInfo.name)); 3110 // Don't do this if the home app is currently being 3111 // instrumented. 3112 aInfo = new ActivityInfo(aInfo); 3113 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3114 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3115 aInfo.applicationInfo.uid, true); 3116 if (app == null || app.instrumentationClass == null) { 3117 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3118 mStackSupervisor.startHomeActivity(intent, aInfo); 3119 } 3120 } 3121 3122 return true; 3123 } 3124 3125 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3126 ActivityInfo ai = null; 3127 ComponentName comp = intent.getComponent(); 3128 try { 3129 if (comp != null) { 3130 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3131 } else { 3132 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3133 intent, 3134 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3135 flags, userId); 3136 3137 if (info != null) { 3138 ai = info.activityInfo; 3139 } 3140 } 3141 } catch (RemoteException e) { 3142 // ignore 3143 } 3144 3145 return ai; 3146 } 3147 3148 /** 3149 * Starts the "new version setup screen" if appropriate. 3150 */ 3151 void startSetupActivityLocked() { 3152 // Only do this once per boot. 3153 if (mCheckedForSetup) { 3154 return; 3155 } 3156 3157 // We will show this screen if the current one is a different 3158 // version than the last one shown, and we are not running in 3159 // low-level factory test mode. 3160 final ContentResolver resolver = mContext.getContentResolver(); 3161 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3162 Settings.Global.getInt(resolver, 3163 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3164 mCheckedForSetup = true; 3165 3166 // See if we should be showing the platform update setup UI. 3167 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3168 List<ResolveInfo> ris = mContext.getPackageManager() 3169 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3170 3171 // We don't allow third party apps to replace this. 3172 ResolveInfo ri = null; 3173 for (int i=0; ris != null && i<ris.size(); i++) { 3174 if ((ris.get(i).activityInfo.applicationInfo.flags 3175 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3176 ri = ris.get(i); 3177 break; 3178 } 3179 } 3180 3181 if (ri != null) { 3182 String vers = ri.activityInfo.metaData != null 3183 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3184 : null; 3185 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3186 vers = ri.activityInfo.applicationInfo.metaData.getString( 3187 Intent.METADATA_SETUP_VERSION); 3188 } 3189 String lastVers = Settings.Secure.getString( 3190 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3191 if (vers != null && !vers.equals(lastVers)) { 3192 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3193 intent.setComponent(new ComponentName( 3194 ri.activityInfo.packageName, ri.activityInfo.name)); 3195 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3196 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3197 } 3198 } 3199 } 3200 } 3201 3202 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3203 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3204 } 3205 3206 void enforceNotIsolatedCaller(String caller) { 3207 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3208 throw new SecurityException("Isolated process not allowed to call " + caller); 3209 } 3210 } 3211 3212 @Override 3213 public int getFrontActivityScreenCompatMode() { 3214 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3215 synchronized (this) { 3216 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3217 } 3218 } 3219 3220 @Override 3221 public void setFrontActivityScreenCompatMode(int mode) { 3222 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3223 "setFrontActivityScreenCompatMode"); 3224 synchronized (this) { 3225 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3226 } 3227 } 3228 3229 @Override 3230 public int getPackageScreenCompatMode(String packageName) { 3231 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3232 synchronized (this) { 3233 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3234 } 3235 } 3236 3237 @Override 3238 public void setPackageScreenCompatMode(String packageName, int mode) { 3239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3240 "setPackageScreenCompatMode"); 3241 synchronized (this) { 3242 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3243 } 3244 } 3245 3246 @Override 3247 public boolean getPackageAskScreenCompat(String packageName) { 3248 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3249 synchronized (this) { 3250 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3251 } 3252 } 3253 3254 @Override 3255 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3256 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3257 "setPackageAskScreenCompat"); 3258 synchronized (this) { 3259 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3260 } 3261 } 3262 3263 private void dispatchProcessesChanged() { 3264 int N; 3265 synchronized (this) { 3266 N = mPendingProcessChanges.size(); 3267 if (mActiveProcessChanges.length < N) { 3268 mActiveProcessChanges = new ProcessChangeItem[N]; 3269 } 3270 mPendingProcessChanges.toArray(mActiveProcessChanges); 3271 mAvailProcessChanges.addAll(mPendingProcessChanges); 3272 mPendingProcessChanges.clear(); 3273 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3274 } 3275 3276 int i = mProcessObservers.beginBroadcast(); 3277 while (i > 0) { 3278 i--; 3279 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3280 if (observer != null) { 3281 try { 3282 for (int j=0; j<N; j++) { 3283 ProcessChangeItem item = mActiveProcessChanges[j]; 3284 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3286 + item.pid + " uid=" + item.uid + ": " 3287 + item.foregroundActivities); 3288 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3289 item.foregroundActivities); 3290 } 3291 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3292 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3293 + item.pid + " uid=" + item.uid + ": " + item.processState); 3294 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3295 } 3296 } 3297 } catch (RemoteException e) { 3298 } 3299 } 3300 } 3301 mProcessObservers.finishBroadcast(); 3302 } 3303 3304 private void dispatchProcessDied(int pid, int uid) { 3305 int i = mProcessObservers.beginBroadcast(); 3306 while (i > 0) { 3307 i--; 3308 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3309 if (observer != null) { 3310 try { 3311 observer.onProcessDied(pid, uid); 3312 } catch (RemoteException e) { 3313 } 3314 } 3315 } 3316 mProcessObservers.finishBroadcast(); 3317 } 3318 3319 final void doPendingActivityLaunchesLocked(boolean doResume) { 3320 final int N = mPendingActivityLaunches.size(); 3321 if (N <= 0) { 3322 return; 3323 } 3324 for (int i=0; i<N; i++) { 3325 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3326 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3327 doResume && i == (N-1), null); 3328 } 3329 mPendingActivityLaunches.clear(); 3330 } 3331 3332 @Override 3333 public final int startActivity(IApplicationThread caller, String callingPackage, 3334 Intent intent, String resolvedType, IBinder resultTo, 3335 String resultWho, int requestCode, int startFlags, 3336 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3337 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3338 resultWho, requestCode, 3339 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3340 } 3341 3342 @Override 3343 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3344 Intent intent, String resolvedType, IBinder resultTo, 3345 String resultWho, int requestCode, int startFlags, 3346 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3347 enforceNotIsolatedCaller("startActivity"); 3348 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3349 false, true, "startActivity", null); 3350 // TODO: Switch to user app stacks here. 3351 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3352 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3353 null, null, options, userId, null); 3354 } 3355 3356 @Override 3357 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3358 Intent intent, String resolvedType, IBinder resultTo, 3359 String resultWho, int requestCode, int startFlags, String profileFile, 3360 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3361 enforceNotIsolatedCaller("startActivityAndWait"); 3362 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3363 false, true, "startActivityAndWait", null); 3364 WaitResult res = new WaitResult(); 3365 // TODO: Switch to user app stacks here. 3366 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3367 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3368 res, null, options, UserHandle.getCallingUserId(), null); 3369 return res; 3370 } 3371 3372 @Override 3373 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3374 Intent intent, String resolvedType, IBinder resultTo, 3375 String resultWho, int requestCode, int startFlags, Configuration config, 3376 Bundle options, int userId) { 3377 enforceNotIsolatedCaller("startActivityWithConfig"); 3378 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3379 false, true, "startActivityWithConfig", null); 3380 // TODO: Switch to user app stacks here. 3381 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3382 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3383 null, null, null, config, options, userId, null); 3384 return ret; 3385 } 3386 3387 @Override 3388 public int startActivityIntentSender(IApplicationThread caller, 3389 IntentSender intent, Intent fillInIntent, String resolvedType, 3390 IBinder resultTo, String resultWho, int requestCode, 3391 int flagsMask, int flagsValues, Bundle options) { 3392 enforceNotIsolatedCaller("startActivityIntentSender"); 3393 // Refuse possible leaked file descriptors 3394 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3395 throw new IllegalArgumentException("File descriptors passed in Intent"); 3396 } 3397 3398 IIntentSender sender = intent.getTarget(); 3399 if (!(sender instanceof PendingIntentRecord)) { 3400 throw new IllegalArgumentException("Bad PendingIntent object"); 3401 } 3402 3403 PendingIntentRecord pir = (PendingIntentRecord)sender; 3404 3405 synchronized (this) { 3406 // If this is coming from the currently resumed activity, it is 3407 // effectively saying that app switches are allowed at this point. 3408 final ActivityStack stack = getFocusedStack(); 3409 if (stack.mResumedActivity != null && 3410 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3411 mAppSwitchesAllowedTime = 0; 3412 } 3413 } 3414 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3415 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3416 return ret; 3417 } 3418 3419 @Override 3420 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3421 Intent intent, String resolvedType, IVoiceInteractionSession session, 3422 IVoiceInteractor interactor, int startFlags, String profileFile, 3423 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3424 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3425 != PackageManager.PERMISSION_GRANTED) { 3426 String msg = "Permission Denial: startVoiceActivity() from pid=" 3427 + Binder.getCallingPid() 3428 + ", uid=" + Binder.getCallingUid() 3429 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3430 Slog.w(TAG, msg); 3431 throw new SecurityException(msg); 3432 } 3433 if (session == null || interactor == null) { 3434 throw new NullPointerException("null session or interactor"); 3435 } 3436 userId = handleIncomingUser(callingPid, callingUid, userId, 3437 false, true, "startVoiceActivity", null); 3438 // TODO: Switch to user app stacks here. 3439 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3440 resolvedType, session, interactor, null, null, 0, startFlags, 3441 profileFile, profileFd, null, null, options, userId, null); 3442 } 3443 3444 @Override 3445 public boolean startNextMatchingActivity(IBinder callingActivity, 3446 Intent intent, Bundle options) { 3447 // Refuse possible leaked file descriptors 3448 if (intent != null && intent.hasFileDescriptors() == true) { 3449 throw new IllegalArgumentException("File descriptors passed in Intent"); 3450 } 3451 3452 synchronized (this) { 3453 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3454 if (r == null) { 3455 ActivityOptions.abort(options); 3456 return false; 3457 } 3458 if (r.app == null || r.app.thread == null) { 3459 // The caller is not running... d'oh! 3460 ActivityOptions.abort(options); 3461 return false; 3462 } 3463 intent = new Intent(intent); 3464 // The caller is not allowed to change the data. 3465 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3466 // And we are resetting to find the next component... 3467 intent.setComponent(null); 3468 3469 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3470 3471 ActivityInfo aInfo = null; 3472 try { 3473 List<ResolveInfo> resolves = 3474 AppGlobals.getPackageManager().queryIntentActivities( 3475 intent, r.resolvedType, 3476 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3477 UserHandle.getCallingUserId()); 3478 3479 // Look for the original activity in the list... 3480 final int N = resolves != null ? resolves.size() : 0; 3481 for (int i=0; i<N; i++) { 3482 ResolveInfo rInfo = resolves.get(i); 3483 if (rInfo.activityInfo.packageName.equals(r.packageName) 3484 && rInfo.activityInfo.name.equals(r.info.name)) { 3485 // We found the current one... the next matching is 3486 // after it. 3487 i++; 3488 if (i<N) { 3489 aInfo = resolves.get(i).activityInfo; 3490 } 3491 if (debug) { 3492 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3493 + "/" + r.info.name); 3494 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3495 + "/" + aInfo.name); 3496 } 3497 break; 3498 } 3499 } 3500 } catch (RemoteException e) { 3501 } 3502 3503 if (aInfo == null) { 3504 // Nobody who is next! 3505 ActivityOptions.abort(options); 3506 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3507 return false; 3508 } 3509 3510 intent.setComponent(new ComponentName( 3511 aInfo.applicationInfo.packageName, aInfo.name)); 3512 intent.setFlags(intent.getFlags()&~( 3513 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3514 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3515 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3516 Intent.FLAG_ACTIVITY_NEW_TASK)); 3517 3518 // Okay now we need to start the new activity, replacing the 3519 // currently running activity. This is a little tricky because 3520 // we want to start the new one as if the current one is finished, 3521 // but not finish the current one first so that there is no flicker. 3522 // And thus... 3523 final boolean wasFinishing = r.finishing; 3524 r.finishing = true; 3525 3526 // Propagate reply information over to the new activity. 3527 final ActivityRecord resultTo = r.resultTo; 3528 final String resultWho = r.resultWho; 3529 final int requestCode = r.requestCode; 3530 r.resultTo = null; 3531 if (resultTo != null) { 3532 resultTo.removeResultsLocked(r, resultWho, requestCode); 3533 } 3534 3535 final long origId = Binder.clearCallingIdentity(); 3536 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3537 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3538 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3539 options, false, null, null); 3540 Binder.restoreCallingIdentity(origId); 3541 3542 r.finishing = wasFinishing; 3543 if (res != ActivityManager.START_SUCCESS) { 3544 return false; 3545 } 3546 return true; 3547 } 3548 } 3549 3550 final int startActivityInPackage(int uid, String callingPackage, 3551 Intent intent, String resolvedType, IBinder resultTo, 3552 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3553 IActivityContainer container) { 3554 3555 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3556 false, true, "startActivityInPackage", null); 3557 3558 // TODO: Switch to user app stacks here. 3559 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3560 null, null, resultTo, resultWho, requestCode, startFlags, 3561 null, null, null, null, options, userId, container); 3562 return ret; 3563 } 3564 3565 @Override 3566 public final int startActivities(IApplicationThread caller, String callingPackage, 3567 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3568 int userId) { 3569 enforceNotIsolatedCaller("startActivities"); 3570 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3571 false, true, "startActivity", null); 3572 // TODO: Switch to user app stacks here. 3573 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3574 resolvedTypes, resultTo, options, userId); 3575 return ret; 3576 } 3577 3578 final int startActivitiesInPackage(int uid, String callingPackage, 3579 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3580 Bundle options, int userId) { 3581 3582 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3583 false, true, "startActivityInPackage", null); 3584 // TODO: Switch to user app stacks here. 3585 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3586 resultTo, options, userId); 3587 return ret; 3588 } 3589 3590 final void addRecentTaskLocked(TaskRecord task) { 3591 int N = mRecentTasks.size(); 3592 // Quick case: check if the top-most recent task is the same. 3593 if (N > 0 && mRecentTasks.get(0) == task) { 3594 return; 3595 } 3596 // Another quick case: never add voice sessions. 3597 if (task.voiceSession != null) { 3598 return; 3599 } 3600 // Remove any existing entries that are the same kind of task. 3601 final Intent intent = task.intent; 3602 final boolean document = intent != null && intent.isDocument(); 3603 final ComponentName comp = intent.getComponent(); 3604 3605 int maxRecents = task.maxRecents - 1; 3606 for (int i=0; i<N; i++) { 3607 TaskRecord tr = mRecentTasks.get(i); 3608 if (task != tr) { 3609 if (task.userId != tr.userId) { 3610 continue; 3611 } 3612 final Intent trIntent = tr.intent; 3613 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3614 (intent == null || !intent.filterEquals(trIntent))) { 3615 continue; 3616 } 3617 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3618 if (document && trIsDocument) { 3619 // These are the same document activity (not necessarily the same doc). 3620 if (maxRecents > 0) { 3621 --maxRecents; 3622 continue; 3623 } 3624 // Hit the maximum number of documents for this task. Fall through 3625 // and remove this document from recents. 3626 } else if (document || trIsDocument) { 3627 // Only one of these is a document. Not the droid we're looking for. 3628 continue; 3629 } 3630 } 3631 3632 // Either task and tr are the same or, their affinities match or their intents match 3633 // and neither of them is a document, or they are documents using the same activity 3634 // and their maxRecents has been reached. 3635 tr.disposeThumbnail(); 3636 mRecentTasks.remove(i); 3637 i--; 3638 N--; 3639 if (task.intent == null) { 3640 // If the new recent task we are adding is not fully 3641 // specified, then replace it with the existing recent task. 3642 task = tr; 3643 } 3644 mTaskPersister.notify(tr, false); 3645 } 3646 if (N >= MAX_RECENT_TASKS) { 3647 mRecentTasks.remove(N-1).disposeThumbnail(); 3648 } 3649 mRecentTasks.add(0, task); 3650 } 3651 3652 @Override 3653 public void reportActivityFullyDrawn(IBinder token) { 3654 synchronized (this) { 3655 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3656 if (r == null) { 3657 return; 3658 } 3659 r.reportFullyDrawnLocked(); 3660 } 3661 } 3662 3663 @Override 3664 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3665 synchronized (this) { 3666 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3667 if (r == null) { 3668 return; 3669 } 3670 final long origId = Binder.clearCallingIdentity(); 3671 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3672 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3673 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3674 if (config != null) { 3675 r.frozenBeforeDestroy = true; 3676 if (!updateConfigurationLocked(config, r, false, false)) { 3677 mStackSupervisor.resumeTopActivitiesLocked(); 3678 } 3679 } 3680 Binder.restoreCallingIdentity(origId); 3681 } 3682 } 3683 3684 @Override 3685 public int getRequestedOrientation(IBinder token) { 3686 synchronized (this) { 3687 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3688 if (r == null) { 3689 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3690 } 3691 return mWindowManager.getAppOrientation(r.appToken); 3692 } 3693 } 3694 3695 /** 3696 * This is the internal entry point for handling Activity.finish(). 3697 * 3698 * @param token The Binder token referencing the Activity we want to finish. 3699 * @param resultCode Result code, if any, from this Activity. 3700 * @param resultData Result data (Intent), if any, from this Activity. 3701 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3702 * the root Activity in the task. 3703 * 3704 * @return Returns true if the activity successfully finished, or false if it is still running. 3705 */ 3706 @Override 3707 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3708 boolean finishTask) { 3709 // Refuse possible leaked file descriptors 3710 if (resultData != null && resultData.hasFileDescriptors() == true) { 3711 throw new IllegalArgumentException("File descriptors passed in Intent"); 3712 } 3713 3714 synchronized(this) { 3715 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3716 if (r == null) { 3717 return true; 3718 } 3719 // Keep track of the root activity of the task before we finish it 3720 TaskRecord tr = r.task; 3721 ActivityRecord rootR = tr.getRootActivity(); 3722 // Do not allow task to finish in Lock Task mode. 3723 if (tr == mStackSupervisor.mLockTaskModeTask) { 3724 if (rootR == r) { 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 Binder.restoreCallingIdentity(origId); 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 boolean willActivityBeVisible(IBinder token) { 3896 synchronized(this) { 3897 ActivityStack stack = ActivityRecord.getStackLocked(token); 3898 if (stack != null) { 3899 return stack.willActivityBeVisibleLocked(token); 3900 } 3901 return false; 3902 } 3903 } 3904 3905 @Override 3906 public void overridePendingTransition(IBinder token, String packageName, 3907 int enterAnim, int exitAnim) { 3908 synchronized(this) { 3909 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3910 if (self == null) { 3911 return; 3912 } 3913 3914 final long origId = Binder.clearCallingIdentity(); 3915 3916 if (self.state == ActivityState.RESUMED 3917 || self.state == ActivityState.PAUSING) { 3918 mWindowManager.overridePendingAppTransition(packageName, 3919 enterAnim, exitAnim, null); 3920 } 3921 3922 Binder.restoreCallingIdentity(origId); 3923 } 3924 } 3925 3926 /** 3927 * Main function for removing an existing process from the activity manager 3928 * as a result of that process going away. Clears out all connections 3929 * to the process. 3930 */ 3931 private final void handleAppDiedLocked(ProcessRecord app, 3932 boolean restarting, boolean allowRestart) { 3933 int pid = app.pid; 3934 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3935 if (!restarting) { 3936 removeLruProcessLocked(app); 3937 if (pid > 0) { 3938 ProcessList.remove(pid); 3939 } 3940 } 3941 3942 if (mProfileProc == app) { 3943 clearProfilerLocked(); 3944 } 3945 3946 // Remove this application's activities from active lists. 3947 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3948 3949 app.activities.clear(); 3950 3951 if (app.instrumentationClass != null) { 3952 Slog.w(TAG, "Crash of app " + app.processName 3953 + " running instrumentation " + app.instrumentationClass); 3954 Bundle info = new Bundle(); 3955 info.putString("shortMsg", "Process crashed."); 3956 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3957 } 3958 3959 if (!restarting) { 3960 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3961 // If there was nothing to resume, and we are not already 3962 // restarting this process, but there is a visible activity that 3963 // is hosted by the process... then make sure all visible 3964 // activities are running, taking care of restarting this 3965 // process. 3966 if (hasVisibleActivities) { 3967 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3968 } 3969 } 3970 } 3971 } 3972 3973 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3974 IBinder threadBinder = thread.asBinder(); 3975 // Find the application record. 3976 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3977 ProcessRecord rec = mLruProcesses.get(i); 3978 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3979 return i; 3980 } 3981 } 3982 return -1; 3983 } 3984 3985 final ProcessRecord getRecordForAppLocked( 3986 IApplicationThread thread) { 3987 if (thread == null) { 3988 return null; 3989 } 3990 3991 int appIndex = getLRURecordIndexForAppLocked(thread); 3992 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3993 } 3994 3995 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3996 // If there are no longer any background processes running, 3997 // and the app that died was not running instrumentation, 3998 // then tell everyone we are now low on memory. 3999 boolean haveBg = false; 4000 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4001 ProcessRecord rec = mLruProcesses.get(i); 4002 if (rec.thread != null 4003 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4004 haveBg = true; 4005 break; 4006 } 4007 } 4008 4009 if (!haveBg) { 4010 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4011 if (doReport) { 4012 long now = SystemClock.uptimeMillis(); 4013 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4014 doReport = false; 4015 } else { 4016 mLastMemUsageReportTime = now; 4017 } 4018 } 4019 final ArrayList<ProcessMemInfo> memInfos 4020 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4021 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4022 long now = SystemClock.uptimeMillis(); 4023 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4024 ProcessRecord rec = mLruProcesses.get(i); 4025 if (rec == dyingProc || rec.thread == null) { 4026 continue; 4027 } 4028 if (doReport) { 4029 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4030 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4031 } 4032 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4033 // The low memory report is overriding any current 4034 // state for a GC request. Make sure to do 4035 // heavy/important/visible/foreground processes first. 4036 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4037 rec.lastRequestedGc = 0; 4038 } else { 4039 rec.lastRequestedGc = rec.lastLowMemory; 4040 } 4041 rec.reportLowMemory = true; 4042 rec.lastLowMemory = now; 4043 mProcessesToGc.remove(rec); 4044 addProcessToGcListLocked(rec); 4045 } 4046 } 4047 if (doReport) { 4048 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4049 mHandler.sendMessage(msg); 4050 } 4051 scheduleAppGcsLocked(); 4052 } 4053 } 4054 4055 final void appDiedLocked(ProcessRecord app, int pid, 4056 IApplicationThread thread) { 4057 4058 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4059 synchronized (stats) { 4060 stats.noteProcessDiedLocked(app.info.uid, pid); 4061 } 4062 4063 // Clean up already done if the process has been re-started. 4064 if (app.pid == pid && app.thread != null && 4065 app.thread.asBinder() == thread.asBinder()) { 4066 boolean doLowMem = app.instrumentationClass == null; 4067 boolean doOomAdj = doLowMem; 4068 if (!app.killedByAm) { 4069 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4070 + ") has died."); 4071 mAllowLowerMemLevel = true; 4072 } else { 4073 // Note that we always want to do oom adj to update our state with the 4074 // new number of procs. 4075 mAllowLowerMemLevel = false; 4076 doLowMem = false; 4077 } 4078 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4079 if (DEBUG_CLEANUP) Slog.v( 4080 TAG, "Dying app: " + app + ", pid: " + pid 4081 + ", thread: " + thread.asBinder()); 4082 handleAppDiedLocked(app, false, true); 4083 4084 if (doOomAdj) { 4085 updateOomAdjLocked(); 4086 } 4087 if (doLowMem) { 4088 doLowMemReportIfNeededLocked(app); 4089 } 4090 } else if (app.pid != pid) { 4091 // A new process has already been started. 4092 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4093 + ") has died and restarted (pid " + app.pid + ")."); 4094 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4095 } else if (DEBUG_PROCESSES) { 4096 Slog.d(TAG, "Received spurious death notification for thread " 4097 + thread.asBinder()); 4098 } 4099 } 4100 4101 /** 4102 * If a stack trace dump file is configured, dump process stack traces. 4103 * @param clearTraces causes the dump file to be erased prior to the new 4104 * traces being written, if true; when false, the new traces will be 4105 * appended to any existing file content. 4106 * @param firstPids of dalvik VM processes to dump stack traces for first 4107 * @param lastPids of dalvik VM processes to dump stack traces for last 4108 * @param nativeProcs optional list of native process names to dump stack crawls 4109 * @return file containing stack traces, or null if no dump file is configured 4110 */ 4111 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4112 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4113 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4114 if (tracesPath == null || tracesPath.length() == 0) { 4115 return null; 4116 } 4117 4118 File tracesFile = new File(tracesPath); 4119 try { 4120 File tracesDir = tracesFile.getParentFile(); 4121 if (!tracesDir.exists()) { 4122 tracesFile.mkdirs(); 4123 if (!SELinux.restorecon(tracesDir)) { 4124 return null; 4125 } 4126 } 4127 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4128 4129 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4130 tracesFile.createNewFile(); 4131 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4132 } catch (IOException e) { 4133 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4134 return null; 4135 } 4136 4137 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4138 return tracesFile; 4139 } 4140 4141 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4142 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4143 // Use a FileObserver to detect when traces finish writing. 4144 // The order of traces is considered important to maintain for legibility. 4145 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4146 @Override 4147 public synchronized void onEvent(int event, String path) { notify(); } 4148 }; 4149 4150 try { 4151 observer.startWatching(); 4152 4153 // First collect all of the stacks of the most important pids. 4154 if (firstPids != null) { 4155 try { 4156 int num = firstPids.size(); 4157 for (int i = 0; i < num; i++) { 4158 synchronized (observer) { 4159 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4160 observer.wait(200); // Wait for write-close, give up after 200msec 4161 } 4162 } 4163 } catch (InterruptedException e) { 4164 Log.wtf(TAG, e); 4165 } 4166 } 4167 4168 // Next collect the stacks of the native pids 4169 if (nativeProcs != null) { 4170 int[] pids = Process.getPidsForCommands(nativeProcs); 4171 if (pids != null) { 4172 for (int pid : pids) { 4173 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4174 } 4175 } 4176 } 4177 4178 // Lastly, measure CPU usage. 4179 if (processCpuTracker != null) { 4180 processCpuTracker.init(); 4181 System.gc(); 4182 processCpuTracker.update(); 4183 try { 4184 synchronized (processCpuTracker) { 4185 processCpuTracker.wait(500); // measure over 1/2 second. 4186 } 4187 } catch (InterruptedException e) { 4188 } 4189 processCpuTracker.update(); 4190 4191 // We'll take the stack crawls of just the top apps using CPU. 4192 final int N = processCpuTracker.countWorkingStats(); 4193 int numProcs = 0; 4194 for (int i=0; i<N && numProcs<5; i++) { 4195 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4196 if (lastPids.indexOfKey(stats.pid) >= 0) { 4197 numProcs++; 4198 try { 4199 synchronized (observer) { 4200 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4201 observer.wait(200); // Wait for write-close, give up after 200msec 4202 } 4203 } catch (InterruptedException e) { 4204 Log.wtf(TAG, e); 4205 } 4206 4207 } 4208 } 4209 } 4210 } finally { 4211 observer.stopWatching(); 4212 } 4213 } 4214 4215 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4216 if (true || IS_USER_BUILD) { 4217 return; 4218 } 4219 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4220 if (tracesPath == null || tracesPath.length() == 0) { 4221 return; 4222 } 4223 4224 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4225 StrictMode.allowThreadDiskWrites(); 4226 try { 4227 final File tracesFile = new File(tracesPath); 4228 final File tracesDir = tracesFile.getParentFile(); 4229 final File tracesTmp = new File(tracesDir, "__tmp__"); 4230 try { 4231 if (!tracesDir.exists()) { 4232 tracesFile.mkdirs(); 4233 if (!SELinux.restorecon(tracesDir.getPath())) { 4234 return; 4235 } 4236 } 4237 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4238 4239 if (tracesFile.exists()) { 4240 tracesTmp.delete(); 4241 tracesFile.renameTo(tracesTmp); 4242 } 4243 StringBuilder sb = new StringBuilder(); 4244 Time tobj = new Time(); 4245 tobj.set(System.currentTimeMillis()); 4246 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4247 sb.append(": "); 4248 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4249 sb.append(" since "); 4250 sb.append(msg); 4251 FileOutputStream fos = new FileOutputStream(tracesFile); 4252 fos.write(sb.toString().getBytes()); 4253 if (app == null) { 4254 fos.write("\n*** No application process!".getBytes()); 4255 } 4256 fos.close(); 4257 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4258 } catch (IOException e) { 4259 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4260 return; 4261 } 4262 4263 if (app != null) { 4264 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4265 firstPids.add(app.pid); 4266 dumpStackTraces(tracesPath, firstPids, null, null, null); 4267 } 4268 4269 File lastTracesFile = null; 4270 File curTracesFile = null; 4271 for (int i=9; i>=0; i--) { 4272 String name = String.format(Locale.US, "slow%02d.txt", i); 4273 curTracesFile = new File(tracesDir, name); 4274 if (curTracesFile.exists()) { 4275 if (lastTracesFile != null) { 4276 curTracesFile.renameTo(lastTracesFile); 4277 } else { 4278 curTracesFile.delete(); 4279 } 4280 } 4281 lastTracesFile = curTracesFile; 4282 } 4283 tracesFile.renameTo(curTracesFile); 4284 if (tracesTmp.exists()) { 4285 tracesTmp.renameTo(tracesFile); 4286 } 4287 } finally { 4288 StrictMode.setThreadPolicy(oldPolicy); 4289 } 4290 } 4291 4292 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4293 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4294 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4295 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4296 4297 if (mController != null) { 4298 try { 4299 // 0 == continue, -1 = kill process immediately 4300 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4301 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4302 } catch (RemoteException e) { 4303 mController = null; 4304 Watchdog.getInstance().setActivityController(null); 4305 } 4306 } 4307 4308 long anrTime = SystemClock.uptimeMillis(); 4309 if (MONITOR_CPU_USAGE) { 4310 updateCpuStatsNow(); 4311 } 4312 4313 synchronized (this) { 4314 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4315 if (mShuttingDown) { 4316 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4317 return; 4318 } else if (app.notResponding) { 4319 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4320 return; 4321 } else if (app.crashing) { 4322 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4323 return; 4324 } 4325 4326 // In case we come through here for the same app before completing 4327 // this one, mark as anring now so we will bail out. 4328 app.notResponding = true; 4329 4330 // Log the ANR to the event log. 4331 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4332 app.processName, app.info.flags, annotation); 4333 4334 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4335 firstPids.add(app.pid); 4336 4337 int parentPid = app.pid; 4338 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4339 if (parentPid != app.pid) firstPids.add(parentPid); 4340 4341 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4342 4343 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4344 ProcessRecord r = mLruProcesses.get(i); 4345 if (r != null && r.thread != null) { 4346 int pid = r.pid; 4347 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4348 if (r.persistent) { 4349 firstPids.add(pid); 4350 } else { 4351 lastPids.put(pid, Boolean.TRUE); 4352 } 4353 } 4354 } 4355 } 4356 } 4357 4358 // Log the ANR to the main log. 4359 StringBuilder info = new StringBuilder(); 4360 info.setLength(0); 4361 info.append("ANR in ").append(app.processName); 4362 if (activity != null && activity.shortComponentName != null) { 4363 info.append(" (").append(activity.shortComponentName).append(")"); 4364 } 4365 info.append("\n"); 4366 info.append("PID: ").append(app.pid).append("\n"); 4367 if (annotation != null) { 4368 info.append("Reason: ").append(annotation).append("\n"); 4369 } 4370 if (parent != null && parent != activity) { 4371 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4372 } 4373 4374 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4375 4376 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4377 NATIVE_STACKS_OF_INTEREST); 4378 4379 String cpuInfo = null; 4380 if (MONITOR_CPU_USAGE) { 4381 updateCpuStatsNow(); 4382 synchronized (mProcessCpuThread) { 4383 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4384 } 4385 info.append(processCpuTracker.printCurrentLoad()); 4386 info.append(cpuInfo); 4387 } 4388 4389 info.append(processCpuTracker.printCurrentState(anrTime)); 4390 4391 Slog.e(TAG, info.toString()); 4392 if (tracesFile == null) { 4393 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4394 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4395 } 4396 4397 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4398 cpuInfo, tracesFile, null); 4399 4400 if (mController != null) { 4401 try { 4402 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4403 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4404 if (res != 0) { 4405 if (res < 0 && app.pid != MY_PID) { 4406 Process.killProcess(app.pid); 4407 } else { 4408 synchronized (this) { 4409 mServices.scheduleServiceTimeoutLocked(app); 4410 } 4411 } 4412 return; 4413 } 4414 } catch (RemoteException e) { 4415 mController = null; 4416 Watchdog.getInstance().setActivityController(null); 4417 } 4418 } 4419 4420 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4421 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4422 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4423 4424 synchronized (this) { 4425 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4426 killUnneededProcessLocked(app, "background ANR"); 4427 return; 4428 } 4429 4430 // Set the app's notResponding state, and look up the errorReportReceiver 4431 makeAppNotRespondingLocked(app, 4432 activity != null ? activity.shortComponentName : null, 4433 annotation != null ? "ANR " + annotation : "ANR", 4434 info.toString()); 4435 4436 // Bring up the infamous App Not Responding dialog 4437 Message msg = Message.obtain(); 4438 HashMap<String, Object> map = new HashMap<String, Object>(); 4439 msg.what = SHOW_NOT_RESPONDING_MSG; 4440 msg.obj = map; 4441 msg.arg1 = aboveSystem ? 1 : 0; 4442 map.put("app", app); 4443 if (activity != null) { 4444 map.put("activity", activity); 4445 } 4446 4447 mHandler.sendMessage(msg); 4448 } 4449 } 4450 4451 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4452 if (!mLaunchWarningShown) { 4453 mLaunchWarningShown = true; 4454 mHandler.post(new Runnable() { 4455 @Override 4456 public void run() { 4457 synchronized (ActivityManagerService.this) { 4458 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4459 d.show(); 4460 mHandler.postDelayed(new Runnable() { 4461 @Override 4462 public void run() { 4463 synchronized (ActivityManagerService.this) { 4464 d.dismiss(); 4465 mLaunchWarningShown = false; 4466 } 4467 } 4468 }, 4000); 4469 } 4470 } 4471 }); 4472 } 4473 } 4474 4475 @Override 4476 public boolean clearApplicationUserData(final String packageName, 4477 final IPackageDataObserver observer, int userId) { 4478 enforceNotIsolatedCaller("clearApplicationUserData"); 4479 int uid = Binder.getCallingUid(); 4480 int pid = Binder.getCallingPid(); 4481 userId = handleIncomingUser(pid, uid, 4482 userId, false, true, "clearApplicationUserData", null); 4483 long callingId = Binder.clearCallingIdentity(); 4484 try { 4485 IPackageManager pm = AppGlobals.getPackageManager(); 4486 int pkgUid = -1; 4487 synchronized(this) { 4488 try { 4489 pkgUid = pm.getPackageUid(packageName, userId); 4490 } catch (RemoteException e) { 4491 } 4492 if (pkgUid == -1) { 4493 Slog.w(TAG, "Invalid packageName: " + packageName); 4494 if (observer != null) { 4495 try { 4496 observer.onRemoveCompleted(packageName, false); 4497 } catch (RemoteException e) { 4498 Slog.i(TAG, "Observer no longer exists."); 4499 } 4500 } 4501 return false; 4502 } 4503 if (uid == pkgUid || checkComponentPermission( 4504 android.Manifest.permission.CLEAR_APP_USER_DATA, 4505 pid, uid, -1, true) 4506 == PackageManager.PERMISSION_GRANTED) { 4507 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4508 } else { 4509 throw new SecurityException("PID " + pid + " does not have permission " 4510 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4511 + " of package " + packageName); 4512 } 4513 } 4514 4515 try { 4516 // Clear application user data 4517 pm.clearApplicationUserData(packageName, observer, userId); 4518 4519 // Remove all permissions granted from/to this package 4520 removeUriPermissionsForPackageLocked(packageName, userId, true); 4521 4522 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4523 Uri.fromParts("package", packageName, null)); 4524 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4525 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4526 null, null, 0, null, null, null, false, false, userId); 4527 } catch (RemoteException e) { 4528 } 4529 } finally { 4530 Binder.restoreCallingIdentity(callingId); 4531 } 4532 return true; 4533 } 4534 4535 @Override 4536 public void killBackgroundProcesses(final String packageName, int userId) { 4537 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4538 != PackageManager.PERMISSION_GRANTED && 4539 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4540 != PackageManager.PERMISSION_GRANTED) { 4541 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4542 + Binder.getCallingPid() 4543 + ", uid=" + Binder.getCallingUid() 4544 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4545 Slog.w(TAG, msg); 4546 throw new SecurityException(msg); 4547 } 4548 4549 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4550 userId, true, true, "killBackgroundProcesses", null); 4551 long callingId = Binder.clearCallingIdentity(); 4552 try { 4553 IPackageManager pm = AppGlobals.getPackageManager(); 4554 synchronized(this) { 4555 int appId = -1; 4556 try { 4557 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4558 } catch (RemoteException e) { 4559 } 4560 if (appId == -1) { 4561 Slog.w(TAG, "Invalid packageName: " + packageName); 4562 return; 4563 } 4564 killPackageProcessesLocked(packageName, appId, userId, 4565 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4566 } 4567 } finally { 4568 Binder.restoreCallingIdentity(callingId); 4569 } 4570 } 4571 4572 @Override 4573 public void killAllBackgroundProcesses() { 4574 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4575 != PackageManager.PERMISSION_GRANTED) { 4576 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4577 + Binder.getCallingPid() 4578 + ", uid=" + Binder.getCallingUid() 4579 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4580 Slog.w(TAG, msg); 4581 throw new SecurityException(msg); 4582 } 4583 4584 long callingId = Binder.clearCallingIdentity(); 4585 try { 4586 synchronized(this) { 4587 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4588 final int NP = mProcessNames.getMap().size(); 4589 for (int ip=0; ip<NP; ip++) { 4590 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4591 final int NA = apps.size(); 4592 for (int ia=0; ia<NA; ia++) { 4593 ProcessRecord app = apps.valueAt(ia); 4594 if (app.persistent) { 4595 // we don't kill persistent processes 4596 continue; 4597 } 4598 if (app.removed) { 4599 procs.add(app); 4600 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4601 app.removed = true; 4602 procs.add(app); 4603 } 4604 } 4605 } 4606 4607 int N = procs.size(); 4608 for (int i=0; i<N; i++) { 4609 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4610 } 4611 mAllowLowerMemLevel = true; 4612 updateOomAdjLocked(); 4613 doLowMemReportIfNeededLocked(null); 4614 } 4615 } finally { 4616 Binder.restoreCallingIdentity(callingId); 4617 } 4618 } 4619 4620 @Override 4621 public void forceStopPackage(final String packageName, int userId) { 4622 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4623 != PackageManager.PERMISSION_GRANTED) { 4624 String msg = "Permission Denial: forceStopPackage() from pid=" 4625 + Binder.getCallingPid() 4626 + ", uid=" + Binder.getCallingUid() 4627 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4628 Slog.w(TAG, msg); 4629 throw new SecurityException(msg); 4630 } 4631 final int callingPid = Binder.getCallingPid(); 4632 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4633 userId, true, true, "forceStopPackage", null); 4634 long callingId = Binder.clearCallingIdentity(); 4635 try { 4636 IPackageManager pm = AppGlobals.getPackageManager(); 4637 synchronized(this) { 4638 int[] users = userId == UserHandle.USER_ALL 4639 ? getUsersLocked() : new int[] { userId }; 4640 for (int user : users) { 4641 int pkgUid = -1; 4642 try { 4643 pkgUid = pm.getPackageUid(packageName, user); 4644 } catch (RemoteException e) { 4645 } 4646 if (pkgUid == -1) { 4647 Slog.w(TAG, "Invalid packageName: " + packageName); 4648 continue; 4649 } 4650 try { 4651 pm.setPackageStoppedState(packageName, true, user); 4652 } catch (RemoteException e) { 4653 } catch (IllegalArgumentException e) { 4654 Slog.w(TAG, "Failed trying to unstop package " 4655 + packageName + ": " + e); 4656 } 4657 if (isUserRunningLocked(user, false)) { 4658 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4659 } 4660 } 4661 } 4662 } finally { 4663 Binder.restoreCallingIdentity(callingId); 4664 } 4665 } 4666 4667 /* 4668 * The pkg name and app id have to be specified. 4669 */ 4670 @Override 4671 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4672 if (pkg == null) { 4673 return; 4674 } 4675 // Make sure the uid is valid. 4676 if (appid < 0) { 4677 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4678 return; 4679 } 4680 int callerUid = Binder.getCallingUid(); 4681 // Only the system server can kill an application 4682 if (callerUid == Process.SYSTEM_UID) { 4683 // Post an aysnc message to kill the application 4684 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4685 msg.arg1 = appid; 4686 msg.arg2 = 0; 4687 Bundle bundle = new Bundle(); 4688 bundle.putString("pkg", pkg); 4689 bundle.putString("reason", reason); 4690 msg.obj = bundle; 4691 mHandler.sendMessage(msg); 4692 } else { 4693 throw new SecurityException(callerUid + " cannot kill pkg: " + 4694 pkg); 4695 } 4696 } 4697 4698 @Override 4699 public void closeSystemDialogs(String reason) { 4700 enforceNotIsolatedCaller("closeSystemDialogs"); 4701 4702 final int pid = Binder.getCallingPid(); 4703 final int uid = Binder.getCallingUid(); 4704 final long origId = Binder.clearCallingIdentity(); 4705 try { 4706 synchronized (this) { 4707 // Only allow this from foreground processes, so that background 4708 // applications can't abuse it to prevent system UI from being shown. 4709 if (uid >= Process.FIRST_APPLICATION_UID) { 4710 ProcessRecord proc; 4711 synchronized (mPidsSelfLocked) { 4712 proc = mPidsSelfLocked.get(pid); 4713 } 4714 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4715 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4716 + " from background process " + proc); 4717 return; 4718 } 4719 } 4720 closeSystemDialogsLocked(reason); 4721 } 4722 } finally { 4723 Binder.restoreCallingIdentity(origId); 4724 } 4725 } 4726 4727 void closeSystemDialogsLocked(String reason) { 4728 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4729 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4730 | Intent.FLAG_RECEIVER_FOREGROUND); 4731 if (reason != null) { 4732 intent.putExtra("reason", reason); 4733 } 4734 mWindowManager.closeSystemDialogs(reason); 4735 4736 mStackSupervisor.closeSystemDialogsLocked(); 4737 4738 broadcastIntentLocked(null, null, intent, null, 4739 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4740 Process.SYSTEM_UID, UserHandle.USER_ALL); 4741 } 4742 4743 @Override 4744 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4745 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4746 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4747 for (int i=pids.length-1; i>=0; i--) { 4748 ProcessRecord proc; 4749 int oomAdj; 4750 synchronized (this) { 4751 synchronized (mPidsSelfLocked) { 4752 proc = mPidsSelfLocked.get(pids[i]); 4753 oomAdj = proc != null ? proc.setAdj : 0; 4754 } 4755 } 4756 infos[i] = new Debug.MemoryInfo(); 4757 Debug.getMemoryInfo(pids[i], infos[i]); 4758 if (proc != null) { 4759 synchronized (this) { 4760 if (proc.thread != null && proc.setAdj == oomAdj) { 4761 // Record this for posterity if the process has been stable. 4762 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4763 infos[i].getTotalUss(), false, proc.pkgList); 4764 } 4765 } 4766 } 4767 } 4768 return infos; 4769 } 4770 4771 @Override 4772 public long[] getProcessPss(int[] pids) { 4773 enforceNotIsolatedCaller("getProcessPss"); 4774 long[] pss = new long[pids.length]; 4775 for (int i=pids.length-1; i>=0; i--) { 4776 ProcessRecord proc; 4777 int oomAdj; 4778 synchronized (this) { 4779 synchronized (mPidsSelfLocked) { 4780 proc = mPidsSelfLocked.get(pids[i]); 4781 oomAdj = proc != null ? proc.setAdj : 0; 4782 } 4783 } 4784 long[] tmpUss = new long[1]; 4785 pss[i] = Debug.getPss(pids[i], tmpUss); 4786 if (proc != null) { 4787 synchronized (this) { 4788 if (proc.thread != null && proc.setAdj == oomAdj) { 4789 // Record this for posterity if the process has been stable. 4790 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4791 } 4792 } 4793 } 4794 } 4795 return pss; 4796 } 4797 4798 @Override 4799 public void killApplicationProcess(String processName, int uid) { 4800 if (processName == null) { 4801 return; 4802 } 4803 4804 int callerUid = Binder.getCallingUid(); 4805 // Only the system server can kill an application 4806 if (callerUid == Process.SYSTEM_UID) { 4807 synchronized (this) { 4808 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4809 if (app != null && app.thread != null) { 4810 try { 4811 app.thread.scheduleSuicide(); 4812 } catch (RemoteException e) { 4813 // If the other end already died, then our work here is done. 4814 } 4815 } else { 4816 Slog.w(TAG, "Process/uid not found attempting kill of " 4817 + processName + " / " + uid); 4818 } 4819 } 4820 } else { 4821 throw new SecurityException(callerUid + " cannot kill app process: " + 4822 processName); 4823 } 4824 } 4825 4826 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4827 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4828 false, true, false, false, UserHandle.getUserId(uid), reason); 4829 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4830 Uri.fromParts("package", packageName, null)); 4831 if (!mProcessesReady) { 4832 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4833 | Intent.FLAG_RECEIVER_FOREGROUND); 4834 } 4835 intent.putExtra(Intent.EXTRA_UID, uid); 4836 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4837 broadcastIntentLocked(null, null, intent, 4838 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4839 false, false, 4840 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4841 } 4842 4843 private void forceStopUserLocked(int userId, String reason) { 4844 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4845 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4846 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4847 | Intent.FLAG_RECEIVER_FOREGROUND); 4848 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4849 broadcastIntentLocked(null, null, intent, 4850 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4851 false, false, 4852 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4853 } 4854 4855 private final boolean killPackageProcessesLocked(String packageName, int appId, 4856 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4857 boolean doit, boolean evenPersistent, String reason) { 4858 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4859 4860 // Remove all processes this package may have touched: all with the 4861 // same UID (except for the system or root user), and all whose name 4862 // matches the package name. 4863 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4864 final int NP = mProcessNames.getMap().size(); 4865 for (int ip=0; ip<NP; ip++) { 4866 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4867 final int NA = apps.size(); 4868 for (int ia=0; ia<NA; ia++) { 4869 ProcessRecord app = apps.valueAt(ia); 4870 if (app.persistent && !evenPersistent) { 4871 // we don't kill persistent processes 4872 continue; 4873 } 4874 if (app.removed) { 4875 if (doit) { 4876 procs.add(app); 4877 } 4878 continue; 4879 } 4880 4881 // Skip process if it doesn't meet our oom adj requirement. 4882 if (app.setAdj < minOomAdj) { 4883 continue; 4884 } 4885 4886 // If no package is specified, we call all processes under the 4887 // give user id. 4888 if (packageName == null) { 4889 if (app.userId != userId) { 4890 continue; 4891 } 4892 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4893 continue; 4894 } 4895 // Package has been specified, we want to hit all processes 4896 // that match it. We need to qualify this by the processes 4897 // that are running under the specified app and user ID. 4898 } else { 4899 if (UserHandle.getAppId(app.uid) != appId) { 4900 continue; 4901 } 4902 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4903 continue; 4904 } 4905 if (!app.pkgList.containsKey(packageName)) { 4906 continue; 4907 } 4908 } 4909 4910 // Process has passed all conditions, kill it! 4911 if (!doit) { 4912 return true; 4913 } 4914 app.removed = true; 4915 procs.add(app); 4916 } 4917 } 4918 4919 int N = procs.size(); 4920 for (int i=0; i<N; i++) { 4921 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4922 } 4923 updateOomAdjLocked(); 4924 return N > 0; 4925 } 4926 4927 private final boolean forceStopPackageLocked(String name, int appId, 4928 boolean callerWillRestart, boolean purgeCache, boolean doit, 4929 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4930 int i; 4931 int N; 4932 4933 if (userId == UserHandle.USER_ALL && name == null) { 4934 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4935 } 4936 4937 if (appId < 0 && name != null) { 4938 try { 4939 appId = UserHandle.getAppId( 4940 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4941 } catch (RemoteException e) { 4942 } 4943 } 4944 4945 if (doit) { 4946 if (name != null) { 4947 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4948 + " user=" + userId + ": " + reason); 4949 } else { 4950 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4951 } 4952 4953 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4954 for (int ip=pmap.size()-1; ip>=0; ip--) { 4955 SparseArray<Long> ba = pmap.valueAt(ip); 4956 for (i=ba.size()-1; i>=0; i--) { 4957 boolean remove = false; 4958 final int entUid = ba.keyAt(i); 4959 if (name != null) { 4960 if (userId == UserHandle.USER_ALL) { 4961 if (UserHandle.getAppId(entUid) == appId) { 4962 remove = true; 4963 } 4964 } else { 4965 if (entUid == UserHandle.getUid(userId, appId)) { 4966 remove = true; 4967 } 4968 } 4969 } else if (UserHandle.getUserId(entUid) == userId) { 4970 remove = true; 4971 } 4972 if (remove) { 4973 ba.removeAt(i); 4974 } 4975 } 4976 if (ba.size() == 0) { 4977 pmap.removeAt(ip); 4978 } 4979 } 4980 } 4981 4982 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4983 -100, callerWillRestart, true, doit, evenPersistent, 4984 name == null ? ("stop user " + userId) : ("stop " + name)); 4985 4986 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4987 if (!doit) { 4988 return true; 4989 } 4990 didSomething = true; 4991 } 4992 4993 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4994 if (!doit) { 4995 return true; 4996 } 4997 didSomething = true; 4998 } 4999 5000 if (name == null) { 5001 // Remove all sticky broadcasts from this user. 5002 mStickyBroadcasts.remove(userId); 5003 } 5004 5005 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5006 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5007 userId, providers)) { 5008 if (!doit) { 5009 return true; 5010 } 5011 didSomething = true; 5012 } 5013 N = providers.size(); 5014 for (i=0; i<N; i++) { 5015 removeDyingProviderLocked(null, providers.get(i), true); 5016 } 5017 5018 // Remove transient permissions granted from/to this package/user 5019 removeUriPermissionsForPackageLocked(name, userId, false); 5020 5021 if (name == null || uninstalling) { 5022 // Remove pending intents. For now we only do this when force 5023 // stopping users, because we have some problems when doing this 5024 // for packages -- app widgets are not currently cleaned up for 5025 // such packages, so they can be left with bad pending intents. 5026 if (mIntentSenderRecords.size() > 0) { 5027 Iterator<WeakReference<PendingIntentRecord>> it 5028 = mIntentSenderRecords.values().iterator(); 5029 while (it.hasNext()) { 5030 WeakReference<PendingIntentRecord> wpir = it.next(); 5031 if (wpir == null) { 5032 it.remove(); 5033 continue; 5034 } 5035 PendingIntentRecord pir = wpir.get(); 5036 if (pir == null) { 5037 it.remove(); 5038 continue; 5039 } 5040 if (name == null) { 5041 // Stopping user, remove all objects for the user. 5042 if (pir.key.userId != userId) { 5043 // Not the same user, skip it. 5044 continue; 5045 } 5046 } else { 5047 if (UserHandle.getAppId(pir.uid) != appId) { 5048 // Different app id, skip it. 5049 continue; 5050 } 5051 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5052 // Different user, skip it. 5053 continue; 5054 } 5055 if (!pir.key.packageName.equals(name)) { 5056 // Different package, skip it. 5057 continue; 5058 } 5059 } 5060 if (!doit) { 5061 return true; 5062 } 5063 didSomething = true; 5064 it.remove(); 5065 pir.canceled = true; 5066 if (pir.key.activity != null) { 5067 pir.key.activity.pendingResults.remove(pir.ref); 5068 } 5069 } 5070 } 5071 } 5072 5073 if (doit) { 5074 if (purgeCache && name != null) { 5075 AttributeCache ac = AttributeCache.instance(); 5076 if (ac != null) { 5077 ac.removePackage(name); 5078 } 5079 } 5080 if (mBooted) { 5081 mStackSupervisor.resumeTopActivitiesLocked(); 5082 mStackSupervisor.scheduleIdleLocked(); 5083 } 5084 } 5085 5086 return didSomething; 5087 } 5088 5089 private final boolean removeProcessLocked(ProcessRecord app, 5090 boolean callerWillRestart, boolean allowRestart, String reason) { 5091 final String name = app.processName; 5092 final int uid = app.uid; 5093 if (DEBUG_PROCESSES) Slog.d( 5094 TAG, "Force removing proc " + app.toShortString() + " (" + name 5095 + "/" + uid + ")"); 5096 5097 mProcessNames.remove(name, uid); 5098 mIsolatedProcesses.remove(app.uid); 5099 if (mHeavyWeightProcess == app) { 5100 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5101 mHeavyWeightProcess.userId, 0)); 5102 mHeavyWeightProcess = null; 5103 } 5104 boolean needRestart = false; 5105 if (app.pid > 0 && app.pid != MY_PID) { 5106 int pid = app.pid; 5107 synchronized (mPidsSelfLocked) { 5108 mPidsSelfLocked.remove(pid); 5109 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5110 } 5111 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5112 app.processName, app.info.uid); 5113 if (app.isolated) { 5114 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5115 } 5116 killUnneededProcessLocked(app, reason); 5117 handleAppDiedLocked(app, true, allowRestart); 5118 removeLruProcessLocked(app); 5119 5120 if (app.persistent && !app.isolated) { 5121 if (!callerWillRestart) { 5122 addAppLocked(app.info, false, null /* ABI override */); 5123 } else { 5124 needRestart = true; 5125 } 5126 } 5127 } else { 5128 mRemovedProcesses.add(app); 5129 } 5130 5131 return needRestart; 5132 } 5133 5134 private final void processStartTimedOutLocked(ProcessRecord app) { 5135 final int pid = app.pid; 5136 boolean gone = false; 5137 synchronized (mPidsSelfLocked) { 5138 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5139 if (knownApp != null && knownApp.thread == null) { 5140 mPidsSelfLocked.remove(pid); 5141 gone = true; 5142 } 5143 } 5144 5145 if (gone) { 5146 Slog.w(TAG, "Process " + app + " failed to attach"); 5147 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5148 pid, app.uid, app.processName); 5149 mProcessNames.remove(app.processName, app.uid); 5150 mIsolatedProcesses.remove(app.uid); 5151 if (mHeavyWeightProcess == app) { 5152 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5153 mHeavyWeightProcess.userId, 0)); 5154 mHeavyWeightProcess = null; 5155 } 5156 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5157 app.processName, app.info.uid); 5158 if (app.isolated) { 5159 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5160 } 5161 // Take care of any launching providers waiting for this process. 5162 checkAppInLaunchingProvidersLocked(app, true); 5163 // Take care of any services that are waiting for the process. 5164 mServices.processStartTimedOutLocked(app); 5165 killUnneededProcessLocked(app, "start timeout"); 5166 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5167 Slog.w(TAG, "Unattached app died before backup, skipping"); 5168 try { 5169 IBackupManager bm = IBackupManager.Stub.asInterface( 5170 ServiceManager.getService(Context.BACKUP_SERVICE)); 5171 bm.agentDisconnected(app.info.packageName); 5172 } catch (RemoteException e) { 5173 // Can't happen; the backup manager is local 5174 } 5175 } 5176 if (isPendingBroadcastProcessLocked(pid)) { 5177 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5178 skipPendingBroadcastLocked(pid); 5179 } 5180 } else { 5181 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5182 } 5183 } 5184 5185 private final boolean attachApplicationLocked(IApplicationThread thread, 5186 int pid) { 5187 5188 // Find the application record that is being attached... either via 5189 // the pid if we are running in multiple processes, or just pull the 5190 // next app record if we are emulating process with anonymous threads. 5191 ProcessRecord app; 5192 if (pid != MY_PID && pid >= 0) { 5193 synchronized (mPidsSelfLocked) { 5194 app = mPidsSelfLocked.get(pid); 5195 } 5196 } else { 5197 app = null; 5198 } 5199 5200 if (app == null) { 5201 Slog.w(TAG, "No pending application record for pid " + pid 5202 + " (IApplicationThread " + thread + "); dropping process"); 5203 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5204 if (pid > 0 && pid != MY_PID) { 5205 Process.killProcessQuiet(pid); 5206 } else { 5207 try { 5208 thread.scheduleExit(); 5209 } catch (Exception e) { 5210 // Ignore exceptions. 5211 } 5212 } 5213 return false; 5214 } 5215 5216 // If this application record is still attached to a previous 5217 // process, clean it up now. 5218 if (app.thread != null) { 5219 handleAppDiedLocked(app, true, true); 5220 } 5221 5222 // Tell the process all about itself. 5223 5224 if (localLOGV) Slog.v( 5225 TAG, "Binding process pid " + pid + " to record " + app); 5226 5227 final String processName = app.processName; 5228 try { 5229 AppDeathRecipient adr = new AppDeathRecipient( 5230 app, pid, thread); 5231 thread.asBinder().linkToDeath(adr, 0); 5232 app.deathRecipient = adr; 5233 } catch (RemoteException e) { 5234 app.resetPackageList(mProcessStats); 5235 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5236 return false; 5237 } 5238 5239 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5240 5241 app.makeActive(thread, mProcessStats); 5242 app.curAdj = app.setAdj = -100; 5243 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5244 app.forcingToForeground = null; 5245 updateProcessForegroundLocked(app, false, false); 5246 app.hasShownUi = false; 5247 app.debugging = false; 5248 app.cached = false; 5249 5250 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5251 5252 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5253 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5254 5255 if (!normalMode) { 5256 Slog.i(TAG, "Launching preboot mode app: " + app); 5257 } 5258 5259 if (localLOGV) Slog.v( 5260 TAG, "New app record " + app 5261 + " thread=" + thread.asBinder() + " pid=" + pid); 5262 try { 5263 int testMode = IApplicationThread.DEBUG_OFF; 5264 if (mDebugApp != null && mDebugApp.equals(processName)) { 5265 testMode = mWaitForDebugger 5266 ? IApplicationThread.DEBUG_WAIT 5267 : IApplicationThread.DEBUG_ON; 5268 app.debugging = true; 5269 if (mDebugTransient) { 5270 mDebugApp = mOrigDebugApp; 5271 mWaitForDebugger = mOrigWaitForDebugger; 5272 } 5273 } 5274 String profileFile = app.instrumentationProfileFile; 5275 ParcelFileDescriptor profileFd = null; 5276 boolean profileAutoStop = false; 5277 if (mProfileApp != null && mProfileApp.equals(processName)) { 5278 mProfileProc = app; 5279 profileFile = mProfileFile; 5280 profileFd = mProfileFd; 5281 profileAutoStop = mAutoStopProfiler; 5282 } 5283 boolean enableOpenGlTrace = false; 5284 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5285 enableOpenGlTrace = true; 5286 mOpenGlTraceApp = null; 5287 } 5288 5289 // If the app is being launched for restore or full backup, set it up specially 5290 boolean isRestrictedBackupMode = false; 5291 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5292 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5293 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5294 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5295 } 5296 5297 ensurePackageDexOpt(app.instrumentationInfo != null 5298 ? app.instrumentationInfo.packageName 5299 : app.info.packageName); 5300 if (app.instrumentationClass != null) { 5301 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5302 } 5303 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5304 + processName + " with config " + mConfiguration); 5305 ApplicationInfo appInfo = app.instrumentationInfo != null 5306 ? app.instrumentationInfo : app.info; 5307 app.compat = compatibilityInfoForPackageLocked(appInfo); 5308 if (profileFd != null) { 5309 profileFd = profileFd.dup(); 5310 } 5311 thread.bindApplication(processName, appInfo, providers, 5312 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5313 app.instrumentationArguments, app.instrumentationWatcher, 5314 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5315 isRestrictedBackupMode || !normalMode, app.persistent, 5316 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5317 mCoreSettingsObserver.getCoreSettingsLocked()); 5318 updateLruProcessLocked(app, false, null); 5319 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5320 } catch (Exception e) { 5321 // todo: Yikes! What should we do? For now we will try to 5322 // start another process, but that could easily get us in 5323 // an infinite loop of restarting processes... 5324 Slog.w(TAG, "Exception thrown during bind!", e); 5325 5326 app.resetPackageList(mProcessStats); 5327 app.unlinkDeathRecipient(); 5328 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5329 return false; 5330 } 5331 5332 // Remove this record from the list of starting applications. 5333 mPersistentStartingProcesses.remove(app); 5334 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5335 "Attach application locked removing on hold: " + app); 5336 mProcessesOnHold.remove(app); 5337 5338 boolean badApp = false; 5339 boolean didSomething = false; 5340 5341 // See if the top visible activity is waiting to run in this process... 5342 if (normalMode) { 5343 try { 5344 if (mStackSupervisor.attachApplicationLocked(app)) { 5345 didSomething = true; 5346 } 5347 } catch (Exception e) { 5348 badApp = true; 5349 } 5350 } 5351 5352 // Find any services that should be running in this process... 5353 if (!badApp) { 5354 try { 5355 didSomething |= mServices.attachApplicationLocked(app, processName); 5356 } catch (Exception e) { 5357 badApp = true; 5358 } 5359 } 5360 5361 // Check if a next-broadcast receiver is in this process... 5362 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5363 try { 5364 didSomething |= sendPendingBroadcastsLocked(app); 5365 } catch (Exception e) { 5366 // If the app died trying to launch the receiver we declare it 'bad' 5367 badApp = true; 5368 } 5369 } 5370 5371 // Check whether the next backup agent is in this process... 5372 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5373 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5374 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5375 try { 5376 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5377 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5378 mBackupTarget.backupMode); 5379 } catch (Exception e) { 5380 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5381 e.printStackTrace(); 5382 } 5383 } 5384 5385 if (badApp) { 5386 // todo: Also need to kill application to deal with all 5387 // kinds of exceptions. 5388 handleAppDiedLocked(app, false, true); 5389 return false; 5390 } 5391 5392 if (!didSomething) { 5393 updateOomAdjLocked(); 5394 } 5395 5396 return true; 5397 } 5398 5399 @Override 5400 public final void attachApplication(IApplicationThread thread) { 5401 synchronized (this) { 5402 int callingPid = Binder.getCallingPid(); 5403 final long origId = Binder.clearCallingIdentity(); 5404 attachApplicationLocked(thread, callingPid); 5405 Binder.restoreCallingIdentity(origId); 5406 } 5407 } 5408 5409 @Override 5410 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5411 final long origId = Binder.clearCallingIdentity(); 5412 synchronized (this) { 5413 ActivityStack stack = ActivityRecord.getStackLocked(token); 5414 if (stack != null) { 5415 ActivityRecord r = 5416 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5417 if (stopProfiling) { 5418 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5419 try { 5420 mProfileFd.close(); 5421 } catch (IOException e) { 5422 } 5423 clearProfilerLocked(); 5424 } 5425 } 5426 } 5427 } 5428 Binder.restoreCallingIdentity(origId); 5429 } 5430 5431 void enableScreenAfterBoot() { 5432 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5433 SystemClock.uptimeMillis()); 5434 mWindowManager.enableScreenAfterBoot(); 5435 5436 synchronized (this) { 5437 updateEventDispatchingLocked(); 5438 } 5439 } 5440 5441 @Override 5442 public void showBootMessage(final CharSequence msg, final boolean always) { 5443 enforceNotIsolatedCaller("showBootMessage"); 5444 mWindowManager.showBootMessage(msg, always); 5445 } 5446 5447 @Override 5448 public void dismissKeyguardOnNextActivity() { 5449 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5450 final long token = Binder.clearCallingIdentity(); 5451 try { 5452 synchronized (this) { 5453 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5454 if (mLockScreenShown) { 5455 mLockScreenShown = false; 5456 comeOutOfSleepIfNeededLocked(); 5457 } 5458 mStackSupervisor.setDismissKeyguard(true); 5459 } 5460 } finally { 5461 Binder.restoreCallingIdentity(token); 5462 } 5463 } 5464 5465 final void finishBooting() { 5466 // Register receivers to handle package update events 5467 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5468 5469 synchronized (this) { 5470 // Ensure that any processes we had put on hold are now started 5471 // up. 5472 final int NP = mProcessesOnHold.size(); 5473 if (NP > 0) { 5474 ArrayList<ProcessRecord> procs = 5475 new ArrayList<ProcessRecord>(mProcessesOnHold); 5476 for (int ip=0; ip<NP; ip++) { 5477 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5478 + procs.get(ip)); 5479 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5480 } 5481 } 5482 5483 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5484 // Start looking for apps that are abusing wake locks. 5485 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5486 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5487 // Tell anyone interested that we are done booting! 5488 SystemProperties.set("sys.boot_completed", "1"); 5489 SystemProperties.set("dev.bootcomplete", "1"); 5490 for (int i=0; i<mStartedUsers.size(); i++) { 5491 UserStartedState uss = mStartedUsers.valueAt(i); 5492 if (uss.mState == UserStartedState.STATE_BOOTING) { 5493 uss.mState = UserStartedState.STATE_RUNNING; 5494 final int userId = mStartedUsers.keyAt(i); 5495 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5496 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5497 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5498 broadcastIntentLocked(null, null, intent, null, 5499 new IIntentReceiver.Stub() { 5500 @Override 5501 public void performReceive(Intent intent, int resultCode, 5502 String data, Bundle extras, boolean ordered, 5503 boolean sticky, int sendingUser) { 5504 synchronized (ActivityManagerService.this) { 5505 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5506 true, false); 5507 } 5508 } 5509 }, 5510 0, null, null, 5511 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5512 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5513 userId); 5514 } 5515 } 5516 scheduleStartProfilesLocked(); 5517 } 5518 } 5519 } 5520 5521 final void ensureBootCompleted() { 5522 boolean booting; 5523 boolean enableScreen; 5524 synchronized (this) { 5525 booting = mBooting; 5526 mBooting = false; 5527 enableScreen = !mBooted; 5528 mBooted = true; 5529 } 5530 5531 if (booting) { 5532 finishBooting(); 5533 } 5534 5535 if (enableScreen) { 5536 enableScreenAfterBoot(); 5537 } 5538 } 5539 5540 @Override 5541 public final void activityResumed(IBinder token) { 5542 final long origId = Binder.clearCallingIdentity(); 5543 synchronized(this) { 5544 ActivityStack stack = ActivityRecord.getStackLocked(token); 5545 if (stack != null) { 5546 ActivityRecord.activityResumedLocked(token); 5547 } 5548 } 5549 Binder.restoreCallingIdentity(origId); 5550 } 5551 5552 @Override 5553 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5554 final long origId = Binder.clearCallingIdentity(); 5555 synchronized(this) { 5556 ActivityStack stack = ActivityRecord.getStackLocked(token); 5557 if (stack != null) { 5558 stack.activityPausedLocked(token, false, persistentState); 5559 } 5560 } 5561 Binder.restoreCallingIdentity(origId); 5562 } 5563 5564 @Override 5565 public final void activityStopped(IBinder token, Bundle icicle, 5566 PersistableBundle persistentState, CharSequence description) { 5567 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5568 5569 // Refuse possible leaked file descriptors 5570 if (icicle != null && icicle.hasFileDescriptors()) { 5571 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5572 } 5573 5574 final long origId = Binder.clearCallingIdentity(); 5575 5576 synchronized (this) { 5577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5578 if (r != null) { 5579 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5580 } 5581 } 5582 5583 trimApplications(); 5584 5585 Binder.restoreCallingIdentity(origId); 5586 } 5587 5588 @Override 5589 public final void activityDestroyed(IBinder token) { 5590 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5591 synchronized (this) { 5592 ActivityStack stack = ActivityRecord.getStackLocked(token); 5593 if (stack != null) { 5594 stack.activityDestroyedLocked(token); 5595 } 5596 } 5597 } 5598 5599 @Override 5600 public String getCallingPackage(IBinder token) { 5601 synchronized (this) { 5602 ActivityRecord r = getCallingRecordLocked(token); 5603 return r != null ? r.info.packageName : null; 5604 } 5605 } 5606 5607 @Override 5608 public ComponentName getCallingActivity(IBinder token) { 5609 synchronized (this) { 5610 ActivityRecord r = getCallingRecordLocked(token); 5611 return r != null ? r.intent.getComponent() : null; 5612 } 5613 } 5614 5615 private ActivityRecord getCallingRecordLocked(IBinder token) { 5616 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5617 if (r == null) { 5618 return null; 5619 } 5620 return r.resultTo; 5621 } 5622 5623 @Override 5624 public ComponentName getActivityClassForToken(IBinder token) { 5625 synchronized(this) { 5626 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5627 if (r == null) { 5628 return null; 5629 } 5630 return r.intent.getComponent(); 5631 } 5632 } 5633 5634 @Override 5635 public String getPackageForToken(IBinder token) { 5636 synchronized(this) { 5637 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5638 if (r == null) { 5639 return null; 5640 } 5641 return r.packageName; 5642 } 5643 } 5644 5645 @Override 5646 public IIntentSender getIntentSender(int type, 5647 String packageName, IBinder token, String resultWho, 5648 int requestCode, Intent[] intents, String[] resolvedTypes, 5649 int flags, Bundle options, int userId) { 5650 enforceNotIsolatedCaller("getIntentSender"); 5651 // Refuse possible leaked file descriptors 5652 if (intents != null) { 5653 if (intents.length < 1) { 5654 throw new IllegalArgumentException("Intents array length must be >= 1"); 5655 } 5656 for (int i=0; i<intents.length; i++) { 5657 Intent intent = intents[i]; 5658 if (intent != null) { 5659 if (intent.hasFileDescriptors()) { 5660 throw new IllegalArgumentException("File descriptors passed in Intent"); 5661 } 5662 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5663 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5664 throw new IllegalArgumentException( 5665 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5666 } 5667 intents[i] = new Intent(intent); 5668 } 5669 } 5670 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5671 throw new IllegalArgumentException( 5672 "Intent array length does not match resolvedTypes length"); 5673 } 5674 } 5675 if (options != null) { 5676 if (options.hasFileDescriptors()) { 5677 throw new IllegalArgumentException("File descriptors passed in options"); 5678 } 5679 } 5680 5681 synchronized(this) { 5682 int callingUid = Binder.getCallingUid(); 5683 int origUserId = userId; 5684 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5685 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5686 "getIntentSender", null); 5687 if (origUserId == UserHandle.USER_CURRENT) { 5688 // We don't want to evaluate this until the pending intent is 5689 // actually executed. However, we do want to always do the 5690 // security checking for it above. 5691 userId = UserHandle.USER_CURRENT; 5692 } 5693 try { 5694 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5695 int uid = AppGlobals.getPackageManager() 5696 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5697 if (!UserHandle.isSameApp(callingUid, uid)) { 5698 String msg = "Permission Denial: getIntentSender() from pid=" 5699 + Binder.getCallingPid() 5700 + ", uid=" + Binder.getCallingUid() 5701 + ", (need uid=" + uid + ")" 5702 + " is not allowed to send as package " + packageName; 5703 Slog.w(TAG, msg); 5704 throw new SecurityException(msg); 5705 } 5706 } 5707 5708 return getIntentSenderLocked(type, packageName, callingUid, userId, 5709 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5710 5711 } catch (RemoteException e) { 5712 throw new SecurityException(e); 5713 } 5714 } 5715 } 5716 5717 IIntentSender getIntentSenderLocked(int type, String packageName, 5718 int callingUid, int userId, IBinder token, String resultWho, 5719 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5720 Bundle options) { 5721 if (DEBUG_MU) 5722 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5723 ActivityRecord activity = null; 5724 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5725 activity = ActivityRecord.isInStackLocked(token); 5726 if (activity == null) { 5727 return null; 5728 } 5729 if (activity.finishing) { 5730 return null; 5731 } 5732 } 5733 5734 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5735 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5736 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5737 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5738 |PendingIntent.FLAG_UPDATE_CURRENT); 5739 5740 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5741 type, packageName, activity, resultWho, 5742 requestCode, intents, resolvedTypes, flags, options, userId); 5743 WeakReference<PendingIntentRecord> ref; 5744 ref = mIntentSenderRecords.get(key); 5745 PendingIntentRecord rec = ref != null ? ref.get() : null; 5746 if (rec != null) { 5747 if (!cancelCurrent) { 5748 if (updateCurrent) { 5749 if (rec.key.requestIntent != null) { 5750 rec.key.requestIntent.replaceExtras(intents != null ? 5751 intents[intents.length - 1] : null); 5752 } 5753 if (intents != null) { 5754 intents[intents.length-1] = rec.key.requestIntent; 5755 rec.key.allIntents = intents; 5756 rec.key.allResolvedTypes = resolvedTypes; 5757 } else { 5758 rec.key.allIntents = null; 5759 rec.key.allResolvedTypes = null; 5760 } 5761 } 5762 return rec; 5763 } 5764 rec.canceled = true; 5765 mIntentSenderRecords.remove(key); 5766 } 5767 if (noCreate) { 5768 return rec; 5769 } 5770 rec = new PendingIntentRecord(this, key, callingUid); 5771 mIntentSenderRecords.put(key, rec.ref); 5772 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5773 if (activity.pendingResults == null) { 5774 activity.pendingResults 5775 = new HashSet<WeakReference<PendingIntentRecord>>(); 5776 } 5777 activity.pendingResults.add(rec.ref); 5778 } 5779 return rec; 5780 } 5781 5782 @Override 5783 public void cancelIntentSender(IIntentSender sender) { 5784 if (!(sender instanceof PendingIntentRecord)) { 5785 return; 5786 } 5787 synchronized(this) { 5788 PendingIntentRecord rec = (PendingIntentRecord)sender; 5789 try { 5790 int uid = AppGlobals.getPackageManager() 5791 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5792 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5793 String msg = "Permission Denial: cancelIntentSender() from pid=" 5794 + Binder.getCallingPid() 5795 + ", uid=" + Binder.getCallingUid() 5796 + " is not allowed to cancel packges " 5797 + rec.key.packageName; 5798 Slog.w(TAG, msg); 5799 throw new SecurityException(msg); 5800 } 5801 } catch (RemoteException e) { 5802 throw new SecurityException(e); 5803 } 5804 cancelIntentSenderLocked(rec, true); 5805 } 5806 } 5807 5808 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5809 rec.canceled = true; 5810 mIntentSenderRecords.remove(rec.key); 5811 if (cleanActivity && rec.key.activity != null) { 5812 rec.key.activity.pendingResults.remove(rec.ref); 5813 } 5814 } 5815 5816 @Override 5817 public String getPackageForIntentSender(IIntentSender pendingResult) { 5818 if (!(pendingResult instanceof PendingIntentRecord)) { 5819 return null; 5820 } 5821 try { 5822 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5823 return res.key.packageName; 5824 } catch (ClassCastException e) { 5825 } 5826 return null; 5827 } 5828 5829 @Override 5830 public int getUidForIntentSender(IIntentSender sender) { 5831 if (sender instanceof PendingIntentRecord) { 5832 try { 5833 PendingIntentRecord res = (PendingIntentRecord)sender; 5834 return res.uid; 5835 } catch (ClassCastException e) { 5836 } 5837 } 5838 return -1; 5839 } 5840 5841 @Override 5842 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5843 if (!(pendingResult instanceof PendingIntentRecord)) { 5844 return false; 5845 } 5846 try { 5847 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5848 if (res.key.allIntents == null) { 5849 return false; 5850 } 5851 for (int i=0; i<res.key.allIntents.length; i++) { 5852 Intent intent = res.key.allIntents[i]; 5853 if (intent.getPackage() != null && intent.getComponent() != null) { 5854 return false; 5855 } 5856 } 5857 return true; 5858 } catch (ClassCastException e) { 5859 } 5860 return false; 5861 } 5862 5863 @Override 5864 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5865 if (!(pendingResult instanceof PendingIntentRecord)) { 5866 return false; 5867 } 5868 try { 5869 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5870 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5871 return true; 5872 } 5873 return false; 5874 } catch (ClassCastException e) { 5875 } 5876 return false; 5877 } 5878 5879 @Override 5880 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5881 if (!(pendingResult instanceof PendingIntentRecord)) { 5882 return null; 5883 } 5884 try { 5885 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5886 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5887 } catch (ClassCastException e) { 5888 } 5889 return null; 5890 } 5891 5892 @Override 5893 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5894 if (!(pendingResult instanceof PendingIntentRecord)) { 5895 return null; 5896 } 5897 try { 5898 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5899 Intent intent = res.key.requestIntent; 5900 if (intent != null) { 5901 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5902 || res.lastTagPrefix.equals(prefix))) { 5903 return res.lastTag; 5904 } 5905 res.lastTagPrefix = prefix; 5906 StringBuilder sb = new StringBuilder(128); 5907 if (prefix != null) { 5908 sb.append(prefix); 5909 } 5910 if (intent.getAction() != null) { 5911 sb.append(intent.getAction()); 5912 } else if (intent.getComponent() != null) { 5913 intent.getComponent().appendShortString(sb); 5914 } else { 5915 sb.append("?"); 5916 } 5917 return res.lastTag = sb.toString(); 5918 } 5919 } catch (ClassCastException e) { 5920 } 5921 return null; 5922 } 5923 5924 @Override 5925 public void setProcessLimit(int max) { 5926 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5927 "setProcessLimit()"); 5928 synchronized (this) { 5929 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5930 mProcessLimitOverride = max; 5931 } 5932 trimApplications(); 5933 } 5934 5935 @Override 5936 public int getProcessLimit() { 5937 synchronized (this) { 5938 return mProcessLimitOverride; 5939 } 5940 } 5941 5942 void foregroundTokenDied(ForegroundToken token) { 5943 synchronized (ActivityManagerService.this) { 5944 synchronized (mPidsSelfLocked) { 5945 ForegroundToken cur 5946 = mForegroundProcesses.get(token.pid); 5947 if (cur != token) { 5948 return; 5949 } 5950 mForegroundProcesses.remove(token.pid); 5951 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5952 if (pr == null) { 5953 return; 5954 } 5955 pr.forcingToForeground = null; 5956 updateProcessForegroundLocked(pr, false, false); 5957 } 5958 updateOomAdjLocked(); 5959 } 5960 } 5961 5962 @Override 5963 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5964 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5965 "setProcessForeground()"); 5966 synchronized(this) { 5967 boolean changed = false; 5968 5969 synchronized (mPidsSelfLocked) { 5970 ProcessRecord pr = mPidsSelfLocked.get(pid); 5971 if (pr == null && isForeground) { 5972 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5973 return; 5974 } 5975 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5976 if (oldToken != null) { 5977 oldToken.token.unlinkToDeath(oldToken, 0); 5978 mForegroundProcesses.remove(pid); 5979 if (pr != null) { 5980 pr.forcingToForeground = null; 5981 } 5982 changed = true; 5983 } 5984 if (isForeground && token != null) { 5985 ForegroundToken newToken = new ForegroundToken() { 5986 @Override 5987 public void binderDied() { 5988 foregroundTokenDied(this); 5989 } 5990 }; 5991 newToken.pid = pid; 5992 newToken.token = token; 5993 try { 5994 token.linkToDeath(newToken, 0); 5995 mForegroundProcesses.put(pid, newToken); 5996 pr.forcingToForeground = token; 5997 changed = true; 5998 } catch (RemoteException e) { 5999 // If the process died while doing this, we will later 6000 // do the cleanup with the process death link. 6001 } 6002 } 6003 } 6004 6005 if (changed) { 6006 updateOomAdjLocked(); 6007 } 6008 } 6009 } 6010 6011 // ========================================================= 6012 // PERMISSIONS 6013 // ========================================================= 6014 6015 static class PermissionController extends IPermissionController.Stub { 6016 ActivityManagerService mActivityManagerService; 6017 PermissionController(ActivityManagerService activityManagerService) { 6018 mActivityManagerService = activityManagerService; 6019 } 6020 6021 @Override 6022 public boolean checkPermission(String permission, int pid, int uid) { 6023 return mActivityManagerService.checkPermission(permission, pid, 6024 uid) == PackageManager.PERMISSION_GRANTED; 6025 } 6026 } 6027 6028 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6029 @Override 6030 public int checkComponentPermission(String permission, int pid, int uid, 6031 int owningUid, boolean exported) { 6032 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6033 owningUid, exported); 6034 } 6035 6036 @Override 6037 public Object getAMSLock() { 6038 return ActivityManagerService.this; 6039 } 6040 } 6041 6042 /** 6043 * This can be called with or without the global lock held. 6044 */ 6045 int checkComponentPermission(String permission, int pid, int uid, 6046 int owningUid, boolean exported) { 6047 // We might be performing an operation on behalf of an indirect binder 6048 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6049 // client identity accordingly before proceeding. 6050 Identity tlsIdentity = sCallerIdentity.get(); 6051 if (tlsIdentity != null) { 6052 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6053 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6054 uid = tlsIdentity.uid; 6055 pid = tlsIdentity.pid; 6056 } 6057 6058 if (pid == MY_PID) { 6059 return PackageManager.PERMISSION_GRANTED; 6060 } 6061 6062 return ActivityManager.checkComponentPermission(permission, uid, 6063 owningUid, exported); 6064 } 6065 6066 /** 6067 * As the only public entry point for permissions checking, this method 6068 * can enforce the semantic that requesting a check on a null global 6069 * permission is automatically denied. (Internally a null permission 6070 * string is used when calling {@link #checkComponentPermission} in cases 6071 * when only uid-based security is needed.) 6072 * 6073 * This can be called with or without the global lock held. 6074 */ 6075 @Override 6076 public int checkPermission(String permission, int pid, int uid) { 6077 if (permission == null) { 6078 return PackageManager.PERMISSION_DENIED; 6079 } 6080 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6081 } 6082 6083 /** 6084 * Binder IPC calls go through the public entry point. 6085 * This can be called with or without the global lock held. 6086 */ 6087 int checkCallingPermission(String permission) { 6088 return checkPermission(permission, 6089 Binder.getCallingPid(), 6090 UserHandle.getAppId(Binder.getCallingUid())); 6091 } 6092 6093 /** 6094 * This can be called with or without the global lock held. 6095 */ 6096 void enforceCallingPermission(String permission, String func) { 6097 if (checkCallingPermission(permission) 6098 == PackageManager.PERMISSION_GRANTED) { 6099 return; 6100 } 6101 6102 String msg = "Permission Denial: " + func + " from pid=" 6103 + Binder.getCallingPid() 6104 + ", uid=" + Binder.getCallingUid() 6105 + " requires " + permission; 6106 Slog.w(TAG, msg); 6107 throw new SecurityException(msg); 6108 } 6109 6110 /** 6111 * Determine if UID is holding permissions required to access {@link Uri} in 6112 * the given {@link ProviderInfo}. Final permission checking is always done 6113 * in {@link ContentProvider}. 6114 */ 6115 private final boolean checkHoldingPermissionsLocked( 6116 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6117 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6118 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6119 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6120 return false; 6121 } 6122 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6123 } 6124 6125 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6126 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6127 if (pi.applicationInfo.uid == uid) { 6128 return true; 6129 } else if (!pi.exported) { 6130 return false; 6131 } 6132 6133 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6134 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6135 try { 6136 // check if target holds top-level <provider> permissions 6137 if (!readMet && pi.readPermission != null && considerUidPermissions 6138 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6139 readMet = true; 6140 } 6141 if (!writeMet && pi.writePermission != null && considerUidPermissions 6142 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6143 writeMet = true; 6144 } 6145 6146 // track if unprotected read/write is allowed; any denied 6147 // <path-permission> below removes this ability 6148 boolean allowDefaultRead = pi.readPermission == null; 6149 boolean allowDefaultWrite = pi.writePermission == null; 6150 6151 // check if target holds any <path-permission> that match uri 6152 final PathPermission[] pps = pi.pathPermissions; 6153 if (pps != null) { 6154 final String path = grantUri.uri.getPath(); 6155 int i = pps.length; 6156 while (i > 0 && (!readMet || !writeMet)) { 6157 i--; 6158 PathPermission pp = pps[i]; 6159 if (pp.match(path)) { 6160 if (!readMet) { 6161 final String pprperm = pp.getReadPermission(); 6162 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6163 + pprperm + " for " + pp.getPath() 6164 + ": match=" + pp.match(path) 6165 + " check=" + pm.checkUidPermission(pprperm, uid)); 6166 if (pprperm != null) { 6167 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6168 == PERMISSION_GRANTED) { 6169 readMet = true; 6170 } else { 6171 allowDefaultRead = false; 6172 } 6173 } 6174 } 6175 if (!writeMet) { 6176 final String ppwperm = pp.getWritePermission(); 6177 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6178 + ppwperm + " for " + pp.getPath() 6179 + ": match=" + pp.match(path) 6180 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6181 if (ppwperm != null) { 6182 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6183 == PERMISSION_GRANTED) { 6184 writeMet = true; 6185 } else { 6186 allowDefaultWrite = false; 6187 } 6188 } 6189 } 6190 } 6191 } 6192 } 6193 6194 // grant unprotected <provider> read/write, if not blocked by 6195 // <path-permission> above 6196 if (allowDefaultRead) readMet = true; 6197 if (allowDefaultWrite) writeMet = true; 6198 6199 } catch (RemoteException e) { 6200 return false; 6201 } 6202 6203 return readMet && writeMet; 6204 } 6205 6206 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6207 ProviderInfo pi = null; 6208 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6209 if (cpr != null) { 6210 pi = cpr.info; 6211 } else { 6212 try { 6213 pi = AppGlobals.getPackageManager().resolveContentProvider( 6214 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6215 } catch (RemoteException ex) { 6216 } 6217 } 6218 return pi; 6219 } 6220 6221 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6222 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6223 if (targetUris != null) { 6224 return targetUris.get(grantUri); 6225 } 6226 return null; 6227 } 6228 6229 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6230 String targetPkg, int targetUid, GrantUri grantUri) { 6231 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6232 if (targetUris == null) { 6233 targetUris = Maps.newArrayMap(); 6234 mGrantedUriPermissions.put(targetUid, targetUris); 6235 } 6236 6237 UriPermission perm = targetUris.get(grantUri); 6238 if (perm == null) { 6239 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6240 targetUris.put(grantUri, perm); 6241 } 6242 6243 return perm; 6244 } 6245 6246 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6247 final int modeFlags) { 6248 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6249 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6250 : UriPermission.STRENGTH_OWNED; 6251 6252 // Root gets to do everything. 6253 if (uid == 0) { 6254 return true; 6255 } 6256 6257 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6258 if (perms == null) return false; 6259 6260 // First look for exact match 6261 final UriPermission exactPerm = perms.get(grantUri); 6262 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6263 return true; 6264 } 6265 6266 // No exact match, look for prefixes 6267 final int N = perms.size(); 6268 for (int i = 0; i < N; i++) { 6269 final UriPermission perm = perms.valueAt(i); 6270 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6271 && perm.getStrength(modeFlags) >= minStrength) { 6272 return true; 6273 } 6274 } 6275 6276 return false; 6277 } 6278 6279 @Override 6280 public int checkUriPermission(Uri uri, int pid, int uid, 6281 final int modeFlags, int userId) { 6282 enforceNotIsolatedCaller("checkUriPermission"); 6283 6284 // Another redirected-binder-call permissions check as in 6285 // {@link checkComponentPermission}. 6286 Identity tlsIdentity = sCallerIdentity.get(); 6287 if (tlsIdentity != null) { 6288 uid = tlsIdentity.uid; 6289 pid = tlsIdentity.pid; 6290 } 6291 6292 // Our own process gets to do everything. 6293 if (pid == MY_PID) { 6294 return PackageManager.PERMISSION_GRANTED; 6295 } 6296 synchronized (this) { 6297 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6298 ? PackageManager.PERMISSION_GRANTED 6299 : PackageManager.PERMISSION_DENIED; 6300 } 6301 } 6302 6303 /** 6304 * Check if the targetPkg can be granted permission to access uri by 6305 * the callingUid using the given modeFlags. Throws a security exception 6306 * if callingUid is not allowed to do this. Returns the uid of the target 6307 * if the URI permission grant should be performed; returns -1 if it is not 6308 * needed (for example targetPkg already has permission to access the URI). 6309 * If you already know the uid of the target, you can supply it in 6310 * lastTargetUid else set that to -1. 6311 */ 6312 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6313 final int modeFlags, int lastTargetUid) { 6314 if (!Intent.isAccessUriMode(modeFlags)) { 6315 return -1; 6316 } 6317 6318 if (targetPkg != null) { 6319 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6320 "Checking grant " + targetPkg + " permission to " + grantUri); 6321 } 6322 6323 final IPackageManager pm = AppGlobals.getPackageManager(); 6324 6325 // If this is not a content: uri, we can't do anything with it. 6326 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6327 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6328 "Can't grant URI permission for non-content URI: " + grantUri); 6329 return -1; 6330 } 6331 6332 final String authority = grantUri.uri.getAuthority(); 6333 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6334 if (pi == null) { 6335 Slog.w(TAG, "No content provider found for permission check: " + 6336 grantUri.uri.toSafeString()); 6337 return -1; 6338 } 6339 6340 int targetUid = lastTargetUid; 6341 if (targetUid < 0 && targetPkg != null) { 6342 try { 6343 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6344 if (targetUid < 0) { 6345 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6346 "Can't grant URI permission no uid for: " + targetPkg); 6347 return -1; 6348 } 6349 } catch (RemoteException ex) { 6350 return -1; 6351 } 6352 } 6353 6354 if (targetUid >= 0) { 6355 // First... does the target actually need this permission? 6356 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6357 // No need to grant the target this permission. 6358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6359 "Target " + targetPkg + " already has full permission to " + grantUri); 6360 return -1; 6361 } 6362 } else { 6363 // First... there is no target package, so can anyone access it? 6364 boolean allowed = pi.exported; 6365 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6366 if (pi.readPermission != null) { 6367 allowed = false; 6368 } 6369 } 6370 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6371 if (pi.writePermission != null) { 6372 allowed = false; 6373 } 6374 } 6375 if (allowed) { 6376 return -1; 6377 } 6378 } 6379 6380 /* There is a special cross user grant if: 6381 * - The target is on another user. 6382 * - Apps on the current user can access the uri without any uid permissions. 6383 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6384 * grant uri permissions. 6385 */ 6386 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6387 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6388 modeFlags, false /*without considering the uid permissions*/); 6389 6390 // Second... is the provider allowing granting of URI permissions? 6391 if (!specialCrossUserGrant) { 6392 if (!pi.grantUriPermissions) { 6393 throw new SecurityException("Provider " + pi.packageName 6394 + "/" + pi.name 6395 + " does not allow granting of Uri permissions (uri " 6396 + grantUri + ")"); 6397 } 6398 if (pi.uriPermissionPatterns != null) { 6399 final int N = pi.uriPermissionPatterns.length; 6400 boolean allowed = false; 6401 for (int i=0; i<N; i++) { 6402 if (pi.uriPermissionPatterns[i] != null 6403 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6404 allowed = true; 6405 break; 6406 } 6407 } 6408 if (!allowed) { 6409 throw new SecurityException("Provider " + pi.packageName 6410 + "/" + pi.name 6411 + " does not allow granting of permission to path of Uri " 6412 + grantUri); 6413 } 6414 } 6415 } 6416 6417 // Third... does the caller itself have permission to access 6418 // this uri? 6419 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6420 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6421 // Require they hold a strong enough Uri permission 6422 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6423 throw new SecurityException("Uid " + callingUid 6424 + " does not have permission to uri " + grantUri); 6425 } 6426 } 6427 } 6428 return targetUid; 6429 } 6430 6431 @Override 6432 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6433 final int modeFlags, int userId) { 6434 enforceNotIsolatedCaller("checkGrantUriPermission"); 6435 synchronized(this) { 6436 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6437 new GrantUri(userId, uri, false), modeFlags, -1); 6438 } 6439 } 6440 6441 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6442 final int modeFlags, UriPermissionOwner owner) { 6443 if (!Intent.isAccessUriMode(modeFlags)) { 6444 return; 6445 } 6446 6447 // So here we are: the caller has the assumed permission 6448 // to the uri, and the target doesn't. Let's now give this to 6449 // the target. 6450 6451 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6452 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6453 6454 final String authority = grantUri.uri.getAuthority(); 6455 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6456 if (pi == null) { 6457 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6458 return; 6459 } 6460 6461 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6462 grantUri.prefix = true; 6463 } 6464 final UriPermission perm = findOrCreateUriPermissionLocked( 6465 pi.packageName, targetPkg, targetUid, grantUri); 6466 perm.grantModes(modeFlags, owner); 6467 } 6468 6469 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6470 final int modeFlags, UriPermissionOwner owner) { 6471 if (targetPkg == null) { 6472 throw new NullPointerException("targetPkg"); 6473 } 6474 6475 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6476 -1); 6477 if (targetUid < 0) { 6478 return; 6479 } 6480 6481 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6482 owner); 6483 } 6484 6485 static class NeededUriGrants extends ArrayList<GrantUri> { 6486 final String targetPkg; 6487 final int targetUid; 6488 final int flags; 6489 6490 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6491 this.targetPkg = targetPkg; 6492 this.targetUid = targetUid; 6493 this.flags = flags; 6494 } 6495 } 6496 6497 /** 6498 * Like checkGrantUriPermissionLocked, but takes an Intent. 6499 */ 6500 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6501 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6502 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6503 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6504 + " clip=" + (intent != null ? intent.getClipData() : null) 6505 + " from " + intent + "; flags=0x" 6506 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6507 6508 if (targetPkg == null) { 6509 throw new NullPointerException("targetPkg"); 6510 } 6511 6512 if (intent == null) { 6513 return null; 6514 } 6515 Uri data = intent.getData(); 6516 ClipData clip = intent.getClipData(); 6517 if (data == null && clip == null) { 6518 return null; 6519 } 6520 final IPackageManager pm = AppGlobals.getPackageManager(); 6521 int targetUid; 6522 if (needed != null) { 6523 targetUid = needed.targetUid; 6524 } else { 6525 try { 6526 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6527 } catch (RemoteException ex) { 6528 return null; 6529 } 6530 if (targetUid < 0) { 6531 if (DEBUG_URI_PERMISSION) { 6532 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6533 + " on user " + targetUserId); 6534 } 6535 return null; 6536 } 6537 } 6538 if (data != null) { 6539 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6540 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6541 targetUid); 6542 if (targetUid > 0) { 6543 if (needed == null) { 6544 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6545 } 6546 needed.add(grantUri); 6547 } 6548 } 6549 if (clip != null) { 6550 for (int i=0; i<clip.getItemCount(); i++) { 6551 Uri uri = clip.getItemAt(i).getUri(); 6552 if (uri != null) { 6553 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6554 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6555 targetUid); 6556 if (targetUid > 0) { 6557 if (needed == null) { 6558 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6559 } 6560 needed.add(grantUri); 6561 } 6562 } else { 6563 Intent clipIntent = clip.getItemAt(i).getIntent(); 6564 if (clipIntent != null) { 6565 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6566 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6567 if (newNeeded != null) { 6568 needed = newNeeded; 6569 } 6570 } 6571 } 6572 } 6573 } 6574 6575 return needed; 6576 } 6577 6578 /** 6579 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6580 */ 6581 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6582 UriPermissionOwner owner) { 6583 if (needed != null) { 6584 for (int i=0; i<needed.size(); i++) { 6585 GrantUri grantUri = needed.get(i); 6586 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6587 grantUri, needed.flags, owner); 6588 } 6589 } 6590 } 6591 6592 void grantUriPermissionFromIntentLocked(int callingUid, 6593 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6594 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6595 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6596 if (needed == null) { 6597 return; 6598 } 6599 6600 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6601 } 6602 6603 @Override 6604 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6605 final int modeFlags, int userId) { 6606 enforceNotIsolatedCaller("grantUriPermission"); 6607 GrantUri grantUri = new GrantUri(userId, uri, false); 6608 synchronized(this) { 6609 final ProcessRecord r = getRecordForAppLocked(caller); 6610 if (r == null) { 6611 throw new SecurityException("Unable to find app for caller " 6612 + caller 6613 + " when granting permission to uri " + grantUri); 6614 } 6615 if (targetPkg == null) { 6616 throw new IllegalArgumentException("null target"); 6617 } 6618 if (grantUri == null) { 6619 throw new IllegalArgumentException("null uri"); 6620 } 6621 6622 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6623 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6624 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6625 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6626 6627 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6628 } 6629 } 6630 6631 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6632 if (perm.modeFlags == 0) { 6633 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6634 perm.targetUid); 6635 if (perms != null) { 6636 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6637 "Removing " + perm.targetUid + " permission to " + perm.uri); 6638 6639 perms.remove(perm.uri); 6640 if (perms.isEmpty()) { 6641 mGrantedUriPermissions.remove(perm.targetUid); 6642 } 6643 } 6644 } 6645 } 6646 6647 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6648 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6649 6650 final IPackageManager pm = AppGlobals.getPackageManager(); 6651 final String authority = grantUri.uri.getAuthority(); 6652 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6653 if (pi == null) { 6654 Slog.w(TAG, "No content provider found for permission revoke: " 6655 + grantUri.toSafeString()); 6656 return; 6657 } 6658 6659 // Does the caller have this permission on the URI? 6660 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6661 // Right now, if you are not the original owner of the permission, 6662 // you are not allowed to revoke it. 6663 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6664 throw new SecurityException("Uid " + callingUid 6665 + " does not have permission to uri " + grantUri); 6666 //} 6667 } 6668 6669 boolean persistChanged = false; 6670 6671 // Go through all of the permissions and remove any that match. 6672 int N = mGrantedUriPermissions.size(); 6673 for (int i = 0; i < N; i++) { 6674 final int targetUid = mGrantedUriPermissions.keyAt(i); 6675 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6676 6677 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6678 final UriPermission perm = it.next(); 6679 if (perm.uri.sourceUserId == grantUri.sourceUserId 6680 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6681 if (DEBUG_URI_PERMISSION) 6682 Slog.v(TAG, 6683 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6684 persistChanged |= perm.revokeModes( 6685 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6686 if (perm.modeFlags == 0) { 6687 it.remove(); 6688 } 6689 } 6690 } 6691 6692 if (perms.isEmpty()) { 6693 mGrantedUriPermissions.remove(targetUid); 6694 N--; 6695 i--; 6696 } 6697 } 6698 6699 if (persistChanged) { 6700 schedulePersistUriGrants(); 6701 } 6702 } 6703 6704 @Override 6705 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6706 int userId) { 6707 enforceNotIsolatedCaller("revokeUriPermission"); 6708 synchronized(this) { 6709 final ProcessRecord r = getRecordForAppLocked(caller); 6710 if (r == null) { 6711 throw new SecurityException("Unable to find app for caller " 6712 + caller 6713 + " when revoking permission to uri " + uri); 6714 } 6715 if (uri == null) { 6716 Slog.w(TAG, "revokeUriPermission: null uri"); 6717 return; 6718 } 6719 6720 if (!Intent.isAccessUriMode(modeFlags)) { 6721 return; 6722 } 6723 6724 final IPackageManager pm = AppGlobals.getPackageManager(); 6725 final String authority = uri.getAuthority(); 6726 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6727 if (pi == null) { 6728 Slog.w(TAG, "No content provider found for permission revoke: " 6729 + uri.toSafeString()); 6730 return; 6731 } 6732 6733 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6734 } 6735 } 6736 6737 /** 6738 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6739 * given package. 6740 * 6741 * @param packageName Package name to match, or {@code null} to apply to all 6742 * packages. 6743 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6744 * to all users. 6745 * @param persistable If persistable grants should be removed. 6746 */ 6747 private void removeUriPermissionsForPackageLocked( 6748 String packageName, int userHandle, boolean persistable) { 6749 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6750 throw new IllegalArgumentException("Must narrow by either package or user"); 6751 } 6752 6753 boolean persistChanged = false; 6754 6755 int N = mGrantedUriPermissions.size(); 6756 for (int i = 0; i < N; i++) { 6757 final int targetUid = mGrantedUriPermissions.keyAt(i); 6758 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6759 6760 // Only inspect grants matching user 6761 if (userHandle == UserHandle.USER_ALL 6762 || userHandle == UserHandle.getUserId(targetUid)) { 6763 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6764 final UriPermission perm = it.next(); 6765 6766 // Only inspect grants matching package 6767 if (packageName == null || perm.sourcePkg.equals(packageName) 6768 || perm.targetPkg.equals(packageName)) { 6769 persistChanged |= perm.revokeModes( 6770 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6771 6772 // Only remove when no modes remain; any persisted grants 6773 // will keep this alive. 6774 if (perm.modeFlags == 0) { 6775 it.remove(); 6776 } 6777 } 6778 } 6779 6780 if (perms.isEmpty()) { 6781 mGrantedUriPermissions.remove(targetUid); 6782 N--; 6783 i--; 6784 } 6785 } 6786 } 6787 6788 if (persistChanged) { 6789 schedulePersistUriGrants(); 6790 } 6791 } 6792 6793 @Override 6794 public IBinder newUriPermissionOwner(String name) { 6795 enforceNotIsolatedCaller("newUriPermissionOwner"); 6796 synchronized(this) { 6797 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6798 return owner.getExternalTokenLocked(); 6799 } 6800 } 6801 6802 @Override 6803 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6804 final int modeFlags, int userId) { 6805 synchronized(this) { 6806 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6807 if (owner == null) { 6808 throw new IllegalArgumentException("Unknown owner: " + token); 6809 } 6810 if (fromUid != Binder.getCallingUid()) { 6811 if (Binder.getCallingUid() != Process.myUid()) { 6812 // Only system code can grant URI permissions on behalf 6813 // of other users. 6814 throw new SecurityException("nice try"); 6815 } 6816 } 6817 if (targetPkg == null) { 6818 throw new IllegalArgumentException("null target"); 6819 } 6820 if (uri == null) { 6821 throw new IllegalArgumentException("null uri"); 6822 } 6823 6824 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6825 modeFlags, owner); 6826 } 6827 } 6828 6829 @Override 6830 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6831 synchronized(this) { 6832 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6833 if (owner == null) { 6834 throw new IllegalArgumentException("Unknown owner: " + token); 6835 } 6836 6837 if (uri == null) { 6838 owner.removeUriPermissionsLocked(mode); 6839 } else { 6840 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6841 } 6842 } 6843 } 6844 6845 private void schedulePersistUriGrants() { 6846 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6847 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6848 10 * DateUtils.SECOND_IN_MILLIS); 6849 } 6850 } 6851 6852 private void writeGrantedUriPermissions() { 6853 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6854 6855 // Snapshot permissions so we can persist without lock 6856 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6857 synchronized (this) { 6858 final int size = mGrantedUriPermissions.size(); 6859 for (int i = 0; i < size; i++) { 6860 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6861 for (UriPermission perm : perms.values()) { 6862 if (perm.persistedModeFlags != 0) { 6863 persist.add(perm.snapshot()); 6864 } 6865 } 6866 } 6867 } 6868 6869 FileOutputStream fos = null; 6870 try { 6871 fos = mGrantFile.startWrite(); 6872 6873 XmlSerializer out = new FastXmlSerializer(); 6874 out.setOutput(fos, "utf-8"); 6875 out.startDocument(null, true); 6876 out.startTag(null, TAG_URI_GRANTS); 6877 for (UriPermission.Snapshot perm : persist) { 6878 out.startTag(null, TAG_URI_GRANT); 6879 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6880 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6881 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6882 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6883 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6884 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6885 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6886 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6887 out.endTag(null, TAG_URI_GRANT); 6888 } 6889 out.endTag(null, TAG_URI_GRANTS); 6890 out.endDocument(); 6891 6892 mGrantFile.finishWrite(fos); 6893 } catch (IOException e) { 6894 if (fos != null) { 6895 mGrantFile.failWrite(fos); 6896 } 6897 } 6898 } 6899 6900 private void readGrantedUriPermissionsLocked() { 6901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6902 6903 final long now = System.currentTimeMillis(); 6904 6905 FileInputStream fis = null; 6906 try { 6907 fis = mGrantFile.openRead(); 6908 final XmlPullParser in = Xml.newPullParser(); 6909 in.setInput(fis, null); 6910 6911 int type; 6912 while ((type = in.next()) != END_DOCUMENT) { 6913 final String tag = in.getName(); 6914 if (type == START_TAG) { 6915 if (TAG_URI_GRANT.equals(tag)) { 6916 final int sourceUserId; 6917 final int targetUserId; 6918 final int userHandle = readIntAttribute(in, 6919 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6920 if (userHandle != UserHandle.USER_NULL) { 6921 // For backwards compatibility. 6922 sourceUserId = userHandle; 6923 targetUserId = userHandle; 6924 } else { 6925 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6926 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6927 } 6928 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6929 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6930 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6931 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6932 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6933 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6934 6935 // Sanity check that provider still belongs to source package 6936 final ProviderInfo pi = getProviderInfoLocked( 6937 uri.getAuthority(), sourceUserId); 6938 if (pi != null && sourcePkg.equals(pi.packageName)) { 6939 int targetUid = -1; 6940 try { 6941 targetUid = AppGlobals.getPackageManager() 6942 .getPackageUid(targetPkg, targetUserId); 6943 } catch (RemoteException e) { 6944 } 6945 if (targetUid != -1) { 6946 final UriPermission perm = findOrCreateUriPermissionLocked( 6947 sourcePkg, targetPkg, targetUid, 6948 new GrantUri(sourceUserId, uri, prefix)); 6949 perm.initPersistedModes(modeFlags, createdTime); 6950 } 6951 } else { 6952 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6953 + " but instead found " + pi); 6954 } 6955 } 6956 } 6957 } 6958 } catch (FileNotFoundException e) { 6959 // Missing grants is okay 6960 } catch (IOException e) { 6961 Log.wtf(TAG, "Failed reading Uri grants", e); 6962 } catch (XmlPullParserException e) { 6963 Log.wtf(TAG, "Failed reading Uri grants", e); 6964 } finally { 6965 IoUtils.closeQuietly(fis); 6966 } 6967 } 6968 6969 @Override 6970 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6971 enforceNotIsolatedCaller("takePersistableUriPermission"); 6972 6973 Preconditions.checkFlagsArgument(modeFlags, 6974 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6975 6976 synchronized (this) { 6977 final int callingUid = Binder.getCallingUid(); 6978 boolean persistChanged = false; 6979 GrantUri grantUri = new GrantUri(userId, uri, false); 6980 6981 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6982 new GrantUri(userId, uri, false)); 6983 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6984 new GrantUri(userId, uri, true)); 6985 6986 final boolean exactValid = (exactPerm != null) 6987 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6988 final boolean prefixValid = (prefixPerm != null) 6989 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6990 6991 if (!(exactValid || prefixValid)) { 6992 throw new SecurityException("No persistable permission grants found for UID " 6993 + callingUid + " and Uri " + grantUri.toSafeString()); 6994 } 6995 6996 if (exactValid) { 6997 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6998 } 6999 if (prefixValid) { 7000 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7001 } 7002 7003 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7004 7005 if (persistChanged) { 7006 schedulePersistUriGrants(); 7007 } 7008 } 7009 } 7010 7011 @Override 7012 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7013 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7014 7015 Preconditions.checkFlagsArgument(modeFlags, 7016 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7017 7018 synchronized (this) { 7019 final int callingUid = Binder.getCallingUid(); 7020 boolean persistChanged = false; 7021 7022 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7023 new GrantUri(userId, uri, false)); 7024 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7025 new GrantUri(userId, uri, true)); 7026 if (exactPerm == null && prefixPerm == null) { 7027 throw new SecurityException("No permission grants found for UID " + callingUid 7028 + " and Uri " + uri.toSafeString()); 7029 } 7030 7031 if (exactPerm != null) { 7032 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7033 removeUriPermissionIfNeededLocked(exactPerm); 7034 } 7035 if (prefixPerm != null) { 7036 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7037 removeUriPermissionIfNeededLocked(prefixPerm); 7038 } 7039 7040 if (persistChanged) { 7041 schedulePersistUriGrants(); 7042 } 7043 } 7044 } 7045 7046 /** 7047 * Prune any older {@link UriPermission} for the given UID until outstanding 7048 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7049 * 7050 * @return if any mutations occured that require persisting. 7051 */ 7052 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7053 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7054 if (perms == null) return false; 7055 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7056 7057 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7058 for (UriPermission perm : perms.values()) { 7059 if (perm.persistedModeFlags != 0) { 7060 persisted.add(perm); 7061 } 7062 } 7063 7064 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7065 if (trimCount <= 0) return false; 7066 7067 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7068 for (int i = 0; i < trimCount; i++) { 7069 final UriPermission perm = persisted.get(i); 7070 7071 if (DEBUG_URI_PERMISSION) { 7072 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7073 } 7074 7075 perm.releasePersistableModes(~0); 7076 removeUriPermissionIfNeededLocked(perm); 7077 } 7078 7079 return true; 7080 } 7081 7082 @Override 7083 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7084 String packageName, boolean incoming) { 7085 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7086 Preconditions.checkNotNull(packageName, "packageName"); 7087 7088 final int callingUid = Binder.getCallingUid(); 7089 final IPackageManager pm = AppGlobals.getPackageManager(); 7090 try { 7091 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7092 if (packageUid != callingUid) { 7093 throw new SecurityException( 7094 "Package " + packageName + " does not belong to calling UID " + callingUid); 7095 } 7096 } catch (RemoteException e) { 7097 throw new SecurityException("Failed to verify package name ownership"); 7098 } 7099 7100 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7101 synchronized (this) { 7102 if (incoming) { 7103 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7104 callingUid); 7105 if (perms == null) { 7106 Slog.w(TAG, "No permission grants found for " + packageName); 7107 } else { 7108 for (UriPermission perm : perms.values()) { 7109 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7110 result.add(perm.buildPersistedPublicApiObject()); 7111 } 7112 } 7113 } 7114 } else { 7115 final int size = mGrantedUriPermissions.size(); 7116 for (int i = 0; i < size; i++) { 7117 final ArrayMap<GrantUri, UriPermission> perms = 7118 mGrantedUriPermissions.valueAt(i); 7119 for (UriPermission perm : perms.values()) { 7120 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7121 result.add(perm.buildPersistedPublicApiObject()); 7122 } 7123 } 7124 } 7125 } 7126 } 7127 return new ParceledListSlice<android.content.UriPermission>(result); 7128 } 7129 7130 @Override 7131 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7132 synchronized (this) { 7133 ProcessRecord app = 7134 who != null ? getRecordForAppLocked(who) : null; 7135 if (app == null) return; 7136 7137 Message msg = Message.obtain(); 7138 msg.what = WAIT_FOR_DEBUGGER_MSG; 7139 msg.obj = app; 7140 msg.arg1 = waiting ? 1 : 0; 7141 mHandler.sendMessage(msg); 7142 } 7143 } 7144 7145 @Override 7146 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7147 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7148 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7149 outInfo.availMem = Process.getFreeMemory(); 7150 outInfo.totalMem = Process.getTotalMemory(); 7151 outInfo.threshold = homeAppMem; 7152 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7153 outInfo.hiddenAppThreshold = cachedAppMem; 7154 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7155 ProcessList.SERVICE_ADJ); 7156 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7157 ProcessList.VISIBLE_APP_ADJ); 7158 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7159 ProcessList.FOREGROUND_APP_ADJ); 7160 } 7161 7162 // ========================================================= 7163 // TASK MANAGEMENT 7164 // ========================================================= 7165 7166 @Override 7167 public List<IAppTask> getAppTasks() { 7168 int callingUid = Binder.getCallingUid(); 7169 long ident = Binder.clearCallingIdentity(); 7170 synchronized(this) { 7171 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7172 try { 7173 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7174 7175 final int N = mRecentTasks.size(); 7176 for (int i = 0; i < N; i++) { 7177 TaskRecord tr = mRecentTasks.get(i); 7178 // Skip tasks that are not created by the caller 7179 if (tr.creatorUid == callingUid) { 7180 ActivityManager.RecentTaskInfo taskInfo = 7181 createRecentTaskInfoFromTaskRecord(tr); 7182 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7183 list.add(taskImpl); 7184 } 7185 } 7186 } finally { 7187 Binder.restoreCallingIdentity(ident); 7188 } 7189 return list; 7190 } 7191 } 7192 7193 @Override 7194 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7195 final int callingUid = Binder.getCallingUid(); 7196 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7197 7198 synchronized(this) { 7199 if (localLOGV) Slog.v( 7200 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7201 7202 final boolean allowed = checkCallingPermission( 7203 android.Manifest.permission.GET_TASKS) 7204 == PackageManager.PERMISSION_GRANTED; 7205 if (!allowed) { 7206 Slog.w(TAG, "getTasks: caller " + callingUid 7207 + " does not hold GET_TASKS; limiting output"); 7208 } 7209 7210 // TODO: Improve with MRU list from all ActivityStacks. 7211 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7212 } 7213 7214 return list; 7215 } 7216 7217 TaskRecord getMostRecentTask() { 7218 return mRecentTasks.get(0); 7219 } 7220 7221 /** 7222 * Creates a new RecentTaskInfo from a TaskRecord. 7223 */ 7224 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7225 // Update the task description to reflect any changes in the task stack 7226 tr.updateTaskDescription(); 7227 7228 // Compose the recent task info 7229 ActivityManager.RecentTaskInfo rti 7230 = new ActivityManager.RecentTaskInfo(); 7231 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7232 rti.persistentId = tr.taskId; 7233 rti.baseIntent = new Intent(tr.getBaseIntent()); 7234 rti.origActivity = tr.origActivity; 7235 rti.description = tr.lastDescription; 7236 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7237 rti.userId = tr.userId; 7238 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7239 rti.lastActiveTime = tr.lastActiveTime; 7240 return rti; 7241 } 7242 7243 @Override 7244 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7245 int flags, int userId) { 7246 final int callingUid = Binder.getCallingUid(); 7247 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7248 false, true, "getRecentTasks", null); 7249 7250 synchronized (this) { 7251 final boolean allowed = checkCallingPermission( 7252 android.Manifest.permission.GET_TASKS) 7253 == PackageManager.PERMISSION_GRANTED; 7254 if (!allowed) { 7255 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7256 + " does not hold GET_TASKS; limiting output"); 7257 } 7258 final boolean detailed = checkCallingPermission( 7259 android.Manifest.permission.GET_DETAILED_TASKS) 7260 == PackageManager.PERMISSION_GRANTED; 7261 7262 IPackageManager pm = AppGlobals.getPackageManager(); 7263 7264 final int N = mRecentTasks.size(); 7265 ArrayList<ActivityManager.RecentTaskInfo> res 7266 = new ArrayList<ActivityManager.RecentTaskInfo>( 7267 maxNum < N ? maxNum : N); 7268 7269 final Set<Integer> includedUsers; 7270 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7271 includedUsers = getProfileIdsLocked(userId); 7272 } else { 7273 includedUsers = new HashSet<Integer>(); 7274 } 7275 includedUsers.add(Integer.valueOf(userId)); 7276 for (int i=0; i<N && maxNum > 0; i++) { 7277 TaskRecord tr = mRecentTasks.get(i); 7278 // Only add calling user or related users recent tasks 7279 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7280 7281 // Return the entry if desired by the caller. We always return 7282 // the first entry, because callers always expect this to be the 7283 // foreground app. We may filter others if the caller has 7284 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7285 // we should exclude the entry. 7286 7287 if (i == 0 7288 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7289 || (tr.intent == null) 7290 || ((tr.intent.getFlags() 7291 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7292 if (!allowed) { 7293 // If the caller doesn't have the GET_TASKS permission, then only 7294 // allow them to see a small subset of tasks -- their own and home. 7295 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7296 continue; 7297 } 7298 } 7299 if (tr.intent != null && 7300 (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) 7301 != 0 && tr.getTopActivity() == null) { 7302 // Don't include auto remove tasks that are finished or finishing. 7303 continue; 7304 } 7305 7306 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7307 if (!detailed) { 7308 rti.baseIntent.replaceExtras((Bundle)null); 7309 } 7310 7311 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7312 // Check whether this activity is currently available. 7313 try { 7314 if (rti.origActivity != null) { 7315 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7316 == null) { 7317 continue; 7318 } 7319 } else if (rti.baseIntent != null) { 7320 if (pm.queryIntentActivities(rti.baseIntent, 7321 null, 0, userId) == null) { 7322 continue; 7323 } 7324 } 7325 } catch (RemoteException e) { 7326 // Will never happen. 7327 } 7328 } 7329 7330 res.add(rti); 7331 maxNum--; 7332 } 7333 } 7334 return res; 7335 } 7336 } 7337 7338 private TaskRecord recentTaskForIdLocked(int id) { 7339 final int N = mRecentTasks.size(); 7340 for (int i=0; i<N; i++) { 7341 TaskRecord tr = mRecentTasks.get(i); 7342 if (tr.taskId == id) { 7343 return tr; 7344 } 7345 } 7346 return null; 7347 } 7348 7349 @Override 7350 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7351 synchronized (this) { 7352 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7353 "getTaskThumbnails()"); 7354 TaskRecord tr = recentTaskForIdLocked(id); 7355 if (tr != null) { 7356 return tr.getTaskThumbnailsLocked(); 7357 } 7358 } 7359 return null; 7360 } 7361 7362 @Override 7363 public Bitmap getTaskTopThumbnail(int id) { 7364 synchronized (this) { 7365 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7366 "getTaskTopThumbnail()"); 7367 TaskRecord tr = recentTaskForIdLocked(id); 7368 if (tr != null) { 7369 return tr.getTaskTopThumbnailLocked(); 7370 } 7371 } 7372 return null; 7373 } 7374 7375 @Override 7376 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7377 synchronized (this) { 7378 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7379 if (r != null) { 7380 r.taskDescription = td; 7381 r.task.updateTaskDescription(); 7382 } 7383 } 7384 } 7385 7386 @Override 7387 public boolean removeSubTask(int taskId, int subTaskIndex) { 7388 synchronized (this) { 7389 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7390 "removeSubTask()"); 7391 long ident = Binder.clearCallingIdentity(); 7392 try { 7393 TaskRecord tr = recentTaskForIdLocked(taskId); 7394 if (tr != null) { 7395 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7396 } 7397 return false; 7398 } finally { 7399 Binder.restoreCallingIdentity(ident); 7400 } 7401 } 7402 } 7403 7404 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7405 if (!pr.killedByAm) { 7406 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7407 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7408 pr.processName, pr.setAdj, reason); 7409 pr.killedByAm = true; 7410 Process.killProcessQuiet(pr.pid); 7411 } 7412 } 7413 7414 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7415 tr.disposeThumbnail(); 7416 mRecentTasks.remove(tr); 7417 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7418 Intent baseIntent = new Intent( 7419 tr.intent != null ? tr.intent : tr.affinityIntent); 7420 ComponentName component = baseIntent.getComponent(); 7421 if (component == null) { 7422 Slog.w(TAG, "Now component for base intent of task: " + tr); 7423 return; 7424 } 7425 7426 // Find any running services associated with this app. 7427 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7428 7429 if (killProcesses) { 7430 // Find any running processes associated with this app. 7431 final String pkg = component.getPackageName(); 7432 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7433 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7434 for (int i=0; i<pmap.size(); i++) { 7435 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7436 for (int j=0; j<uids.size(); j++) { 7437 ProcessRecord proc = uids.valueAt(j); 7438 if (proc.userId != tr.userId) { 7439 continue; 7440 } 7441 if (!proc.pkgList.containsKey(pkg)) { 7442 continue; 7443 } 7444 procs.add(proc); 7445 } 7446 } 7447 7448 // Kill the running processes. 7449 for (int i=0; i<procs.size(); i++) { 7450 ProcessRecord pr = procs.get(i); 7451 if (pr == mHomeProcess) { 7452 // Don't kill the home process along with tasks from the same package. 7453 continue; 7454 } 7455 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7456 killUnneededProcessLocked(pr, "remove task"); 7457 } else { 7458 pr.waitingToKill = "remove task"; 7459 } 7460 } 7461 } 7462 } 7463 7464 /** 7465 * Removes the task with the specified task id. 7466 * 7467 * @param taskId Identifier of the task to be removed. 7468 * @param flags Additional operational flags. May be 0 or 7469 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7470 * @return Returns true if the given task was found and removed. 7471 */ 7472 private boolean removeTaskByIdLocked(int taskId, int flags) { 7473 TaskRecord tr = recentTaskForIdLocked(taskId); 7474 if (tr != null) { 7475 tr.removeTaskActivitiesLocked(-1, false); 7476 cleanUpRemovedTaskLocked(tr, flags); 7477 if (tr.isPersistable) { 7478 notifyTaskPersisterLocked(tr, true); 7479 } 7480 return true; 7481 } 7482 return false; 7483 } 7484 7485 @Override 7486 public boolean removeTask(int taskId, int flags) { 7487 synchronized (this) { 7488 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7489 "removeTask()"); 7490 long ident = Binder.clearCallingIdentity(); 7491 try { 7492 return removeTaskByIdLocked(taskId, flags); 7493 } finally { 7494 Binder.restoreCallingIdentity(ident); 7495 } 7496 } 7497 } 7498 7499 /** 7500 * TODO: Add mController hook 7501 */ 7502 @Override 7503 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7504 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7505 "moveTaskToFront()"); 7506 7507 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7508 synchronized(this) { 7509 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7510 Binder.getCallingUid(), "Task to front")) { 7511 ActivityOptions.abort(options); 7512 return; 7513 } 7514 final long origId = Binder.clearCallingIdentity(); 7515 try { 7516 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7517 if (task == null) { 7518 return; 7519 } 7520 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7521 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7522 return; 7523 } 7524 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7525 if (prev != null && prev.isRecentsActivity()) { 7526 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7527 } 7528 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7529 } finally { 7530 Binder.restoreCallingIdentity(origId); 7531 } 7532 ActivityOptions.abort(options); 7533 } 7534 } 7535 7536 @Override 7537 public void moveTaskToBack(int taskId) { 7538 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7539 "moveTaskToBack()"); 7540 7541 synchronized(this) { 7542 TaskRecord tr = recentTaskForIdLocked(taskId); 7543 if (tr != null) { 7544 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7545 ActivityStack stack = tr.stack; 7546 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7547 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7548 Binder.getCallingUid(), "Task to back")) { 7549 return; 7550 } 7551 } 7552 final long origId = Binder.clearCallingIdentity(); 7553 try { 7554 stack.moveTaskToBackLocked(taskId, null); 7555 } finally { 7556 Binder.restoreCallingIdentity(origId); 7557 } 7558 } 7559 } 7560 } 7561 7562 /** 7563 * Moves an activity, and all of the other activities within the same task, to the bottom 7564 * of the history stack. The activity's order within the task is unchanged. 7565 * 7566 * @param token A reference to the activity we wish to move 7567 * @param nonRoot If false then this only works if the activity is the root 7568 * of a task; if true it will work for any activity in a task. 7569 * @return Returns true if the move completed, false if not. 7570 */ 7571 @Override 7572 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7573 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7574 synchronized(this) { 7575 final long origId = Binder.clearCallingIdentity(); 7576 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7577 if (taskId >= 0) { 7578 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7579 } 7580 Binder.restoreCallingIdentity(origId); 7581 } 7582 return false; 7583 } 7584 7585 @Override 7586 public void moveTaskBackwards(int task) { 7587 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7588 "moveTaskBackwards()"); 7589 7590 synchronized(this) { 7591 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7592 Binder.getCallingUid(), "Task backwards")) { 7593 return; 7594 } 7595 final long origId = Binder.clearCallingIdentity(); 7596 moveTaskBackwardsLocked(task); 7597 Binder.restoreCallingIdentity(origId); 7598 } 7599 } 7600 7601 private final void moveTaskBackwardsLocked(int task) { 7602 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7603 } 7604 7605 @Override 7606 public IBinder getHomeActivityToken() throws RemoteException { 7607 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7608 "getHomeActivityToken()"); 7609 synchronized (this) { 7610 return mStackSupervisor.getHomeActivityToken(); 7611 } 7612 } 7613 7614 @Override 7615 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7616 IActivityContainerCallback callback) throws RemoteException { 7617 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7618 "createActivityContainer()"); 7619 synchronized (this) { 7620 if (parentActivityToken == null) { 7621 throw new IllegalArgumentException("parent token must not be null"); 7622 } 7623 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7624 if (r == null) { 7625 return null; 7626 } 7627 if (callback == null) { 7628 throw new IllegalArgumentException("callback must not be null"); 7629 } 7630 return mStackSupervisor.createActivityContainer(r, callback); 7631 } 7632 } 7633 7634 @Override 7635 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7636 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7637 "deleteActivityContainer()"); 7638 synchronized (this) { 7639 mStackSupervisor.deleteActivityContainer(container); 7640 } 7641 } 7642 7643 @Override 7644 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7645 throws RemoteException { 7646 synchronized (this) { 7647 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7648 if (stack != null) { 7649 return stack.mActivityContainer; 7650 } 7651 return null; 7652 } 7653 } 7654 7655 @Override 7656 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7657 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7658 "moveTaskToStack()"); 7659 if (stackId == HOME_STACK_ID) { 7660 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7661 new RuntimeException("here").fillInStackTrace()); 7662 } 7663 synchronized (this) { 7664 long ident = Binder.clearCallingIdentity(); 7665 try { 7666 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7667 + stackId + " toTop=" + toTop); 7668 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7669 } finally { 7670 Binder.restoreCallingIdentity(ident); 7671 } 7672 } 7673 } 7674 7675 @Override 7676 public void resizeStack(int stackBoxId, Rect bounds) { 7677 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7678 "resizeStackBox()"); 7679 long ident = Binder.clearCallingIdentity(); 7680 try { 7681 mWindowManager.resizeStack(stackBoxId, bounds); 7682 } finally { 7683 Binder.restoreCallingIdentity(ident); 7684 } 7685 } 7686 7687 @Override 7688 public List<StackInfo> getAllStackInfos() { 7689 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7690 "getAllStackInfos()"); 7691 long ident = Binder.clearCallingIdentity(); 7692 try { 7693 synchronized (this) { 7694 return mStackSupervisor.getAllStackInfosLocked(); 7695 } 7696 } finally { 7697 Binder.restoreCallingIdentity(ident); 7698 } 7699 } 7700 7701 @Override 7702 public StackInfo getStackInfo(int stackId) { 7703 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7704 "getStackInfo()"); 7705 long ident = Binder.clearCallingIdentity(); 7706 try { 7707 synchronized (this) { 7708 return mStackSupervisor.getStackInfoLocked(stackId); 7709 } 7710 } finally { 7711 Binder.restoreCallingIdentity(ident); 7712 } 7713 } 7714 7715 @Override 7716 public boolean isInHomeStack(int taskId) { 7717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7718 "getStackInfo()"); 7719 long ident = Binder.clearCallingIdentity(); 7720 try { 7721 synchronized (this) { 7722 TaskRecord tr = recentTaskForIdLocked(taskId); 7723 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7724 } 7725 } finally { 7726 Binder.restoreCallingIdentity(ident); 7727 } 7728 } 7729 7730 @Override 7731 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7732 synchronized(this) { 7733 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7734 } 7735 } 7736 7737 private boolean isLockTaskAuthorized(String pkg) { 7738 final DevicePolicyManager dpm = (DevicePolicyManager) 7739 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7740 try { 7741 int uid = mContext.getPackageManager().getPackageUid(pkg, 7742 Binder.getCallingUserHandle().getIdentifier()); 7743 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7744 } catch (NameNotFoundException e) { 7745 return false; 7746 } 7747 } 7748 7749 void startLockTaskMode(TaskRecord task) { 7750 final String pkg; 7751 synchronized (this) { 7752 pkg = task.intent.getComponent().getPackageName(); 7753 } 7754 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7755 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7756 final TaskRecord taskRecord = task; 7757 mHandler.post(new Runnable() { 7758 @Override 7759 public void run() { 7760 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7761 } 7762 }); 7763 return; 7764 } 7765 long ident = Binder.clearCallingIdentity(); 7766 try { 7767 synchronized (this) { 7768 // Since we lost lock on task, make sure it is still there. 7769 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7770 if (task != null) { 7771 if (!isSystemInitiated 7772 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7773 throw new IllegalArgumentException("Invalid task, not in foreground"); 7774 } 7775 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated); 7776 } 7777 } 7778 } finally { 7779 Binder.restoreCallingIdentity(ident); 7780 } 7781 } 7782 7783 @Override 7784 public void startLockTaskMode(int taskId) { 7785 final TaskRecord task; 7786 long ident = Binder.clearCallingIdentity(); 7787 try { 7788 synchronized (this) { 7789 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7790 } 7791 } finally { 7792 Binder.restoreCallingIdentity(ident); 7793 } 7794 if (task != null) { 7795 startLockTaskMode(task); 7796 } 7797 } 7798 7799 @Override 7800 public void startLockTaskMode(IBinder token) { 7801 final TaskRecord task; 7802 long ident = Binder.clearCallingIdentity(); 7803 try { 7804 synchronized (this) { 7805 final ActivityRecord r = ActivityRecord.forToken(token); 7806 if (r == null) { 7807 return; 7808 } 7809 task = r.task; 7810 } 7811 } finally { 7812 Binder.restoreCallingIdentity(ident); 7813 } 7814 if (task != null) { 7815 startLockTaskMode(task); 7816 } 7817 } 7818 7819 @Override 7820 public void startLockTaskModeOnCurrent() throws RemoteException { 7821 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7822 ActivityRecord r = null; 7823 synchronized (this) { 7824 r = mStackSupervisor.topRunningActivityLocked(); 7825 } 7826 startLockTaskMode(r.task); 7827 } 7828 7829 @Override 7830 public void stopLockTaskMode() { 7831 // Verify that the user matches the package of the intent for the TaskRecord 7832 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7833 // and stopLockTaskMode. 7834 final int callingUid = Binder.getCallingUid(); 7835 if (callingUid != Process.SYSTEM_UID) { 7836 try { 7837 String pkg = 7838 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7839 int uid = mContext.getPackageManager().getPackageUid(pkg, 7840 Binder.getCallingUserHandle().getIdentifier()); 7841 if (uid != callingUid) { 7842 throw new SecurityException("Invalid uid, expected " + uid); 7843 } 7844 } catch (NameNotFoundException e) { 7845 Log.d(TAG, "stopLockTaskMode " + e); 7846 return; 7847 } 7848 } 7849 long ident = Binder.clearCallingIdentity(); 7850 try { 7851 Log.d(TAG, "stopLockTaskMode"); 7852 // Stop lock task 7853 synchronized (this) { 7854 mStackSupervisor.setLockTaskModeLocked(null, false); 7855 } 7856 } finally { 7857 Binder.restoreCallingIdentity(ident); 7858 } 7859 } 7860 7861 @Override 7862 public void stopLockTaskModeOnCurrent() throws RemoteException { 7863 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7864 long ident = Binder.clearCallingIdentity(); 7865 try { 7866 stopLockTaskMode(); 7867 } finally { 7868 Binder.restoreCallingIdentity(ident); 7869 } 7870 } 7871 7872 @Override 7873 public boolean isInLockTaskMode() { 7874 synchronized (this) { 7875 return mStackSupervisor.isInLockTaskMode(); 7876 } 7877 } 7878 7879 // ========================================================= 7880 // CONTENT PROVIDERS 7881 // ========================================================= 7882 7883 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7884 List<ProviderInfo> providers = null; 7885 try { 7886 providers = AppGlobals.getPackageManager(). 7887 queryContentProviders(app.processName, app.uid, 7888 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7889 } catch (RemoteException ex) { 7890 } 7891 if (DEBUG_MU) 7892 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7893 int userId = app.userId; 7894 if (providers != null) { 7895 int N = providers.size(); 7896 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7897 for (int i=0; i<N; i++) { 7898 ProviderInfo cpi = 7899 (ProviderInfo)providers.get(i); 7900 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7901 cpi.name, cpi.flags); 7902 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7903 // This is a singleton provider, but a user besides the 7904 // default user is asking to initialize a process it runs 7905 // in... well, no, it doesn't actually run in this process, 7906 // it runs in the process of the default user. Get rid of it. 7907 providers.remove(i); 7908 N--; 7909 i--; 7910 continue; 7911 } 7912 7913 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7914 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7915 if (cpr == null) { 7916 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7917 mProviderMap.putProviderByClass(comp, cpr); 7918 } 7919 if (DEBUG_MU) 7920 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7921 app.pubProviders.put(cpi.name, cpr); 7922 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7923 // Don't add this if it is a platform component that is marked 7924 // to run in multiple processes, because this is actually 7925 // part of the framework so doesn't make sense to track as a 7926 // separate apk in the process. 7927 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 7928 mProcessStats); 7929 } 7930 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7931 } 7932 } 7933 return providers; 7934 } 7935 7936 /** 7937 * Check if {@link ProcessRecord} has a possible chance at accessing the 7938 * given {@link ProviderInfo}. Final permission checking is always done 7939 * in {@link ContentProvider}. 7940 */ 7941 private final String checkContentProviderPermissionLocked( 7942 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 7943 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7944 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7945 boolean checkedGrants = false; 7946 if (checkUser) { 7947 // Looking for cross-user grants before enforcing the typical cross-users permissions 7948 if (UserHandle.getUserId(callingUid) != userId) { 7949 if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7950 return null; 7951 } 7952 checkedGrants = true; 7953 } 7954 userId = handleIncomingUser(callingPid, callingUid, userId, 7955 false, true, "checkContentProviderPermissionLocked " + cpi.authority, null); 7956 } 7957 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7958 cpi.applicationInfo.uid, cpi.exported) 7959 == PackageManager.PERMISSION_GRANTED) { 7960 return null; 7961 } 7962 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7963 cpi.applicationInfo.uid, cpi.exported) 7964 == PackageManager.PERMISSION_GRANTED) { 7965 return null; 7966 } 7967 7968 PathPermission[] pps = cpi.pathPermissions; 7969 if (pps != null) { 7970 int i = pps.length; 7971 while (i > 0) { 7972 i--; 7973 PathPermission pp = pps[i]; 7974 String pprperm = pp.getReadPermission(); 7975 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 7976 cpi.applicationInfo.uid, cpi.exported) 7977 == PackageManager.PERMISSION_GRANTED) { 7978 return null; 7979 } 7980 String ppwperm = pp.getWritePermission(); 7981 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 7982 cpi.applicationInfo.uid, cpi.exported) 7983 == PackageManager.PERMISSION_GRANTED) { 7984 return null; 7985 } 7986 } 7987 } 7988 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 7989 return null; 7990 } 7991 7992 String msg; 7993 if (!cpi.exported) { 7994 msg = "Permission Denial: opening provider " + cpi.name 7995 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7996 + ", uid=" + callingUid + ") that is not exported from uid " 7997 + cpi.applicationInfo.uid; 7998 } else { 7999 msg = "Permission Denial: opening provider " + cpi.name 8000 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8001 + ", uid=" + callingUid + ") requires " 8002 + cpi.readPermission + " or " + cpi.writePermission; 8003 } 8004 Slog.w(TAG, msg); 8005 return msg; 8006 } 8007 8008 /** 8009 * Returns if the ContentProvider has granted a uri to callingUid 8010 */ 8011 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8012 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8013 if (perms != null) { 8014 for (GrantUri grantUri : perms.keySet()) { 8015 if (grantUri.sourceUserId == userId || !checkUser) { 8016 if (matchesProvider(grantUri.uri, cpi)) { 8017 return true; 8018 } 8019 } 8020 } 8021 } 8022 return false; 8023 } 8024 8025 /** 8026 * Returns true if the uri authority is one of the authorities specified in the provider. 8027 */ 8028 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8029 String uriAuth = uri.getAuthority(); 8030 String cpiAuth = cpi.authority; 8031 if (cpiAuth.indexOf(';') == -1) { 8032 return cpiAuth.equals(uriAuth); 8033 } 8034 String[] cpiAuths = cpiAuth.split(";"); 8035 int length = cpiAuths.length; 8036 for (int i = 0; i < length; i++) { 8037 if (cpiAuths[i].equals(uriAuth)) return true; 8038 } 8039 return false; 8040 } 8041 8042 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8043 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8044 if (r != null) { 8045 for (int i=0; i<r.conProviders.size(); i++) { 8046 ContentProviderConnection conn = r.conProviders.get(i); 8047 if (conn.provider == cpr) { 8048 if (DEBUG_PROVIDER) Slog.v(TAG, 8049 "Adding provider requested by " 8050 + r.processName + " from process " 8051 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8052 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8053 if (stable) { 8054 conn.stableCount++; 8055 conn.numStableIncs++; 8056 } else { 8057 conn.unstableCount++; 8058 conn.numUnstableIncs++; 8059 } 8060 return conn; 8061 } 8062 } 8063 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8064 if (stable) { 8065 conn.stableCount = 1; 8066 conn.numStableIncs = 1; 8067 } else { 8068 conn.unstableCount = 1; 8069 conn.numUnstableIncs = 1; 8070 } 8071 cpr.connections.add(conn); 8072 r.conProviders.add(conn); 8073 return conn; 8074 } 8075 cpr.addExternalProcessHandleLocked(externalProcessToken); 8076 return null; 8077 } 8078 8079 boolean decProviderCountLocked(ContentProviderConnection conn, 8080 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8081 if (conn != null) { 8082 cpr = conn.provider; 8083 if (DEBUG_PROVIDER) Slog.v(TAG, 8084 "Removing provider requested by " 8085 + conn.client.processName + " from process " 8086 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8087 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8088 if (stable) { 8089 conn.stableCount--; 8090 } else { 8091 conn.unstableCount--; 8092 } 8093 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8094 cpr.connections.remove(conn); 8095 conn.client.conProviders.remove(conn); 8096 return true; 8097 } 8098 return false; 8099 } 8100 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8101 return false; 8102 } 8103 8104 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8105 String name, IBinder token, boolean stable, int userId) { 8106 ContentProviderRecord cpr; 8107 ContentProviderConnection conn = null; 8108 ProviderInfo cpi = null; 8109 8110 synchronized(this) { 8111 ProcessRecord r = null; 8112 if (caller != null) { 8113 r = getRecordForAppLocked(caller); 8114 if (r == null) { 8115 throw new SecurityException( 8116 "Unable to find app for caller " + caller 8117 + " (pid=" + Binder.getCallingPid() 8118 + ") when getting content provider " + name); 8119 } 8120 } 8121 8122 boolean checkCrossUser = true; 8123 8124 // First check if this content provider has been published... 8125 cpr = mProviderMap.getProviderByName(name, userId); 8126 // If that didn't work, check if it exists for user 0 and then 8127 // verify that it's a singleton provider before using it. 8128 if (cpr == null && userId != UserHandle.USER_OWNER) { 8129 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8130 if (cpr != null) { 8131 cpi = cpr.info; 8132 if (isSingleton(cpi.processName, cpi.applicationInfo, 8133 cpi.name, cpi.flags) 8134 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8135 userId = UserHandle.USER_OWNER; 8136 checkCrossUser = false; 8137 } else { 8138 cpr = null; 8139 cpi = null; 8140 } 8141 } 8142 } 8143 8144 boolean providerRunning = cpr != null; 8145 if (providerRunning) { 8146 cpi = cpr.info; 8147 String msg; 8148 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8149 != null) { 8150 throw new SecurityException(msg); 8151 } 8152 8153 if (r != null && cpr.canRunHere(r)) { 8154 // This provider has been published or is in the process 8155 // of being published... but it is also allowed to run 8156 // in the caller's process, so don't make a connection 8157 // and just let the caller instantiate its own instance. 8158 ContentProviderHolder holder = cpr.newHolder(null); 8159 // don't give caller the provider object, it needs 8160 // to make its own. 8161 holder.provider = null; 8162 return holder; 8163 } 8164 8165 final long origId = Binder.clearCallingIdentity(); 8166 8167 // In this case the provider instance already exists, so we can 8168 // return it right away. 8169 conn = incProviderCountLocked(r, cpr, token, stable); 8170 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8171 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8172 // If this is a perceptible app accessing the provider, 8173 // make sure to count it as being accessed and thus 8174 // back up on the LRU list. This is good because 8175 // content providers are often expensive to start. 8176 updateLruProcessLocked(cpr.proc, false, null); 8177 } 8178 } 8179 8180 if (cpr.proc != null) { 8181 if (false) { 8182 if (cpr.name.flattenToShortString().equals( 8183 "com.android.providers.calendar/.CalendarProvider2")) { 8184 Slog.v(TAG, "****************** KILLING " 8185 + cpr.name.flattenToShortString()); 8186 Process.killProcess(cpr.proc.pid); 8187 } 8188 } 8189 boolean success = updateOomAdjLocked(cpr.proc); 8190 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8191 // NOTE: there is still a race here where a signal could be 8192 // pending on the process even though we managed to update its 8193 // adj level. Not sure what to do about this, but at least 8194 // the race is now smaller. 8195 if (!success) { 8196 // Uh oh... it looks like the provider's process 8197 // has been killed on us. We need to wait for a new 8198 // process to be started, and make sure its death 8199 // doesn't kill our process. 8200 Slog.i(TAG, 8201 "Existing provider " + cpr.name.flattenToShortString() 8202 + " is crashing; detaching " + r); 8203 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8204 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8205 if (!lastRef) { 8206 // This wasn't the last ref our process had on 8207 // the provider... we have now been killed, bail. 8208 return null; 8209 } 8210 providerRunning = false; 8211 conn = null; 8212 } 8213 } 8214 8215 Binder.restoreCallingIdentity(origId); 8216 } 8217 8218 boolean singleton; 8219 if (!providerRunning) { 8220 try { 8221 cpi = AppGlobals.getPackageManager(). 8222 resolveContentProvider(name, 8223 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8224 } catch (RemoteException ex) { 8225 } 8226 if (cpi == null) { 8227 return null; 8228 } 8229 // If the provider is a singleton AND 8230 // (it's a call within the same user || the provider is a 8231 // privileged app) 8232 // Then allow connecting to the singleton provider 8233 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8234 cpi.name, cpi.flags) 8235 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8236 if (singleton) { 8237 userId = UserHandle.USER_OWNER; 8238 } 8239 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8240 8241 String msg; 8242 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8243 != null) { 8244 throw new SecurityException(msg); 8245 } 8246 8247 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8248 && !cpi.processName.equals("system")) { 8249 // If this content provider does not run in the system 8250 // process, and the system is not yet ready to run other 8251 // processes, then fail fast instead of hanging. 8252 throw new IllegalArgumentException( 8253 "Attempt to launch content provider before system ready"); 8254 } 8255 8256 // Make sure that the user who owns this provider is started. If not, 8257 // we don't want to allow it to run. 8258 if (mStartedUsers.get(userId) == null) { 8259 Slog.w(TAG, "Unable to launch app " 8260 + cpi.applicationInfo.packageName + "/" 8261 + cpi.applicationInfo.uid + " for provider " 8262 + name + ": user " + userId + " is stopped"); 8263 return null; 8264 } 8265 8266 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8267 cpr = mProviderMap.getProviderByClass(comp, userId); 8268 final boolean firstClass = cpr == null; 8269 if (firstClass) { 8270 try { 8271 ApplicationInfo ai = 8272 AppGlobals.getPackageManager(). 8273 getApplicationInfo( 8274 cpi.applicationInfo.packageName, 8275 STOCK_PM_FLAGS, userId); 8276 if (ai == null) { 8277 Slog.w(TAG, "No package info for content provider " 8278 + cpi.name); 8279 return null; 8280 } 8281 ai = getAppInfoForUser(ai, userId); 8282 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8283 } catch (RemoteException ex) { 8284 // pm is in same process, this will never happen. 8285 } 8286 } 8287 8288 if (r != null && cpr.canRunHere(r)) { 8289 // If this is a multiprocess provider, then just return its 8290 // info and allow the caller to instantiate it. Only do 8291 // this if the provider is the same user as the caller's 8292 // process, or can run as root (so can be in any process). 8293 return cpr.newHolder(null); 8294 } 8295 8296 if (DEBUG_PROVIDER) { 8297 RuntimeException e = new RuntimeException("here"); 8298 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8299 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8300 } 8301 8302 // This is single process, and our app is now connecting to it. 8303 // See if we are already in the process of launching this 8304 // provider. 8305 final int N = mLaunchingProviders.size(); 8306 int i; 8307 for (i=0; i<N; i++) { 8308 if (mLaunchingProviders.get(i) == cpr) { 8309 break; 8310 } 8311 } 8312 8313 // If the provider is not already being launched, then get it 8314 // started. 8315 if (i >= N) { 8316 final long origId = Binder.clearCallingIdentity(); 8317 8318 try { 8319 // Content provider is now in use, its package can't be stopped. 8320 try { 8321 AppGlobals.getPackageManager().setPackageStoppedState( 8322 cpr.appInfo.packageName, false, userId); 8323 } catch (RemoteException e) { 8324 } catch (IllegalArgumentException e) { 8325 Slog.w(TAG, "Failed trying to unstop package " 8326 + cpr.appInfo.packageName + ": " + e); 8327 } 8328 8329 // Use existing process if already started 8330 ProcessRecord proc = getProcessRecordLocked( 8331 cpi.processName, cpr.appInfo.uid, false); 8332 if (proc != null && proc.thread != null) { 8333 if (DEBUG_PROVIDER) { 8334 Slog.d(TAG, "Installing in existing process " + proc); 8335 } 8336 proc.pubProviders.put(cpi.name, cpr); 8337 try { 8338 proc.thread.scheduleInstallProvider(cpi); 8339 } catch (RemoteException e) { 8340 } 8341 } else { 8342 proc = startProcessLocked(cpi.processName, 8343 cpr.appInfo, false, 0, "content provider", 8344 new ComponentName(cpi.applicationInfo.packageName, 8345 cpi.name), false, false, false); 8346 if (proc == null) { 8347 Slog.w(TAG, "Unable to launch app " 8348 + cpi.applicationInfo.packageName + "/" 8349 + cpi.applicationInfo.uid + " for provider " 8350 + name + ": process is bad"); 8351 return null; 8352 } 8353 } 8354 cpr.launchingApp = proc; 8355 mLaunchingProviders.add(cpr); 8356 } finally { 8357 Binder.restoreCallingIdentity(origId); 8358 } 8359 } 8360 8361 // Make sure the provider is published (the same provider class 8362 // may be published under multiple names). 8363 if (firstClass) { 8364 mProviderMap.putProviderByClass(comp, cpr); 8365 } 8366 8367 mProviderMap.putProviderByName(name, cpr); 8368 conn = incProviderCountLocked(r, cpr, token, stable); 8369 if (conn != null) { 8370 conn.waiting = true; 8371 } 8372 } 8373 } 8374 8375 // Wait for the provider to be published... 8376 synchronized (cpr) { 8377 while (cpr.provider == null) { 8378 if (cpr.launchingApp == null) { 8379 Slog.w(TAG, "Unable to launch app " 8380 + cpi.applicationInfo.packageName + "/" 8381 + cpi.applicationInfo.uid + " for provider " 8382 + name + ": launching app became null"); 8383 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8384 UserHandle.getUserId(cpi.applicationInfo.uid), 8385 cpi.applicationInfo.packageName, 8386 cpi.applicationInfo.uid, name); 8387 return null; 8388 } 8389 try { 8390 if (DEBUG_MU) { 8391 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8392 + cpr.launchingApp); 8393 } 8394 if (conn != null) { 8395 conn.waiting = true; 8396 } 8397 cpr.wait(); 8398 } catch (InterruptedException ex) { 8399 } finally { 8400 if (conn != null) { 8401 conn.waiting = false; 8402 } 8403 } 8404 } 8405 } 8406 return cpr != null ? cpr.newHolder(conn) : null; 8407 } 8408 8409 @Override 8410 public final ContentProviderHolder getContentProvider( 8411 IApplicationThread caller, String name, int userId, boolean stable) { 8412 enforceNotIsolatedCaller("getContentProvider"); 8413 if (caller == null) { 8414 String msg = "null IApplicationThread when getting content provider " 8415 + name; 8416 Slog.w(TAG, msg); 8417 throw new SecurityException(msg); 8418 } 8419 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8420 // with cross-user grant. 8421 return getContentProviderImpl(caller, name, null, stable, userId); 8422 } 8423 8424 public ContentProviderHolder getContentProviderExternal( 8425 String name, int userId, IBinder token) { 8426 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8427 "Do not have permission in call getContentProviderExternal()"); 8428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8429 false, true, "getContentProvider", null); 8430 return getContentProviderExternalUnchecked(name, token, userId); 8431 } 8432 8433 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8434 IBinder token, int userId) { 8435 return getContentProviderImpl(null, name, token, true, userId); 8436 } 8437 8438 /** 8439 * Drop a content provider from a ProcessRecord's bookkeeping 8440 */ 8441 public void removeContentProvider(IBinder connection, boolean stable) { 8442 enforceNotIsolatedCaller("removeContentProvider"); 8443 long ident = Binder.clearCallingIdentity(); 8444 try { 8445 synchronized (this) { 8446 ContentProviderConnection conn; 8447 try { 8448 conn = (ContentProviderConnection)connection; 8449 } catch (ClassCastException e) { 8450 String msg ="removeContentProvider: " + connection 8451 + " not a ContentProviderConnection"; 8452 Slog.w(TAG, msg); 8453 throw new IllegalArgumentException(msg); 8454 } 8455 if (conn == null) { 8456 throw new NullPointerException("connection is null"); 8457 } 8458 if (decProviderCountLocked(conn, null, null, stable)) { 8459 updateOomAdjLocked(); 8460 } 8461 } 8462 } finally { 8463 Binder.restoreCallingIdentity(ident); 8464 } 8465 } 8466 8467 public void removeContentProviderExternal(String name, IBinder token) { 8468 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8469 "Do not have permission in call removeContentProviderExternal()"); 8470 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8471 } 8472 8473 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8474 synchronized (this) { 8475 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8476 if(cpr == null) { 8477 //remove from mProvidersByClass 8478 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8479 return; 8480 } 8481 8482 //update content provider record entry info 8483 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8484 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8485 if (localCpr.hasExternalProcessHandles()) { 8486 if (localCpr.removeExternalProcessHandleLocked(token)) { 8487 updateOomAdjLocked(); 8488 } else { 8489 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8490 + " with no external reference for token: " 8491 + token + "."); 8492 } 8493 } else { 8494 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8495 + " with no external references."); 8496 } 8497 } 8498 } 8499 8500 public final void publishContentProviders(IApplicationThread caller, 8501 List<ContentProviderHolder> providers) { 8502 if (providers == null) { 8503 return; 8504 } 8505 8506 enforceNotIsolatedCaller("publishContentProviders"); 8507 synchronized (this) { 8508 final ProcessRecord r = getRecordForAppLocked(caller); 8509 if (DEBUG_MU) 8510 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8511 if (r == null) { 8512 throw new SecurityException( 8513 "Unable to find app for caller " + caller 8514 + " (pid=" + Binder.getCallingPid() 8515 + ") when publishing content providers"); 8516 } 8517 8518 final long origId = Binder.clearCallingIdentity(); 8519 8520 final int N = providers.size(); 8521 for (int i=0; i<N; i++) { 8522 ContentProviderHolder src = providers.get(i); 8523 if (src == null || src.info == null || src.provider == null) { 8524 continue; 8525 } 8526 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8527 if (DEBUG_MU) 8528 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8529 if (dst != null) { 8530 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8531 mProviderMap.putProviderByClass(comp, dst); 8532 String names[] = dst.info.authority.split(";"); 8533 for (int j = 0; j < names.length; j++) { 8534 mProviderMap.putProviderByName(names[j], dst); 8535 } 8536 8537 int NL = mLaunchingProviders.size(); 8538 int j; 8539 for (j=0; j<NL; j++) { 8540 if (mLaunchingProviders.get(j) == dst) { 8541 mLaunchingProviders.remove(j); 8542 j--; 8543 NL--; 8544 } 8545 } 8546 synchronized (dst) { 8547 dst.provider = src.provider; 8548 dst.proc = r; 8549 dst.notifyAll(); 8550 } 8551 updateOomAdjLocked(r); 8552 } 8553 } 8554 8555 Binder.restoreCallingIdentity(origId); 8556 } 8557 } 8558 8559 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8560 ContentProviderConnection conn; 8561 try { 8562 conn = (ContentProviderConnection)connection; 8563 } catch (ClassCastException e) { 8564 String msg ="refContentProvider: " + connection 8565 + " not a ContentProviderConnection"; 8566 Slog.w(TAG, msg); 8567 throw new IllegalArgumentException(msg); 8568 } 8569 if (conn == null) { 8570 throw new NullPointerException("connection is null"); 8571 } 8572 8573 synchronized (this) { 8574 if (stable > 0) { 8575 conn.numStableIncs += stable; 8576 } 8577 stable = conn.stableCount + stable; 8578 if (stable < 0) { 8579 throw new IllegalStateException("stableCount < 0: " + stable); 8580 } 8581 8582 if (unstable > 0) { 8583 conn.numUnstableIncs += unstable; 8584 } 8585 unstable = conn.unstableCount + unstable; 8586 if (unstable < 0) { 8587 throw new IllegalStateException("unstableCount < 0: " + unstable); 8588 } 8589 8590 if ((stable+unstable) <= 0) { 8591 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8592 + stable + " unstable=" + unstable); 8593 } 8594 conn.stableCount = stable; 8595 conn.unstableCount = unstable; 8596 return !conn.dead; 8597 } 8598 } 8599 8600 public void unstableProviderDied(IBinder connection) { 8601 ContentProviderConnection conn; 8602 try { 8603 conn = (ContentProviderConnection)connection; 8604 } catch (ClassCastException e) { 8605 String msg ="refContentProvider: " + connection 8606 + " not a ContentProviderConnection"; 8607 Slog.w(TAG, msg); 8608 throw new IllegalArgumentException(msg); 8609 } 8610 if (conn == null) { 8611 throw new NullPointerException("connection is null"); 8612 } 8613 8614 // Safely retrieve the content provider associated with the connection. 8615 IContentProvider provider; 8616 synchronized (this) { 8617 provider = conn.provider.provider; 8618 } 8619 8620 if (provider == null) { 8621 // Um, yeah, we're way ahead of you. 8622 return; 8623 } 8624 8625 // Make sure the caller is being honest with us. 8626 if (provider.asBinder().pingBinder()) { 8627 // Er, no, still looks good to us. 8628 synchronized (this) { 8629 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8630 + " says " + conn + " died, but we don't agree"); 8631 return; 8632 } 8633 } 8634 8635 // Well look at that! It's dead! 8636 synchronized (this) { 8637 if (conn.provider.provider != provider) { 8638 // But something changed... good enough. 8639 return; 8640 } 8641 8642 ProcessRecord proc = conn.provider.proc; 8643 if (proc == null || proc.thread == null) { 8644 // Seems like the process is already cleaned up. 8645 return; 8646 } 8647 8648 // As far as we're concerned, this is just like receiving a 8649 // death notification... just a bit prematurely. 8650 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8651 + ") early provider death"); 8652 final long ident = Binder.clearCallingIdentity(); 8653 try { 8654 appDiedLocked(proc, proc.pid, proc.thread); 8655 } finally { 8656 Binder.restoreCallingIdentity(ident); 8657 } 8658 } 8659 } 8660 8661 @Override 8662 public void appNotRespondingViaProvider(IBinder connection) { 8663 enforceCallingPermission( 8664 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8665 8666 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8667 if (conn == null) { 8668 Slog.w(TAG, "ContentProviderConnection is null"); 8669 return; 8670 } 8671 8672 final ProcessRecord host = conn.provider.proc; 8673 if (host == null) { 8674 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8675 return; 8676 } 8677 8678 final long token = Binder.clearCallingIdentity(); 8679 try { 8680 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8681 } finally { 8682 Binder.restoreCallingIdentity(token); 8683 } 8684 } 8685 8686 public final void installSystemProviders() { 8687 List<ProviderInfo> providers; 8688 synchronized (this) { 8689 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8690 providers = generateApplicationProvidersLocked(app); 8691 if (providers != null) { 8692 for (int i=providers.size()-1; i>=0; i--) { 8693 ProviderInfo pi = (ProviderInfo)providers.get(i); 8694 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8695 Slog.w(TAG, "Not installing system proc provider " + pi.name 8696 + ": not system .apk"); 8697 providers.remove(i); 8698 } 8699 } 8700 } 8701 } 8702 if (providers != null) { 8703 mSystemThread.installSystemProviders(providers); 8704 } 8705 8706 mCoreSettingsObserver = new CoreSettingsObserver(this); 8707 8708 mUsageStatsService.monitorPackages(); 8709 } 8710 8711 /** 8712 * Allows app to retrieve the MIME type of a URI without having permission 8713 * to access its content provider. 8714 * 8715 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8716 * 8717 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8718 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8719 */ 8720 public String getProviderMimeType(Uri uri, int userId) { 8721 enforceNotIsolatedCaller("getProviderMimeType"); 8722 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8723 userId, false, true, "getProviderMimeType", null); 8724 final String name = uri.getAuthority(); 8725 final long ident = Binder.clearCallingIdentity(); 8726 ContentProviderHolder holder = null; 8727 8728 try { 8729 holder = getContentProviderExternalUnchecked(name, null, userId); 8730 if (holder != null) { 8731 return holder.provider.getType(uri); 8732 } 8733 } catch (RemoteException e) { 8734 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8735 return null; 8736 } finally { 8737 if (holder != null) { 8738 removeContentProviderExternalUnchecked(name, null, userId); 8739 } 8740 Binder.restoreCallingIdentity(ident); 8741 } 8742 8743 return null; 8744 } 8745 8746 // ========================================================= 8747 // GLOBAL MANAGEMENT 8748 // ========================================================= 8749 8750 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8751 boolean isolated) { 8752 String proc = customProcess != null ? customProcess : info.processName; 8753 BatteryStatsImpl.Uid.Proc ps = null; 8754 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8755 int uid = info.uid; 8756 if (isolated) { 8757 int userId = UserHandle.getUserId(uid); 8758 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8759 while (true) { 8760 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8761 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8762 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8763 } 8764 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8765 mNextIsolatedProcessUid++; 8766 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8767 // No process for this uid, use it. 8768 break; 8769 } 8770 stepsLeft--; 8771 if (stepsLeft <= 0) { 8772 return null; 8773 } 8774 } 8775 } 8776 return new ProcessRecord(stats, info, proc, uid); 8777 } 8778 8779 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8780 String abiOverride) { 8781 ProcessRecord app; 8782 if (!isolated) { 8783 app = getProcessRecordLocked(info.processName, info.uid, true); 8784 } else { 8785 app = null; 8786 } 8787 8788 if (app == null) { 8789 app = newProcessRecordLocked(info, null, isolated); 8790 mProcessNames.put(info.processName, app.uid, app); 8791 if (isolated) { 8792 mIsolatedProcesses.put(app.uid, app); 8793 } 8794 updateLruProcessLocked(app, false, null); 8795 updateOomAdjLocked(); 8796 } 8797 8798 // This package really, really can not be stopped. 8799 try { 8800 AppGlobals.getPackageManager().setPackageStoppedState( 8801 info.packageName, false, UserHandle.getUserId(app.uid)); 8802 } catch (RemoteException e) { 8803 } catch (IllegalArgumentException e) { 8804 Slog.w(TAG, "Failed trying to unstop package " 8805 + info.packageName + ": " + e); 8806 } 8807 8808 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8809 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8810 app.persistent = true; 8811 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8812 } 8813 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8814 mPersistentStartingProcesses.add(app); 8815 startProcessLocked(app, "added application", app.processName, 8816 abiOverride); 8817 } 8818 8819 return app; 8820 } 8821 8822 public void unhandledBack() { 8823 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8824 "unhandledBack()"); 8825 8826 synchronized(this) { 8827 final long origId = Binder.clearCallingIdentity(); 8828 try { 8829 getFocusedStack().unhandledBackLocked(); 8830 } finally { 8831 Binder.restoreCallingIdentity(origId); 8832 } 8833 } 8834 } 8835 8836 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8837 enforceNotIsolatedCaller("openContentUri"); 8838 final int userId = UserHandle.getCallingUserId(); 8839 String name = uri.getAuthority(); 8840 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8841 ParcelFileDescriptor pfd = null; 8842 if (cph != null) { 8843 // We record the binder invoker's uid in thread-local storage before 8844 // going to the content provider to open the file. Later, in the code 8845 // that handles all permissions checks, we look for this uid and use 8846 // that rather than the Activity Manager's own uid. The effect is that 8847 // we do the check against the caller's permissions even though it looks 8848 // to the content provider like the Activity Manager itself is making 8849 // the request. 8850 sCallerIdentity.set(new Identity( 8851 Binder.getCallingPid(), Binder.getCallingUid())); 8852 try { 8853 pfd = cph.provider.openFile(null, uri, "r", null); 8854 } catch (FileNotFoundException e) { 8855 // do nothing; pfd will be returned null 8856 } finally { 8857 // Ensure that whatever happens, we clean up the identity state 8858 sCallerIdentity.remove(); 8859 } 8860 8861 // We've got the fd now, so we're done with the provider. 8862 removeContentProviderExternalUnchecked(name, null, userId); 8863 } else { 8864 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8865 } 8866 return pfd; 8867 } 8868 8869 // Actually is sleeping or shutting down or whatever else in the future 8870 // is an inactive state. 8871 public boolean isSleepingOrShuttingDown() { 8872 return mSleeping || mShuttingDown; 8873 } 8874 8875 public boolean isSleeping() { 8876 return mSleeping; 8877 } 8878 8879 void goingToSleep() { 8880 synchronized(this) { 8881 mWentToSleep = true; 8882 updateEventDispatchingLocked(); 8883 goToSleepIfNeededLocked(); 8884 } 8885 } 8886 8887 void finishRunningVoiceLocked() { 8888 if (mRunningVoice) { 8889 mRunningVoice = false; 8890 goToSleepIfNeededLocked(); 8891 } 8892 } 8893 8894 void goToSleepIfNeededLocked() { 8895 if (mWentToSleep && !mRunningVoice) { 8896 if (!mSleeping) { 8897 mSleeping = true; 8898 mStackSupervisor.goingToSleepLocked(); 8899 8900 // Initialize the wake times of all processes. 8901 checkExcessivePowerUsageLocked(false); 8902 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8903 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8904 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8905 } 8906 } 8907 } 8908 8909 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 8910 mTaskPersister.notify(task, flush); 8911 } 8912 8913 @Override 8914 public boolean shutdown(int timeout) { 8915 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8916 != PackageManager.PERMISSION_GRANTED) { 8917 throw new SecurityException("Requires permission " 8918 + android.Manifest.permission.SHUTDOWN); 8919 } 8920 8921 boolean timedout = false; 8922 8923 synchronized(this) { 8924 mShuttingDown = true; 8925 updateEventDispatchingLocked(); 8926 timedout = mStackSupervisor.shutdownLocked(timeout); 8927 } 8928 8929 mAppOpsService.shutdown(); 8930 mUsageStatsService.shutdown(); 8931 mBatteryStatsService.shutdown(); 8932 synchronized (this) { 8933 mProcessStats.shutdownLocked(); 8934 } 8935 notifyTaskPersisterLocked(null, true); 8936 8937 return timedout; 8938 } 8939 8940 public final void activitySlept(IBinder token) { 8941 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8942 8943 final long origId = Binder.clearCallingIdentity(); 8944 8945 synchronized (this) { 8946 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8947 if (r != null) { 8948 mStackSupervisor.activitySleptLocked(r); 8949 } 8950 } 8951 8952 Binder.restoreCallingIdentity(origId); 8953 } 8954 8955 void logLockScreen(String msg) { 8956 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8957 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8958 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8959 mStackSupervisor.mDismissKeyguardOnNextActivity); 8960 } 8961 8962 private void comeOutOfSleepIfNeededLocked() { 8963 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8964 if (mSleeping) { 8965 mSleeping = false; 8966 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8967 } 8968 } 8969 } 8970 8971 void wakingUp() { 8972 synchronized(this) { 8973 mWentToSleep = false; 8974 updateEventDispatchingLocked(); 8975 comeOutOfSleepIfNeededLocked(); 8976 } 8977 } 8978 8979 void startRunningVoiceLocked() { 8980 if (!mRunningVoice) { 8981 mRunningVoice = true; 8982 comeOutOfSleepIfNeededLocked(); 8983 } 8984 } 8985 8986 private void updateEventDispatchingLocked() { 8987 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8988 } 8989 8990 public void setLockScreenShown(boolean shown) { 8991 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8992 != PackageManager.PERMISSION_GRANTED) { 8993 throw new SecurityException("Requires permission " 8994 + android.Manifest.permission.DEVICE_POWER); 8995 } 8996 8997 synchronized(this) { 8998 long ident = Binder.clearCallingIdentity(); 8999 try { 9000 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9001 mLockScreenShown = shown; 9002 comeOutOfSleepIfNeededLocked(); 9003 } finally { 9004 Binder.restoreCallingIdentity(ident); 9005 } 9006 } 9007 } 9008 9009 public void stopAppSwitches() { 9010 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9011 != PackageManager.PERMISSION_GRANTED) { 9012 throw new SecurityException("Requires permission " 9013 + android.Manifest.permission.STOP_APP_SWITCHES); 9014 } 9015 9016 synchronized(this) { 9017 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9018 + APP_SWITCH_DELAY_TIME; 9019 mDidAppSwitch = false; 9020 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9021 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9022 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9023 } 9024 } 9025 9026 public void resumeAppSwitches() { 9027 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9028 != PackageManager.PERMISSION_GRANTED) { 9029 throw new SecurityException("Requires permission " 9030 + android.Manifest.permission.STOP_APP_SWITCHES); 9031 } 9032 9033 synchronized(this) { 9034 // Note that we don't execute any pending app switches... we will 9035 // let those wait until either the timeout, or the next start 9036 // activity request. 9037 mAppSwitchesAllowedTime = 0; 9038 } 9039 } 9040 9041 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9042 String name) { 9043 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9044 return true; 9045 } 9046 9047 final int perm = checkComponentPermission( 9048 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9049 callingUid, -1, true); 9050 if (perm == PackageManager.PERMISSION_GRANTED) { 9051 return true; 9052 } 9053 9054 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9055 return false; 9056 } 9057 9058 public void setDebugApp(String packageName, boolean waitForDebugger, 9059 boolean persistent) { 9060 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9061 "setDebugApp()"); 9062 9063 long ident = Binder.clearCallingIdentity(); 9064 try { 9065 // Note that this is not really thread safe if there are multiple 9066 // callers into it at the same time, but that's not a situation we 9067 // care about. 9068 if (persistent) { 9069 final ContentResolver resolver = mContext.getContentResolver(); 9070 Settings.Global.putString( 9071 resolver, Settings.Global.DEBUG_APP, 9072 packageName); 9073 Settings.Global.putInt( 9074 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9075 waitForDebugger ? 1 : 0); 9076 } 9077 9078 synchronized (this) { 9079 if (!persistent) { 9080 mOrigDebugApp = mDebugApp; 9081 mOrigWaitForDebugger = mWaitForDebugger; 9082 } 9083 mDebugApp = packageName; 9084 mWaitForDebugger = waitForDebugger; 9085 mDebugTransient = !persistent; 9086 if (packageName != null) { 9087 forceStopPackageLocked(packageName, -1, false, false, true, true, 9088 false, UserHandle.USER_ALL, "set debug app"); 9089 } 9090 } 9091 } finally { 9092 Binder.restoreCallingIdentity(ident); 9093 } 9094 } 9095 9096 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9097 synchronized (this) { 9098 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9099 if (!isDebuggable) { 9100 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9101 throw new SecurityException("Process not debuggable: " + app.packageName); 9102 } 9103 } 9104 9105 mOpenGlTraceApp = processName; 9106 } 9107 } 9108 9109 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9110 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9111 synchronized (this) { 9112 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9113 if (!isDebuggable) { 9114 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9115 throw new SecurityException("Process not debuggable: " + app.packageName); 9116 } 9117 } 9118 mProfileApp = processName; 9119 mProfileFile = profileFile; 9120 if (mProfileFd != null) { 9121 try { 9122 mProfileFd.close(); 9123 } catch (IOException e) { 9124 } 9125 mProfileFd = null; 9126 } 9127 mProfileFd = profileFd; 9128 mProfileType = 0; 9129 mAutoStopProfiler = autoStopProfiler; 9130 } 9131 } 9132 9133 @Override 9134 public void setAlwaysFinish(boolean enabled) { 9135 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9136 "setAlwaysFinish()"); 9137 9138 Settings.Global.putInt( 9139 mContext.getContentResolver(), 9140 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9141 9142 synchronized (this) { 9143 mAlwaysFinishActivities = enabled; 9144 } 9145 } 9146 9147 @Override 9148 public void setActivityController(IActivityController controller) { 9149 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9150 "setActivityController()"); 9151 synchronized (this) { 9152 mController = controller; 9153 Watchdog.getInstance().setActivityController(controller); 9154 } 9155 } 9156 9157 @Override 9158 public void setUserIsMonkey(boolean userIsMonkey) { 9159 synchronized (this) { 9160 synchronized (mPidsSelfLocked) { 9161 final int callingPid = Binder.getCallingPid(); 9162 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9163 if (precessRecord == null) { 9164 throw new SecurityException("Unknown process: " + callingPid); 9165 } 9166 if (precessRecord.instrumentationUiAutomationConnection == null) { 9167 throw new SecurityException("Only an instrumentation process " 9168 + "with a UiAutomation can call setUserIsMonkey"); 9169 } 9170 } 9171 mUserIsMonkey = userIsMonkey; 9172 } 9173 } 9174 9175 @Override 9176 public boolean isUserAMonkey() { 9177 synchronized (this) { 9178 // If there is a controller also implies the user is a monkey. 9179 return (mUserIsMonkey || mController != null); 9180 } 9181 } 9182 9183 public void requestBugReport() { 9184 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9185 SystemProperties.set("ctl.start", "bugreport"); 9186 } 9187 9188 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9189 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9190 } 9191 9192 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9193 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9194 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9195 } 9196 return KEY_DISPATCHING_TIMEOUT; 9197 } 9198 9199 @Override 9200 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9201 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9202 != PackageManager.PERMISSION_GRANTED) { 9203 throw new SecurityException("Requires permission " 9204 + android.Manifest.permission.FILTER_EVENTS); 9205 } 9206 ProcessRecord proc; 9207 long timeout; 9208 synchronized (this) { 9209 synchronized (mPidsSelfLocked) { 9210 proc = mPidsSelfLocked.get(pid); 9211 } 9212 timeout = getInputDispatchingTimeoutLocked(proc); 9213 } 9214 9215 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9216 return -1; 9217 } 9218 9219 return timeout; 9220 } 9221 9222 /** 9223 * Handle input dispatching timeouts. 9224 * Returns whether input dispatching should be aborted or not. 9225 */ 9226 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9227 final ActivityRecord activity, final ActivityRecord parent, 9228 final boolean aboveSystem, String reason) { 9229 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9230 != PackageManager.PERMISSION_GRANTED) { 9231 throw new SecurityException("Requires permission " 9232 + android.Manifest.permission.FILTER_EVENTS); 9233 } 9234 9235 final String annotation; 9236 if (reason == null) { 9237 annotation = "Input dispatching timed out"; 9238 } else { 9239 annotation = "Input dispatching timed out (" + reason + ")"; 9240 } 9241 9242 if (proc != null) { 9243 synchronized (this) { 9244 if (proc.debugging) { 9245 return false; 9246 } 9247 9248 if (mDidDexOpt) { 9249 // Give more time since we were dexopting. 9250 mDidDexOpt = false; 9251 return false; 9252 } 9253 9254 if (proc.instrumentationClass != null) { 9255 Bundle info = new Bundle(); 9256 info.putString("shortMsg", "keyDispatchingTimedOut"); 9257 info.putString("longMsg", annotation); 9258 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9259 return true; 9260 } 9261 } 9262 mHandler.post(new Runnable() { 9263 @Override 9264 public void run() { 9265 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9266 } 9267 }); 9268 } 9269 9270 return true; 9271 } 9272 9273 public Bundle getAssistContextExtras(int requestType) { 9274 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9275 "getAssistContextExtras()"); 9276 PendingAssistExtras pae; 9277 Bundle extras = new Bundle(); 9278 synchronized (this) { 9279 ActivityRecord activity = getFocusedStack().mResumedActivity; 9280 if (activity == null) { 9281 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9282 return null; 9283 } 9284 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9285 if (activity.app == null || activity.app.thread == null) { 9286 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9287 return extras; 9288 } 9289 if (activity.app.pid == Binder.getCallingPid()) { 9290 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9291 return extras; 9292 } 9293 pae = new PendingAssistExtras(activity); 9294 try { 9295 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9296 requestType); 9297 mPendingAssistExtras.add(pae); 9298 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9299 } catch (RemoteException e) { 9300 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9301 return extras; 9302 } 9303 } 9304 synchronized (pae) { 9305 while (!pae.haveResult) { 9306 try { 9307 pae.wait(); 9308 } catch (InterruptedException e) { 9309 } 9310 } 9311 if (pae.result != null) { 9312 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9313 } 9314 } 9315 synchronized (this) { 9316 mPendingAssistExtras.remove(pae); 9317 mHandler.removeCallbacks(pae); 9318 } 9319 return extras; 9320 } 9321 9322 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9323 PendingAssistExtras pae = (PendingAssistExtras)token; 9324 synchronized (pae) { 9325 pae.result = extras; 9326 pae.haveResult = true; 9327 pae.notifyAll(); 9328 } 9329 } 9330 9331 public void registerProcessObserver(IProcessObserver observer) { 9332 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9333 "registerProcessObserver()"); 9334 synchronized (this) { 9335 mProcessObservers.register(observer); 9336 } 9337 } 9338 9339 @Override 9340 public void unregisterProcessObserver(IProcessObserver observer) { 9341 synchronized (this) { 9342 mProcessObservers.unregister(observer); 9343 } 9344 } 9345 9346 @Override 9347 public boolean convertFromTranslucent(IBinder token) { 9348 final long origId = Binder.clearCallingIdentity(); 9349 try { 9350 synchronized (this) { 9351 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9352 if (r == null) { 9353 return false; 9354 } 9355 if (r.changeWindowTranslucency(true)) { 9356 mWindowManager.setAppFullscreen(token, true); 9357 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9358 return true; 9359 } 9360 return false; 9361 } 9362 } finally { 9363 Binder.restoreCallingIdentity(origId); 9364 } 9365 } 9366 9367 @Override 9368 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9369 final long origId = Binder.clearCallingIdentity(); 9370 try { 9371 synchronized (this) { 9372 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9373 if (r == null) { 9374 return false; 9375 } 9376 if (r.changeWindowTranslucency(false)) { 9377 r.task.stack.convertToTranslucent(r, options); 9378 mWindowManager.setAppFullscreen(token, false); 9379 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9380 return true; 9381 } 9382 return false; 9383 } 9384 } finally { 9385 Binder.restoreCallingIdentity(origId); 9386 } 9387 } 9388 9389 @Override 9390 public ActivityOptions getActivityOptions(IBinder token) { 9391 final long origId = Binder.clearCallingIdentity(); 9392 try { 9393 synchronized (this) { 9394 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9395 if (r != null) { 9396 final ActivityOptions activityOptions = r.pendingOptions; 9397 r.pendingOptions = null; 9398 return activityOptions; 9399 } 9400 return null; 9401 } 9402 } finally { 9403 Binder.restoreCallingIdentity(origId); 9404 } 9405 } 9406 9407 @Override 9408 public void setImmersive(IBinder token, boolean immersive) { 9409 synchronized(this) { 9410 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9411 if (r == null) { 9412 throw new IllegalArgumentException(); 9413 } 9414 r.immersive = immersive; 9415 9416 // update associated state if we're frontmost 9417 if (r == mFocusedActivity) { 9418 if (DEBUG_IMMERSIVE) { 9419 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9420 } 9421 applyUpdateLockStateLocked(r); 9422 } 9423 } 9424 } 9425 9426 @Override 9427 public boolean isImmersive(IBinder token) { 9428 synchronized (this) { 9429 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9430 if (r == null) { 9431 throw new IllegalArgumentException(); 9432 } 9433 return r.immersive; 9434 } 9435 } 9436 9437 public boolean isTopActivityImmersive() { 9438 enforceNotIsolatedCaller("startActivity"); 9439 synchronized (this) { 9440 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9441 return (r != null) ? r.immersive : false; 9442 } 9443 } 9444 9445 public final void enterSafeMode() { 9446 synchronized(this) { 9447 // It only makes sense to do this before the system is ready 9448 // and started launching other packages. 9449 if (!mSystemReady) { 9450 try { 9451 AppGlobals.getPackageManager().enterSafeMode(); 9452 } catch (RemoteException e) { 9453 } 9454 } 9455 9456 mSafeMode = true; 9457 } 9458 } 9459 9460 public final void showSafeModeOverlay() { 9461 View v = LayoutInflater.from(mContext).inflate( 9462 com.android.internal.R.layout.safe_mode, null); 9463 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9464 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9465 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9466 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9467 lp.gravity = Gravity.BOTTOM | Gravity.START; 9468 lp.format = v.getBackground().getOpacity(); 9469 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9470 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9471 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9472 ((WindowManager)mContext.getSystemService( 9473 Context.WINDOW_SERVICE)).addView(v, lp); 9474 } 9475 9476 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9477 if (!(sender instanceof PendingIntentRecord)) { 9478 return; 9479 } 9480 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9481 synchronized (stats) { 9482 if (mBatteryStatsService.isOnBattery()) { 9483 mBatteryStatsService.enforceCallingPermission(); 9484 PendingIntentRecord rec = (PendingIntentRecord)sender; 9485 int MY_UID = Binder.getCallingUid(); 9486 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9487 BatteryStatsImpl.Uid.Pkg pkg = 9488 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9489 sourcePkg != null ? sourcePkg : rec.key.packageName); 9490 pkg.incWakeupsLocked(); 9491 } 9492 } 9493 } 9494 9495 public boolean killPids(int[] pids, String pReason, boolean secure) { 9496 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9497 throw new SecurityException("killPids only available to the system"); 9498 } 9499 String reason = (pReason == null) ? "Unknown" : pReason; 9500 // XXX Note: don't acquire main activity lock here, because the window 9501 // manager calls in with its locks held. 9502 9503 boolean killed = false; 9504 synchronized (mPidsSelfLocked) { 9505 int[] types = new int[pids.length]; 9506 int worstType = 0; 9507 for (int i=0; i<pids.length; i++) { 9508 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9509 if (proc != null) { 9510 int type = proc.setAdj; 9511 types[i] = type; 9512 if (type > worstType) { 9513 worstType = type; 9514 } 9515 } 9516 } 9517 9518 // If the worst oom_adj is somewhere in the cached proc LRU range, 9519 // then constrain it so we will kill all cached procs. 9520 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9521 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9522 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9523 } 9524 9525 // If this is not a secure call, don't let it kill processes that 9526 // are important. 9527 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9528 worstType = ProcessList.SERVICE_ADJ; 9529 } 9530 9531 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9532 for (int i=0; i<pids.length; i++) { 9533 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9534 if (proc == null) { 9535 continue; 9536 } 9537 int adj = proc.setAdj; 9538 if (adj >= worstType && !proc.killedByAm) { 9539 killUnneededProcessLocked(proc, reason); 9540 killed = true; 9541 } 9542 } 9543 } 9544 return killed; 9545 } 9546 9547 @Override 9548 public void killUid(int uid, String reason) { 9549 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9550 throw new SecurityException("killUid only available to the system"); 9551 } 9552 synchronized (this) { 9553 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9554 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9555 reason != null ? reason : "kill uid"); 9556 } 9557 } 9558 9559 @Override 9560 public boolean killProcessesBelowForeground(String reason) { 9561 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9562 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9563 } 9564 9565 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9566 } 9567 9568 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9569 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9570 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9571 } 9572 9573 boolean killed = false; 9574 synchronized (mPidsSelfLocked) { 9575 final int size = mPidsSelfLocked.size(); 9576 for (int i = 0; i < size; i++) { 9577 final int pid = mPidsSelfLocked.keyAt(i); 9578 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9579 if (proc == null) continue; 9580 9581 final int adj = proc.setAdj; 9582 if (adj > belowAdj && !proc.killedByAm) { 9583 killUnneededProcessLocked(proc, reason); 9584 killed = true; 9585 } 9586 } 9587 } 9588 return killed; 9589 } 9590 9591 @Override 9592 public void hang(final IBinder who, boolean allowRestart) { 9593 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9594 != PackageManager.PERMISSION_GRANTED) { 9595 throw new SecurityException("Requires permission " 9596 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9597 } 9598 9599 final IBinder.DeathRecipient death = new DeathRecipient() { 9600 @Override 9601 public void binderDied() { 9602 synchronized (this) { 9603 notifyAll(); 9604 } 9605 } 9606 }; 9607 9608 try { 9609 who.linkToDeath(death, 0); 9610 } catch (RemoteException e) { 9611 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9612 return; 9613 } 9614 9615 synchronized (this) { 9616 Watchdog.getInstance().setAllowRestart(allowRestart); 9617 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9618 synchronized (death) { 9619 while (who.isBinderAlive()) { 9620 try { 9621 death.wait(); 9622 } catch (InterruptedException e) { 9623 } 9624 } 9625 } 9626 Watchdog.getInstance().setAllowRestart(true); 9627 } 9628 } 9629 9630 @Override 9631 public void restart() { 9632 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9633 != PackageManager.PERMISSION_GRANTED) { 9634 throw new SecurityException("Requires permission " 9635 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9636 } 9637 9638 Log.i(TAG, "Sending shutdown broadcast..."); 9639 9640 BroadcastReceiver br = new BroadcastReceiver() { 9641 @Override public void onReceive(Context context, Intent intent) { 9642 // Now the broadcast is done, finish up the low-level shutdown. 9643 Log.i(TAG, "Shutting down activity manager..."); 9644 shutdown(10000); 9645 Log.i(TAG, "Shutdown complete, restarting!"); 9646 Process.killProcess(Process.myPid()); 9647 System.exit(10); 9648 } 9649 }; 9650 9651 // First send the high-level shut down broadcast. 9652 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9653 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9654 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9655 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9656 mContext.sendOrderedBroadcastAsUser(intent, 9657 UserHandle.ALL, null, br, mHandler, 0, null, null); 9658 */ 9659 br.onReceive(mContext, intent); 9660 } 9661 9662 private long getLowRamTimeSinceIdle(long now) { 9663 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9664 } 9665 9666 @Override 9667 public void performIdleMaintenance() { 9668 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9669 != PackageManager.PERMISSION_GRANTED) { 9670 throw new SecurityException("Requires permission " 9671 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9672 } 9673 9674 synchronized (this) { 9675 final long now = SystemClock.uptimeMillis(); 9676 final long timeSinceLastIdle = now - mLastIdleTime; 9677 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9678 mLastIdleTime = now; 9679 mLowRamTimeSinceLastIdle = 0; 9680 if (mLowRamStartTime != 0) { 9681 mLowRamStartTime = now; 9682 } 9683 9684 StringBuilder sb = new StringBuilder(128); 9685 sb.append("Idle maintenance over "); 9686 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9687 sb.append(" low RAM for "); 9688 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9689 Slog.i(TAG, sb.toString()); 9690 9691 // If at least 1/3 of our time since the last idle period has been spent 9692 // with RAM low, then we want to kill processes. 9693 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9694 9695 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9696 ProcessRecord proc = mLruProcesses.get(i); 9697 if (proc.notCachedSinceIdle) { 9698 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9699 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9700 if (doKilling && proc.initialIdlePss != 0 9701 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9702 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9703 + " from " + proc.initialIdlePss + ")"); 9704 } 9705 } 9706 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9707 proc.notCachedSinceIdle = true; 9708 proc.initialIdlePss = 0; 9709 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9710 isSleeping(), now); 9711 } 9712 } 9713 9714 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9715 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9716 } 9717 } 9718 9719 private void retrieveSettings() { 9720 final ContentResolver resolver = mContext.getContentResolver(); 9721 String debugApp = Settings.Global.getString( 9722 resolver, Settings.Global.DEBUG_APP); 9723 boolean waitForDebugger = Settings.Global.getInt( 9724 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9725 boolean alwaysFinishActivities = Settings.Global.getInt( 9726 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9727 boolean forceRtl = Settings.Global.getInt( 9728 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9729 // Transfer any global setting for forcing RTL layout, into a System Property 9730 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9731 9732 Configuration configuration = new Configuration(); 9733 Settings.System.getConfiguration(resolver, configuration); 9734 if (forceRtl) { 9735 // This will take care of setting the correct layout direction flags 9736 configuration.setLayoutDirection(configuration.locale); 9737 } 9738 9739 synchronized (this) { 9740 mDebugApp = mOrigDebugApp = debugApp; 9741 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9742 mAlwaysFinishActivities = alwaysFinishActivities; 9743 // This happens before any activities are started, so we can 9744 // change mConfiguration in-place. 9745 updateConfigurationLocked(configuration, null, false, true); 9746 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9747 } 9748 } 9749 9750 public boolean testIsSystemReady() { 9751 // no need to synchronize(this) just to read & return the value 9752 return mSystemReady; 9753 } 9754 9755 private static File getCalledPreBootReceiversFile() { 9756 File dataDir = Environment.getDataDirectory(); 9757 File systemDir = new File(dataDir, "system"); 9758 File fname = new File(systemDir, "called_pre_boots.dat"); 9759 return fname; 9760 } 9761 9762 static final int LAST_DONE_VERSION = 10000; 9763 9764 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9765 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9766 File file = getCalledPreBootReceiversFile(); 9767 FileInputStream fis = null; 9768 try { 9769 fis = new FileInputStream(file); 9770 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9771 int fvers = dis.readInt(); 9772 if (fvers == LAST_DONE_VERSION) { 9773 String vers = dis.readUTF(); 9774 String codename = dis.readUTF(); 9775 String build = dis.readUTF(); 9776 if (android.os.Build.VERSION.RELEASE.equals(vers) 9777 && android.os.Build.VERSION.CODENAME.equals(codename) 9778 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9779 int num = dis.readInt(); 9780 while (num > 0) { 9781 num--; 9782 String pkg = dis.readUTF(); 9783 String cls = dis.readUTF(); 9784 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9785 } 9786 } 9787 } 9788 } catch (FileNotFoundException e) { 9789 } catch (IOException e) { 9790 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9791 } finally { 9792 if (fis != null) { 9793 try { 9794 fis.close(); 9795 } catch (IOException e) { 9796 } 9797 } 9798 } 9799 return lastDoneReceivers; 9800 } 9801 9802 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9803 File file = getCalledPreBootReceiversFile(); 9804 FileOutputStream fos = null; 9805 DataOutputStream dos = null; 9806 try { 9807 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9808 fos = new FileOutputStream(file); 9809 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9810 dos.writeInt(LAST_DONE_VERSION); 9811 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9812 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9813 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9814 dos.writeInt(list.size()); 9815 for (int i=0; i<list.size(); i++) { 9816 dos.writeUTF(list.get(i).getPackageName()); 9817 dos.writeUTF(list.get(i).getClassName()); 9818 } 9819 } catch (IOException e) { 9820 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9821 file.delete(); 9822 } finally { 9823 FileUtils.sync(fos); 9824 if (dos != null) { 9825 try { 9826 dos.close(); 9827 } catch (IOException e) { 9828 // TODO Auto-generated catch block 9829 e.printStackTrace(); 9830 } 9831 } 9832 } 9833 } 9834 9835 public void systemReady(final Runnable goingCallback) { 9836 synchronized(this) { 9837 if (mSystemReady) { 9838 if (goingCallback != null) goingCallback.run(); 9839 return; 9840 } 9841 9842 if (mRecentTasks == null) { 9843 mRecentTasks = mTaskPersister.restoreTasksLocked(); 9844 if (!mRecentTasks.isEmpty()) { 9845 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 9846 } 9847 mTaskPersister.startPersisting(); 9848 } 9849 9850 // Check to see if there are any update receivers to run. 9851 if (!mDidUpdate) { 9852 if (mWaitingUpdate) { 9853 return; 9854 } 9855 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9856 List<ResolveInfo> ris = null; 9857 try { 9858 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9859 intent, null, 0, 0); 9860 } catch (RemoteException e) { 9861 } 9862 if (ris != null) { 9863 for (int i=ris.size()-1; i>=0; i--) { 9864 if ((ris.get(i).activityInfo.applicationInfo.flags 9865 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9866 ris.remove(i); 9867 } 9868 } 9869 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9870 9871 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9872 9873 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9874 for (int i=0; i<ris.size(); i++) { 9875 ActivityInfo ai = ris.get(i).activityInfo; 9876 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9877 if (lastDoneReceivers.contains(comp)) { 9878 // We already did the pre boot receiver for this app with the current 9879 // platform version, so don't do it again... 9880 ris.remove(i); 9881 i--; 9882 // ...however, do keep it as one that has been done, so we don't 9883 // forget about it when rewriting the file of last done receivers. 9884 doneReceivers.add(comp); 9885 } 9886 } 9887 9888 final int[] users = getUsersLocked(); 9889 for (int i=0; i<ris.size(); i++) { 9890 ActivityInfo ai = ris.get(i).activityInfo; 9891 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9892 doneReceivers.add(comp); 9893 intent.setComponent(comp); 9894 for (int j=0; j<users.length; j++) { 9895 IIntentReceiver finisher = null; 9896 if (i == ris.size()-1 && j == users.length-1) { 9897 finisher = new IIntentReceiver.Stub() { 9898 public void performReceive(Intent intent, int resultCode, 9899 String data, Bundle extras, boolean ordered, 9900 boolean sticky, int sendingUser) { 9901 // The raw IIntentReceiver interface is called 9902 // with the AM lock held, so redispatch to 9903 // execute our code without the lock. 9904 mHandler.post(new Runnable() { 9905 public void run() { 9906 synchronized (ActivityManagerService.this) { 9907 mDidUpdate = true; 9908 } 9909 writeLastDonePreBootReceivers(doneReceivers); 9910 showBootMessage(mContext.getText( 9911 R.string.android_upgrading_complete), 9912 false); 9913 systemReady(goingCallback); 9914 } 9915 }); 9916 } 9917 }; 9918 } 9919 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9920 + " for user " + users[j]); 9921 broadcastIntentLocked(null, null, intent, null, finisher, 9922 0, null, null, null, AppOpsManager.OP_NONE, 9923 true, false, MY_PID, Process.SYSTEM_UID, 9924 users[j]); 9925 if (finisher != null) { 9926 mWaitingUpdate = true; 9927 } 9928 } 9929 } 9930 } 9931 if (mWaitingUpdate) { 9932 return; 9933 } 9934 mDidUpdate = true; 9935 } 9936 9937 mAppOpsService.systemReady(); 9938 mUsageStatsService.systemReady(); 9939 mSystemReady = true; 9940 } 9941 9942 ArrayList<ProcessRecord> procsToKill = null; 9943 synchronized(mPidsSelfLocked) { 9944 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9945 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9946 if (!isAllowedWhileBooting(proc.info)){ 9947 if (procsToKill == null) { 9948 procsToKill = new ArrayList<ProcessRecord>(); 9949 } 9950 procsToKill.add(proc); 9951 } 9952 } 9953 } 9954 9955 synchronized(this) { 9956 if (procsToKill != null) { 9957 for (int i=procsToKill.size()-1; i>=0; i--) { 9958 ProcessRecord proc = procsToKill.get(i); 9959 Slog.i(TAG, "Removing system update proc: " + proc); 9960 removeProcessLocked(proc, true, false, "system update done"); 9961 } 9962 } 9963 9964 // Now that we have cleaned up any update processes, we 9965 // are ready to start launching real processes and know that 9966 // we won't trample on them any more. 9967 mProcessesReady = true; 9968 } 9969 9970 Slog.i(TAG, "System now ready"); 9971 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9972 SystemClock.uptimeMillis()); 9973 9974 synchronized(this) { 9975 // Make sure we have no pre-ready processes sitting around. 9976 9977 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9978 ResolveInfo ri = mContext.getPackageManager() 9979 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9980 STOCK_PM_FLAGS); 9981 CharSequence errorMsg = null; 9982 if (ri != null) { 9983 ActivityInfo ai = ri.activityInfo; 9984 ApplicationInfo app = ai.applicationInfo; 9985 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9986 mTopAction = Intent.ACTION_FACTORY_TEST; 9987 mTopData = null; 9988 mTopComponent = new ComponentName(app.packageName, 9989 ai.name); 9990 } else { 9991 errorMsg = mContext.getResources().getText( 9992 com.android.internal.R.string.factorytest_not_system); 9993 } 9994 } else { 9995 errorMsg = mContext.getResources().getText( 9996 com.android.internal.R.string.factorytest_no_action); 9997 } 9998 if (errorMsg != null) { 9999 mTopAction = null; 10000 mTopData = null; 10001 mTopComponent = null; 10002 Message msg = Message.obtain(); 10003 msg.what = SHOW_FACTORY_ERROR_MSG; 10004 msg.getData().putCharSequence("msg", errorMsg); 10005 mHandler.sendMessage(msg); 10006 } 10007 } 10008 } 10009 10010 retrieveSettings(); 10011 10012 synchronized (this) { 10013 readGrantedUriPermissionsLocked(); 10014 } 10015 10016 if (goingCallback != null) goingCallback.run(); 10017 10018 mSystemServiceManager.startUser(mCurrentUserId); 10019 10020 synchronized (this) { 10021 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10022 try { 10023 List apps = AppGlobals.getPackageManager(). 10024 getPersistentApplications(STOCK_PM_FLAGS); 10025 if (apps != null) { 10026 int N = apps.size(); 10027 int i; 10028 for (i=0; i<N; i++) { 10029 ApplicationInfo info 10030 = (ApplicationInfo)apps.get(i); 10031 if (info != null && 10032 !info.packageName.equals("android")) { 10033 addAppLocked(info, false, null /* ABI override */); 10034 } 10035 } 10036 } 10037 } catch (RemoteException ex) { 10038 // pm is in same process, this will never happen. 10039 } 10040 } 10041 10042 // Start up initial activity. 10043 mBooting = true; 10044 10045 try { 10046 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10047 Message msg = Message.obtain(); 10048 msg.what = SHOW_UID_ERROR_MSG; 10049 mHandler.sendMessage(msg); 10050 } 10051 } catch (RemoteException e) { 10052 } 10053 10054 long ident = Binder.clearCallingIdentity(); 10055 try { 10056 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10057 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10058 | Intent.FLAG_RECEIVER_FOREGROUND); 10059 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10060 broadcastIntentLocked(null, null, intent, 10061 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10062 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10063 intent = new Intent(Intent.ACTION_USER_STARTING); 10064 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10065 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10066 broadcastIntentLocked(null, null, intent, 10067 null, new IIntentReceiver.Stub() { 10068 @Override 10069 public void performReceive(Intent intent, int resultCode, String data, 10070 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10071 throws RemoteException { 10072 } 10073 }, 0, null, null, 10074 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10075 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10076 } catch (Throwable t) { 10077 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10078 } finally { 10079 Binder.restoreCallingIdentity(ident); 10080 } 10081 mStackSupervisor.resumeTopActivitiesLocked(); 10082 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10083 } 10084 } 10085 10086 private boolean makeAppCrashingLocked(ProcessRecord app, 10087 String shortMsg, String longMsg, String stackTrace) { 10088 app.crashing = true; 10089 app.crashingReport = generateProcessError(app, 10090 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10091 startAppProblemLocked(app); 10092 app.stopFreezingAllLocked(); 10093 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10094 } 10095 10096 private void makeAppNotRespondingLocked(ProcessRecord app, 10097 String activity, String shortMsg, String longMsg) { 10098 app.notResponding = true; 10099 app.notRespondingReport = generateProcessError(app, 10100 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10101 activity, shortMsg, longMsg, null); 10102 startAppProblemLocked(app); 10103 app.stopFreezingAllLocked(); 10104 } 10105 10106 /** 10107 * Generate a process error record, suitable for attachment to a ProcessRecord. 10108 * 10109 * @param app The ProcessRecord in which the error occurred. 10110 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10111 * ActivityManager.AppErrorStateInfo 10112 * @param activity The activity associated with the crash, if known. 10113 * @param shortMsg Short message describing the crash. 10114 * @param longMsg Long message describing the crash. 10115 * @param stackTrace Full crash stack trace, may be null. 10116 * 10117 * @return Returns a fully-formed AppErrorStateInfo record. 10118 */ 10119 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10120 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10121 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10122 10123 report.condition = condition; 10124 report.processName = app.processName; 10125 report.pid = app.pid; 10126 report.uid = app.info.uid; 10127 report.tag = activity; 10128 report.shortMsg = shortMsg; 10129 report.longMsg = longMsg; 10130 report.stackTrace = stackTrace; 10131 10132 return report; 10133 } 10134 10135 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10136 synchronized (this) { 10137 app.crashing = false; 10138 app.crashingReport = null; 10139 app.notResponding = false; 10140 app.notRespondingReport = null; 10141 if (app.anrDialog == fromDialog) { 10142 app.anrDialog = null; 10143 } 10144 if (app.waitDialog == fromDialog) { 10145 app.waitDialog = null; 10146 } 10147 if (app.pid > 0 && app.pid != MY_PID) { 10148 handleAppCrashLocked(app, null, null, null); 10149 killUnneededProcessLocked(app, "user request after error"); 10150 } 10151 } 10152 } 10153 10154 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10155 String stackTrace) { 10156 long now = SystemClock.uptimeMillis(); 10157 10158 Long crashTime; 10159 if (!app.isolated) { 10160 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10161 } else { 10162 crashTime = null; 10163 } 10164 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10165 // This process loses! 10166 Slog.w(TAG, "Process " + app.info.processName 10167 + " has crashed too many times: killing!"); 10168 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10169 app.userId, app.info.processName, app.uid); 10170 mStackSupervisor.handleAppCrashLocked(app); 10171 if (!app.persistent) { 10172 // We don't want to start this process again until the user 10173 // explicitly does so... but for persistent process, we really 10174 // need to keep it running. If a persistent process is actually 10175 // repeatedly crashing, then badness for everyone. 10176 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10177 app.info.processName); 10178 if (!app.isolated) { 10179 // XXX We don't have a way to mark isolated processes 10180 // as bad, since they don't have a peristent identity. 10181 mBadProcesses.put(app.info.processName, app.uid, 10182 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10183 mProcessCrashTimes.remove(app.info.processName, app.uid); 10184 } 10185 app.bad = true; 10186 app.removed = true; 10187 // Don't let services in this process be restarted and potentially 10188 // annoy the user repeatedly. Unless it is persistent, since those 10189 // processes run critical code. 10190 removeProcessLocked(app, false, false, "crash"); 10191 mStackSupervisor.resumeTopActivitiesLocked(); 10192 return false; 10193 } 10194 mStackSupervisor.resumeTopActivitiesLocked(); 10195 } else { 10196 mStackSupervisor.finishTopRunningActivityLocked(app); 10197 } 10198 10199 // Bump up the crash count of any services currently running in the proc. 10200 for (int i=app.services.size()-1; i>=0; i--) { 10201 // Any services running in the application need to be placed 10202 // back in the pending list. 10203 ServiceRecord sr = app.services.valueAt(i); 10204 sr.crashCount++; 10205 } 10206 10207 // If the crashing process is what we consider to be the "home process" and it has been 10208 // replaced by a third-party app, clear the package preferred activities from packages 10209 // with a home activity running in the process to prevent a repeatedly crashing app 10210 // from blocking the user to manually clear the list. 10211 final ArrayList<ActivityRecord> activities = app.activities; 10212 if (app == mHomeProcess && activities.size() > 0 10213 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10214 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10215 final ActivityRecord r = activities.get(activityNdx); 10216 if (r.isHomeActivity()) { 10217 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10218 try { 10219 ActivityThread.getPackageManager() 10220 .clearPackagePreferredActivities(r.packageName); 10221 } catch (RemoteException c) { 10222 // pm is in same process, this will never happen. 10223 } 10224 } 10225 } 10226 } 10227 10228 if (!app.isolated) { 10229 // XXX Can't keep track of crash times for isolated processes, 10230 // because they don't have a perisistent identity. 10231 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10232 } 10233 10234 return true; 10235 } 10236 10237 void startAppProblemLocked(ProcessRecord app) { 10238 if (app.userId == mCurrentUserId) { 10239 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10240 mContext, app.info.packageName, app.info.flags); 10241 } else { 10242 // If this app is not running under the current user, then we 10243 // can't give it a report button because that would require 10244 // launching the report UI under a different user. 10245 app.errorReportReceiver = null; 10246 } 10247 skipCurrentReceiverLocked(app); 10248 } 10249 10250 void skipCurrentReceiverLocked(ProcessRecord app) { 10251 for (BroadcastQueue queue : mBroadcastQueues) { 10252 queue.skipCurrentReceiverLocked(app); 10253 } 10254 } 10255 10256 /** 10257 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10258 * The application process will exit immediately after this call returns. 10259 * @param app object of the crashing app, null for the system server 10260 * @param crashInfo describing the exception 10261 */ 10262 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10263 ProcessRecord r = findAppProcess(app, "Crash"); 10264 final String processName = app == null ? "system_server" 10265 : (r == null ? "unknown" : r.processName); 10266 10267 handleApplicationCrashInner("crash", r, processName, crashInfo); 10268 } 10269 10270 /* Native crash reporting uses this inner version because it needs to be somewhat 10271 * decoupled from the AM-managed cleanup lifecycle 10272 */ 10273 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10274 ApplicationErrorReport.CrashInfo crashInfo) { 10275 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10276 UserHandle.getUserId(Binder.getCallingUid()), processName, 10277 r == null ? -1 : r.info.flags, 10278 crashInfo.exceptionClassName, 10279 crashInfo.exceptionMessage, 10280 crashInfo.throwFileName, 10281 crashInfo.throwLineNumber); 10282 10283 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10284 10285 crashApplication(r, crashInfo); 10286 } 10287 10288 public void handleApplicationStrictModeViolation( 10289 IBinder app, 10290 int violationMask, 10291 StrictMode.ViolationInfo info) { 10292 ProcessRecord r = findAppProcess(app, "StrictMode"); 10293 if (r == null) { 10294 return; 10295 } 10296 10297 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10298 Integer stackFingerprint = info.hashCode(); 10299 boolean logIt = true; 10300 synchronized (mAlreadyLoggedViolatedStacks) { 10301 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10302 logIt = false; 10303 // TODO: sub-sample into EventLog for these, with 10304 // the info.durationMillis? Then we'd get 10305 // the relative pain numbers, without logging all 10306 // the stack traces repeatedly. We'd want to do 10307 // likewise in the client code, which also does 10308 // dup suppression, before the Binder call. 10309 } else { 10310 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10311 mAlreadyLoggedViolatedStacks.clear(); 10312 } 10313 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10314 } 10315 } 10316 if (logIt) { 10317 logStrictModeViolationToDropBox(r, info); 10318 } 10319 } 10320 10321 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10322 AppErrorResult result = new AppErrorResult(); 10323 synchronized (this) { 10324 final long origId = Binder.clearCallingIdentity(); 10325 10326 Message msg = Message.obtain(); 10327 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10328 HashMap<String, Object> data = new HashMap<String, Object>(); 10329 data.put("result", result); 10330 data.put("app", r); 10331 data.put("violationMask", violationMask); 10332 data.put("info", info); 10333 msg.obj = data; 10334 mHandler.sendMessage(msg); 10335 10336 Binder.restoreCallingIdentity(origId); 10337 } 10338 int res = result.get(); 10339 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10340 } 10341 } 10342 10343 // Depending on the policy in effect, there could be a bunch of 10344 // these in quick succession so we try to batch these together to 10345 // minimize disk writes, number of dropbox entries, and maximize 10346 // compression, by having more fewer, larger records. 10347 private void logStrictModeViolationToDropBox( 10348 ProcessRecord process, 10349 StrictMode.ViolationInfo info) { 10350 if (info == null) { 10351 return; 10352 } 10353 final boolean isSystemApp = process == null || 10354 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10355 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10356 final String processName = process == null ? "unknown" : process.processName; 10357 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10358 final DropBoxManager dbox = (DropBoxManager) 10359 mContext.getSystemService(Context.DROPBOX_SERVICE); 10360 10361 // Exit early if the dropbox isn't configured to accept this report type. 10362 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10363 10364 boolean bufferWasEmpty; 10365 boolean needsFlush; 10366 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10367 synchronized (sb) { 10368 bufferWasEmpty = sb.length() == 0; 10369 appendDropBoxProcessHeaders(process, processName, sb); 10370 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10371 sb.append("System-App: ").append(isSystemApp).append("\n"); 10372 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10373 if (info.violationNumThisLoop != 0) { 10374 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10375 } 10376 if (info.numAnimationsRunning != 0) { 10377 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10378 } 10379 if (info.broadcastIntentAction != null) { 10380 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10381 } 10382 if (info.durationMillis != -1) { 10383 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10384 } 10385 if (info.numInstances != -1) { 10386 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10387 } 10388 if (info.tags != null) { 10389 for (String tag : info.tags) { 10390 sb.append("Span-Tag: ").append(tag).append("\n"); 10391 } 10392 } 10393 sb.append("\n"); 10394 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10395 sb.append(info.crashInfo.stackTrace); 10396 } 10397 sb.append("\n"); 10398 10399 // Only buffer up to ~64k. Various logging bits truncate 10400 // things at 128k. 10401 needsFlush = (sb.length() > 64 * 1024); 10402 } 10403 10404 // Flush immediately if the buffer's grown too large, or this 10405 // is a non-system app. Non-system apps are isolated with a 10406 // different tag & policy and not batched. 10407 // 10408 // Batching is useful during internal testing with 10409 // StrictMode settings turned up high. Without batching, 10410 // thousands of separate files could be created on boot. 10411 if (!isSystemApp || needsFlush) { 10412 new Thread("Error dump: " + dropboxTag) { 10413 @Override 10414 public void run() { 10415 String report; 10416 synchronized (sb) { 10417 report = sb.toString(); 10418 sb.delete(0, sb.length()); 10419 sb.trimToSize(); 10420 } 10421 if (report.length() != 0) { 10422 dbox.addText(dropboxTag, report); 10423 } 10424 } 10425 }.start(); 10426 return; 10427 } 10428 10429 // System app batching: 10430 if (!bufferWasEmpty) { 10431 // An existing dropbox-writing thread is outstanding, so 10432 // we don't need to start it up. The existing thread will 10433 // catch the buffer appends we just did. 10434 return; 10435 } 10436 10437 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10438 // (After this point, we shouldn't access AMS internal data structures.) 10439 new Thread("Error dump: " + dropboxTag) { 10440 @Override 10441 public void run() { 10442 // 5 second sleep to let stacks arrive and be batched together 10443 try { 10444 Thread.sleep(5000); // 5 seconds 10445 } catch (InterruptedException e) {} 10446 10447 String errorReport; 10448 synchronized (mStrictModeBuffer) { 10449 errorReport = mStrictModeBuffer.toString(); 10450 if (errorReport.length() == 0) { 10451 return; 10452 } 10453 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10454 mStrictModeBuffer.trimToSize(); 10455 } 10456 dbox.addText(dropboxTag, errorReport); 10457 } 10458 }.start(); 10459 } 10460 10461 /** 10462 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10463 * @param app object of the crashing app, null for the system server 10464 * @param tag reported by the caller 10465 * @param crashInfo describing the context of the error 10466 * @return true if the process should exit immediately (WTF is fatal) 10467 */ 10468 public boolean handleApplicationWtf(IBinder app, String tag, 10469 ApplicationErrorReport.CrashInfo crashInfo) { 10470 ProcessRecord r = findAppProcess(app, "WTF"); 10471 final String processName = app == null ? "system_server" 10472 : (r == null ? "unknown" : r.processName); 10473 10474 EventLog.writeEvent(EventLogTags.AM_WTF, 10475 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10476 processName, 10477 r == null ? -1 : r.info.flags, 10478 tag, crashInfo.exceptionMessage); 10479 10480 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10481 10482 if (r != null && r.pid != Process.myPid() && 10483 Settings.Global.getInt(mContext.getContentResolver(), 10484 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10485 crashApplication(r, crashInfo); 10486 return true; 10487 } else { 10488 return false; 10489 } 10490 } 10491 10492 /** 10493 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10494 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10495 */ 10496 private ProcessRecord findAppProcess(IBinder app, String reason) { 10497 if (app == null) { 10498 return null; 10499 } 10500 10501 synchronized (this) { 10502 final int NP = mProcessNames.getMap().size(); 10503 for (int ip=0; ip<NP; ip++) { 10504 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10505 final int NA = apps.size(); 10506 for (int ia=0; ia<NA; ia++) { 10507 ProcessRecord p = apps.valueAt(ia); 10508 if (p.thread != null && p.thread.asBinder() == app) { 10509 return p; 10510 } 10511 } 10512 } 10513 10514 Slog.w(TAG, "Can't find mystery application for " + reason 10515 + " from pid=" + Binder.getCallingPid() 10516 + " uid=" + Binder.getCallingUid() + ": " + app); 10517 return null; 10518 } 10519 } 10520 10521 /** 10522 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10523 * to append various headers to the dropbox log text. 10524 */ 10525 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10526 StringBuilder sb) { 10527 // Watchdog thread ends up invoking this function (with 10528 // a null ProcessRecord) to add the stack file to dropbox. 10529 // Do not acquire a lock on this (am) in such cases, as it 10530 // could cause a potential deadlock, if and when watchdog 10531 // is invoked due to unavailability of lock on am and it 10532 // would prevent watchdog from killing system_server. 10533 if (process == null) { 10534 sb.append("Process: ").append(processName).append("\n"); 10535 return; 10536 } 10537 // Note: ProcessRecord 'process' is guarded by the service 10538 // instance. (notably process.pkgList, which could otherwise change 10539 // concurrently during execution of this method) 10540 synchronized (this) { 10541 sb.append("Process: ").append(processName).append("\n"); 10542 int flags = process.info.flags; 10543 IPackageManager pm = AppGlobals.getPackageManager(); 10544 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10545 for (int ip=0; ip<process.pkgList.size(); ip++) { 10546 String pkg = process.pkgList.keyAt(ip); 10547 sb.append("Package: ").append(pkg); 10548 try { 10549 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10550 if (pi != null) { 10551 sb.append(" v").append(pi.versionCode); 10552 if (pi.versionName != null) { 10553 sb.append(" (").append(pi.versionName).append(")"); 10554 } 10555 } 10556 } catch (RemoteException e) { 10557 Slog.e(TAG, "Error getting package info: " + pkg, e); 10558 } 10559 sb.append("\n"); 10560 } 10561 } 10562 } 10563 10564 private static String processClass(ProcessRecord process) { 10565 if (process == null || process.pid == MY_PID) { 10566 return "system_server"; 10567 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10568 return "system_app"; 10569 } else { 10570 return "data_app"; 10571 } 10572 } 10573 10574 /** 10575 * Write a description of an error (crash, WTF, ANR) to the drop box. 10576 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10577 * @param process which caused the error, null means the system server 10578 * @param activity which triggered the error, null if unknown 10579 * @param parent activity related to the error, null if unknown 10580 * @param subject line related to the error, null if absent 10581 * @param report in long form describing the error, null if absent 10582 * @param logFile to include in the report, null if none 10583 * @param crashInfo giving an application stack trace, null if absent 10584 */ 10585 public void addErrorToDropBox(String eventType, 10586 ProcessRecord process, String processName, ActivityRecord activity, 10587 ActivityRecord parent, String subject, 10588 final String report, final File logFile, 10589 final ApplicationErrorReport.CrashInfo crashInfo) { 10590 // NOTE -- this must never acquire the ActivityManagerService lock, 10591 // otherwise the watchdog may be prevented from resetting the system. 10592 10593 final String dropboxTag = processClass(process) + "_" + eventType; 10594 final DropBoxManager dbox = (DropBoxManager) 10595 mContext.getSystemService(Context.DROPBOX_SERVICE); 10596 10597 // Exit early if the dropbox isn't configured to accept this report type. 10598 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10599 10600 final StringBuilder sb = new StringBuilder(1024); 10601 appendDropBoxProcessHeaders(process, processName, sb); 10602 if (activity != null) { 10603 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10604 } 10605 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10606 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10607 } 10608 if (parent != null && parent != activity) { 10609 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10610 } 10611 if (subject != null) { 10612 sb.append("Subject: ").append(subject).append("\n"); 10613 } 10614 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10615 if (Debug.isDebuggerConnected()) { 10616 sb.append("Debugger: Connected\n"); 10617 } 10618 sb.append("\n"); 10619 10620 // Do the rest in a worker thread to avoid blocking the caller on I/O 10621 // (After this point, we shouldn't access AMS internal data structures.) 10622 Thread worker = new Thread("Error dump: " + dropboxTag) { 10623 @Override 10624 public void run() { 10625 if (report != null) { 10626 sb.append(report); 10627 } 10628 if (logFile != null) { 10629 try { 10630 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10631 "\n\n[[TRUNCATED]]")); 10632 } catch (IOException e) { 10633 Slog.e(TAG, "Error reading " + logFile, e); 10634 } 10635 } 10636 if (crashInfo != null && crashInfo.stackTrace != null) { 10637 sb.append(crashInfo.stackTrace); 10638 } 10639 10640 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10641 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10642 if (lines > 0) { 10643 sb.append("\n"); 10644 10645 // Merge several logcat streams, and take the last N lines 10646 InputStreamReader input = null; 10647 try { 10648 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10649 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10650 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10651 10652 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10653 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10654 input = new InputStreamReader(logcat.getInputStream()); 10655 10656 int num; 10657 char[] buf = new char[8192]; 10658 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10659 } catch (IOException e) { 10660 Slog.e(TAG, "Error running logcat", e); 10661 } finally { 10662 if (input != null) try { input.close(); } catch (IOException e) {} 10663 } 10664 } 10665 10666 dbox.addText(dropboxTag, sb.toString()); 10667 } 10668 }; 10669 10670 if (process == null) { 10671 // If process is null, we are being called from some internal code 10672 // and may be about to die -- run this synchronously. 10673 worker.run(); 10674 } else { 10675 worker.start(); 10676 } 10677 } 10678 10679 /** 10680 * Bring up the "unexpected error" dialog box for a crashing app. 10681 * Deal with edge cases (intercepts from instrumented applications, 10682 * ActivityController, error intent receivers, that sort of thing). 10683 * @param r the application crashing 10684 * @param crashInfo describing the failure 10685 */ 10686 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10687 long timeMillis = System.currentTimeMillis(); 10688 String shortMsg = crashInfo.exceptionClassName; 10689 String longMsg = crashInfo.exceptionMessage; 10690 String stackTrace = crashInfo.stackTrace; 10691 if (shortMsg != null && longMsg != null) { 10692 longMsg = shortMsg + ": " + longMsg; 10693 } else if (shortMsg != null) { 10694 longMsg = shortMsg; 10695 } 10696 10697 AppErrorResult result = new AppErrorResult(); 10698 synchronized (this) { 10699 if (mController != null) { 10700 try { 10701 String name = r != null ? r.processName : null; 10702 int pid = r != null ? r.pid : Binder.getCallingPid(); 10703 if (!mController.appCrashed(name, pid, 10704 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10705 Slog.w(TAG, "Force-killing crashed app " + name 10706 + " at watcher's request"); 10707 Process.killProcess(pid); 10708 return; 10709 } 10710 } catch (RemoteException e) { 10711 mController = null; 10712 Watchdog.getInstance().setActivityController(null); 10713 } 10714 } 10715 10716 final long origId = Binder.clearCallingIdentity(); 10717 10718 // If this process is running instrumentation, finish it. 10719 if (r != null && r.instrumentationClass != null) { 10720 Slog.w(TAG, "Error in app " + r.processName 10721 + " running instrumentation " + r.instrumentationClass + ":"); 10722 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10723 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10724 Bundle info = new Bundle(); 10725 info.putString("shortMsg", shortMsg); 10726 info.putString("longMsg", longMsg); 10727 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10728 Binder.restoreCallingIdentity(origId); 10729 return; 10730 } 10731 10732 // If we can't identify the process or it's already exceeded its crash quota, 10733 // quit right away without showing a crash dialog. 10734 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10735 Binder.restoreCallingIdentity(origId); 10736 return; 10737 } 10738 10739 Message msg = Message.obtain(); 10740 msg.what = SHOW_ERROR_MSG; 10741 HashMap data = new HashMap(); 10742 data.put("result", result); 10743 data.put("app", r); 10744 msg.obj = data; 10745 mHandler.sendMessage(msg); 10746 10747 Binder.restoreCallingIdentity(origId); 10748 } 10749 10750 int res = result.get(); 10751 10752 Intent appErrorIntent = null; 10753 synchronized (this) { 10754 if (r != null && !r.isolated) { 10755 // XXX Can't keep track of crash time for isolated processes, 10756 // since they don't have a persistent identity. 10757 mProcessCrashTimes.put(r.info.processName, r.uid, 10758 SystemClock.uptimeMillis()); 10759 } 10760 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10761 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10762 } 10763 } 10764 10765 if (appErrorIntent != null) { 10766 try { 10767 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10768 } catch (ActivityNotFoundException e) { 10769 Slog.w(TAG, "bug report receiver dissappeared", e); 10770 } 10771 } 10772 } 10773 10774 Intent createAppErrorIntentLocked(ProcessRecord r, 10775 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10776 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10777 if (report == null) { 10778 return null; 10779 } 10780 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10781 result.setComponent(r.errorReportReceiver); 10782 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10783 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10784 return result; 10785 } 10786 10787 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10788 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10789 if (r.errorReportReceiver == null) { 10790 return null; 10791 } 10792 10793 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10794 return null; 10795 } 10796 10797 ApplicationErrorReport report = new ApplicationErrorReport(); 10798 report.packageName = r.info.packageName; 10799 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10800 report.processName = r.processName; 10801 report.time = timeMillis; 10802 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10803 10804 if (r.crashing || r.forceCrashReport) { 10805 report.type = ApplicationErrorReport.TYPE_CRASH; 10806 report.crashInfo = crashInfo; 10807 } else if (r.notResponding) { 10808 report.type = ApplicationErrorReport.TYPE_ANR; 10809 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10810 10811 report.anrInfo.activity = r.notRespondingReport.tag; 10812 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10813 report.anrInfo.info = r.notRespondingReport.longMsg; 10814 } 10815 10816 return report; 10817 } 10818 10819 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10820 enforceNotIsolatedCaller("getProcessesInErrorState"); 10821 // assume our apps are happy - lazy create the list 10822 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10823 10824 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10825 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10826 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10827 10828 synchronized (this) { 10829 10830 // iterate across all processes 10831 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10832 ProcessRecord app = mLruProcesses.get(i); 10833 if (!allUsers && app.userId != userId) { 10834 continue; 10835 } 10836 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10837 // This one's in trouble, so we'll generate a report for it 10838 // crashes are higher priority (in case there's a crash *and* an anr) 10839 ActivityManager.ProcessErrorStateInfo report = null; 10840 if (app.crashing) { 10841 report = app.crashingReport; 10842 } else if (app.notResponding) { 10843 report = app.notRespondingReport; 10844 } 10845 10846 if (report != null) { 10847 if (errList == null) { 10848 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10849 } 10850 errList.add(report); 10851 } else { 10852 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10853 " crashing = " + app.crashing + 10854 " notResponding = " + app.notResponding); 10855 } 10856 } 10857 } 10858 } 10859 10860 return errList; 10861 } 10862 10863 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10864 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10865 if (currApp != null) { 10866 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10867 } 10868 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10869 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10870 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10871 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10872 if (currApp != null) { 10873 currApp.lru = 0; 10874 } 10875 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10876 } else if (adj >= ProcessList.SERVICE_ADJ) { 10877 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10878 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10879 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10880 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10881 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10882 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10883 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10884 } else { 10885 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10886 } 10887 } 10888 10889 private void fillInProcMemInfo(ProcessRecord app, 10890 ActivityManager.RunningAppProcessInfo outInfo) { 10891 outInfo.pid = app.pid; 10892 outInfo.uid = app.info.uid; 10893 if (mHeavyWeightProcess == app) { 10894 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10895 } 10896 if (app.persistent) { 10897 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10898 } 10899 if (app.activities.size() > 0) { 10900 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10901 } 10902 outInfo.lastTrimLevel = app.trimMemoryLevel; 10903 int adj = app.curAdj; 10904 outInfo.importance = oomAdjToImportance(adj, outInfo); 10905 outInfo.importanceReasonCode = app.adjTypeCode; 10906 outInfo.processState = app.curProcState; 10907 } 10908 10909 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10910 enforceNotIsolatedCaller("getRunningAppProcesses"); 10911 // Lazy instantiation of list 10912 List<ActivityManager.RunningAppProcessInfo> runList = null; 10913 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 10914 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10915 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10916 synchronized (this) { 10917 // Iterate across all processes 10918 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10919 ProcessRecord app = mLruProcesses.get(i); 10920 if (!allUsers && app.userId != userId) { 10921 continue; 10922 } 10923 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10924 // Generate process state info for running application 10925 ActivityManager.RunningAppProcessInfo currApp = 10926 new ActivityManager.RunningAppProcessInfo(app.processName, 10927 app.pid, app.getPackageList()); 10928 fillInProcMemInfo(app, currApp); 10929 if (app.adjSource instanceof ProcessRecord) { 10930 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10931 currApp.importanceReasonImportance = oomAdjToImportance( 10932 app.adjSourceOom, null); 10933 } else if (app.adjSource instanceof ActivityRecord) { 10934 ActivityRecord r = (ActivityRecord)app.adjSource; 10935 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10936 } 10937 if (app.adjTarget instanceof ComponentName) { 10938 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10939 } 10940 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10941 // + " lru=" + currApp.lru); 10942 if (runList == null) { 10943 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10944 } 10945 runList.add(currApp); 10946 } 10947 } 10948 } 10949 return runList; 10950 } 10951 10952 public List<ApplicationInfo> getRunningExternalApplications() { 10953 enforceNotIsolatedCaller("getRunningExternalApplications"); 10954 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10955 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10956 if (runningApps != null && runningApps.size() > 0) { 10957 Set<String> extList = new HashSet<String>(); 10958 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10959 if (app.pkgList != null) { 10960 for (String pkg : app.pkgList) { 10961 extList.add(pkg); 10962 } 10963 } 10964 } 10965 IPackageManager pm = AppGlobals.getPackageManager(); 10966 for (String pkg : extList) { 10967 try { 10968 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10969 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10970 retList.add(info); 10971 } 10972 } catch (RemoteException e) { 10973 } 10974 } 10975 } 10976 return retList; 10977 } 10978 10979 @Override 10980 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10981 enforceNotIsolatedCaller("getMyMemoryState"); 10982 synchronized (this) { 10983 ProcessRecord proc; 10984 synchronized (mPidsSelfLocked) { 10985 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10986 } 10987 fillInProcMemInfo(proc, outInfo); 10988 } 10989 } 10990 10991 @Override 10992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10993 if (checkCallingPermission(android.Manifest.permission.DUMP) 10994 != PackageManager.PERMISSION_GRANTED) { 10995 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10996 + Binder.getCallingPid() 10997 + ", uid=" + Binder.getCallingUid() 10998 + " without permission " 10999 + android.Manifest.permission.DUMP); 11000 return; 11001 } 11002 11003 boolean dumpAll = false; 11004 boolean dumpClient = false; 11005 String dumpPackage = null; 11006 11007 int opti = 0; 11008 while (opti < args.length) { 11009 String opt = args[opti]; 11010 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11011 break; 11012 } 11013 opti++; 11014 if ("-a".equals(opt)) { 11015 dumpAll = true; 11016 } else if ("-c".equals(opt)) { 11017 dumpClient = true; 11018 } else if ("-h".equals(opt)) { 11019 pw.println("Activity manager dump options:"); 11020 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11021 pw.println(" cmd may be one of:"); 11022 pw.println(" a[ctivities]: activity stack state"); 11023 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11024 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11025 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11026 pw.println(" o[om]: out of memory management"); 11027 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11028 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11029 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11030 pw.println(" service [COMP_SPEC]: service client-side state"); 11031 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11032 pw.println(" all: dump all activities"); 11033 pw.println(" top: dump the top activity"); 11034 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11035 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11036 pw.println(" a partial substring in a component name, a"); 11037 pw.println(" hex object identifier."); 11038 pw.println(" -a: include all available server state."); 11039 pw.println(" -c: include client state."); 11040 return; 11041 } else { 11042 pw.println("Unknown argument: " + opt + "; use -h for help"); 11043 } 11044 } 11045 11046 long origId = Binder.clearCallingIdentity(); 11047 boolean more = false; 11048 // Is the caller requesting to dump a particular piece of data? 11049 if (opti < args.length) { 11050 String cmd = args[opti]; 11051 opti++; 11052 if ("activities".equals(cmd) || "a".equals(cmd)) { 11053 synchronized (this) { 11054 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11055 } 11056 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11057 String[] newArgs; 11058 String name; 11059 if (opti >= args.length) { 11060 name = null; 11061 newArgs = EMPTY_STRING_ARRAY; 11062 } else { 11063 name = args[opti]; 11064 opti++; 11065 newArgs = new String[args.length - opti]; 11066 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11067 args.length - opti); 11068 } 11069 synchronized (this) { 11070 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11071 } 11072 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11073 String[] newArgs; 11074 String name; 11075 if (opti >= args.length) { 11076 name = null; 11077 newArgs = EMPTY_STRING_ARRAY; 11078 } else { 11079 name = args[opti]; 11080 opti++; 11081 newArgs = new String[args.length - opti]; 11082 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11083 args.length - opti); 11084 } 11085 synchronized (this) { 11086 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11087 } 11088 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11089 String[] newArgs; 11090 String name; 11091 if (opti >= args.length) { 11092 name = null; 11093 newArgs = EMPTY_STRING_ARRAY; 11094 } else { 11095 name = args[opti]; 11096 opti++; 11097 newArgs = new String[args.length - opti]; 11098 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11099 args.length - opti); 11100 } 11101 synchronized (this) { 11102 dumpProcessesLocked(fd, pw, args, opti, true, name); 11103 } 11104 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11105 synchronized (this) { 11106 dumpOomLocked(fd, pw, args, opti, true); 11107 } 11108 } else if ("provider".equals(cmd)) { 11109 String[] newArgs; 11110 String name; 11111 if (opti >= args.length) { 11112 name = null; 11113 newArgs = EMPTY_STRING_ARRAY; 11114 } else { 11115 name = args[opti]; 11116 opti++; 11117 newArgs = new String[args.length - opti]; 11118 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11119 } 11120 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11121 pw.println("No providers match: " + name); 11122 pw.println("Use -h for help."); 11123 } 11124 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11125 synchronized (this) { 11126 dumpProvidersLocked(fd, pw, args, opti, true, null); 11127 } 11128 } else if ("service".equals(cmd)) { 11129 String[] newArgs; 11130 String name; 11131 if (opti >= args.length) { 11132 name = null; 11133 newArgs = EMPTY_STRING_ARRAY; 11134 } else { 11135 name = args[opti]; 11136 opti++; 11137 newArgs = new String[args.length - opti]; 11138 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11139 args.length - opti); 11140 } 11141 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11142 pw.println("No services match: " + name); 11143 pw.println("Use -h for help."); 11144 } 11145 } else if ("package".equals(cmd)) { 11146 String[] newArgs; 11147 if (opti >= args.length) { 11148 pw.println("package: no package name specified"); 11149 pw.println("Use -h for help."); 11150 } else { 11151 dumpPackage = args[opti]; 11152 opti++; 11153 newArgs = new String[args.length - opti]; 11154 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11155 args.length - opti); 11156 args = newArgs; 11157 opti = 0; 11158 more = true; 11159 } 11160 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11161 synchronized (this) { 11162 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11163 } 11164 } else { 11165 // Dumping a single activity? 11166 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11167 pw.println("Bad activity command, or no activities match: " + cmd); 11168 pw.println("Use -h for help."); 11169 } 11170 } 11171 if (!more) { 11172 Binder.restoreCallingIdentity(origId); 11173 return; 11174 } 11175 } 11176 11177 // No piece of data specified, dump everything. 11178 synchronized (this) { 11179 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11180 pw.println(); 11181 if (dumpAll) { 11182 pw.println("-------------------------------------------------------------------------------"); 11183 } 11184 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11185 pw.println(); 11186 if (dumpAll) { 11187 pw.println("-------------------------------------------------------------------------------"); 11188 } 11189 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11190 pw.println(); 11191 if (dumpAll) { 11192 pw.println("-------------------------------------------------------------------------------"); 11193 } 11194 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11195 pw.println(); 11196 if (dumpAll) { 11197 pw.println("-------------------------------------------------------------------------------"); 11198 } 11199 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11200 pw.println(); 11201 if (dumpAll) { 11202 pw.println("-------------------------------------------------------------------------------"); 11203 } 11204 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11205 } 11206 Binder.restoreCallingIdentity(origId); 11207 } 11208 11209 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11210 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11211 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11212 11213 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11214 dumpPackage); 11215 boolean needSep = printedAnything; 11216 11217 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11218 dumpPackage, needSep, " mFocusedActivity: "); 11219 if (printed) { 11220 printedAnything = true; 11221 needSep = false; 11222 } 11223 11224 if (dumpPackage == null) { 11225 if (needSep) { 11226 pw.println(); 11227 } 11228 needSep = true; 11229 printedAnything = true; 11230 mStackSupervisor.dump(pw, " "); 11231 } 11232 11233 if (mRecentTasks.size() > 0) { 11234 boolean printedHeader = false; 11235 11236 final int N = mRecentTasks.size(); 11237 for (int i=0; i<N; i++) { 11238 TaskRecord tr = mRecentTasks.get(i); 11239 if (dumpPackage != null) { 11240 if (tr.realActivity == null || 11241 !dumpPackage.equals(tr.realActivity)) { 11242 continue; 11243 } 11244 } 11245 if (!printedHeader) { 11246 if (needSep) { 11247 pw.println(); 11248 } 11249 pw.println(" Recent tasks:"); 11250 printedHeader = true; 11251 printedAnything = true; 11252 } 11253 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11254 pw.println(tr); 11255 if (dumpAll) { 11256 mRecentTasks.get(i).dump(pw, " "); 11257 } 11258 } 11259 } 11260 11261 if (!printedAnything) { 11262 pw.println(" (nothing)"); 11263 } 11264 } 11265 11266 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11267 int opti, boolean dumpAll, String dumpPackage) { 11268 boolean needSep = false; 11269 boolean printedAnything = false; 11270 int numPers = 0; 11271 11272 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11273 11274 if (dumpAll) { 11275 final int NP = mProcessNames.getMap().size(); 11276 for (int ip=0; ip<NP; ip++) { 11277 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11278 final int NA = procs.size(); 11279 for (int ia=0; ia<NA; ia++) { 11280 ProcessRecord r = procs.valueAt(ia); 11281 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11282 continue; 11283 } 11284 if (!needSep) { 11285 pw.println(" All known processes:"); 11286 needSep = true; 11287 printedAnything = true; 11288 } 11289 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11290 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11291 pw.print(" "); pw.println(r); 11292 r.dump(pw, " "); 11293 if (r.persistent) { 11294 numPers++; 11295 } 11296 } 11297 } 11298 } 11299 11300 if (mIsolatedProcesses.size() > 0) { 11301 boolean printed = false; 11302 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11303 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11304 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11305 continue; 11306 } 11307 if (!printed) { 11308 if (needSep) { 11309 pw.println(); 11310 } 11311 pw.println(" Isolated process list (sorted by uid):"); 11312 printedAnything = true; 11313 printed = true; 11314 needSep = true; 11315 } 11316 pw.println(String.format("%sIsolated #%2d: %s", 11317 " ", i, r.toString())); 11318 } 11319 } 11320 11321 if (mLruProcesses.size() > 0) { 11322 if (needSep) { 11323 pw.println(); 11324 } 11325 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11326 pw.print(" total, non-act at "); 11327 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11328 pw.print(", non-svc at "); 11329 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11330 pw.println("):"); 11331 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11332 needSep = true; 11333 printedAnything = true; 11334 } 11335 11336 if (dumpAll || dumpPackage != null) { 11337 synchronized (mPidsSelfLocked) { 11338 boolean printed = false; 11339 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11340 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11341 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11342 continue; 11343 } 11344 if (!printed) { 11345 if (needSep) pw.println(); 11346 needSep = true; 11347 pw.println(" PID mappings:"); 11348 printed = true; 11349 printedAnything = true; 11350 } 11351 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11352 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11353 } 11354 } 11355 } 11356 11357 if (mForegroundProcesses.size() > 0) { 11358 synchronized (mPidsSelfLocked) { 11359 boolean printed = false; 11360 for (int i=0; i<mForegroundProcesses.size(); i++) { 11361 ProcessRecord r = mPidsSelfLocked.get( 11362 mForegroundProcesses.valueAt(i).pid); 11363 if (dumpPackage != null && (r == null 11364 || !r.pkgList.containsKey(dumpPackage))) { 11365 continue; 11366 } 11367 if (!printed) { 11368 if (needSep) pw.println(); 11369 needSep = true; 11370 pw.println(" Foreground Processes:"); 11371 printed = true; 11372 printedAnything = true; 11373 } 11374 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11375 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11376 } 11377 } 11378 } 11379 11380 if (mPersistentStartingProcesses.size() > 0) { 11381 if (needSep) pw.println(); 11382 needSep = true; 11383 printedAnything = true; 11384 pw.println(" Persisent processes that are starting:"); 11385 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11386 "Starting Norm", "Restarting PERS", dumpPackage); 11387 } 11388 11389 if (mRemovedProcesses.size() > 0) { 11390 if (needSep) pw.println(); 11391 needSep = true; 11392 printedAnything = true; 11393 pw.println(" Processes that are being removed:"); 11394 dumpProcessList(pw, this, mRemovedProcesses, " ", 11395 "Removed Norm", "Removed PERS", dumpPackage); 11396 } 11397 11398 if (mProcessesOnHold.size() > 0) { 11399 if (needSep) pw.println(); 11400 needSep = true; 11401 printedAnything = true; 11402 pw.println(" Processes that are on old until the system is ready:"); 11403 dumpProcessList(pw, this, mProcessesOnHold, " ", 11404 "OnHold Norm", "OnHold PERS", dumpPackage); 11405 } 11406 11407 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11408 11409 if (mProcessCrashTimes.getMap().size() > 0) { 11410 boolean printed = false; 11411 long now = SystemClock.uptimeMillis(); 11412 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11413 final int NP = pmap.size(); 11414 for (int ip=0; ip<NP; ip++) { 11415 String pname = pmap.keyAt(ip); 11416 SparseArray<Long> uids = pmap.valueAt(ip); 11417 final int N = uids.size(); 11418 for (int i=0; i<N; i++) { 11419 int puid = uids.keyAt(i); 11420 ProcessRecord r = mProcessNames.get(pname, puid); 11421 if (dumpPackage != null && (r == null 11422 || !r.pkgList.containsKey(dumpPackage))) { 11423 continue; 11424 } 11425 if (!printed) { 11426 if (needSep) pw.println(); 11427 needSep = true; 11428 pw.println(" Time since processes crashed:"); 11429 printed = true; 11430 printedAnything = true; 11431 } 11432 pw.print(" Process "); pw.print(pname); 11433 pw.print(" uid "); pw.print(puid); 11434 pw.print(": last crashed "); 11435 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11436 pw.println(" ago"); 11437 } 11438 } 11439 } 11440 11441 if (mBadProcesses.getMap().size() > 0) { 11442 boolean printed = false; 11443 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11444 final int NP = pmap.size(); 11445 for (int ip=0; ip<NP; ip++) { 11446 String pname = pmap.keyAt(ip); 11447 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11448 final int N = uids.size(); 11449 for (int i=0; i<N; i++) { 11450 int puid = uids.keyAt(i); 11451 ProcessRecord r = mProcessNames.get(pname, puid); 11452 if (dumpPackage != null && (r == null 11453 || !r.pkgList.containsKey(dumpPackage))) { 11454 continue; 11455 } 11456 if (!printed) { 11457 if (needSep) pw.println(); 11458 needSep = true; 11459 pw.println(" Bad processes:"); 11460 printedAnything = true; 11461 } 11462 BadProcessInfo info = uids.valueAt(i); 11463 pw.print(" Bad process "); pw.print(pname); 11464 pw.print(" uid "); pw.print(puid); 11465 pw.print(": crashed at time "); pw.println(info.time); 11466 if (info.shortMsg != null) { 11467 pw.print(" Short msg: "); pw.println(info.shortMsg); 11468 } 11469 if (info.longMsg != null) { 11470 pw.print(" Long msg: "); pw.println(info.longMsg); 11471 } 11472 if (info.stack != null) { 11473 pw.println(" Stack:"); 11474 int lastPos = 0; 11475 for (int pos=0; pos<info.stack.length(); pos++) { 11476 if (info.stack.charAt(pos) == '\n') { 11477 pw.print(" "); 11478 pw.write(info.stack, lastPos, pos-lastPos); 11479 pw.println(); 11480 lastPos = pos+1; 11481 } 11482 } 11483 if (lastPos < info.stack.length()) { 11484 pw.print(" "); 11485 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11486 pw.println(); 11487 } 11488 } 11489 } 11490 } 11491 } 11492 11493 if (dumpPackage == null) { 11494 pw.println(); 11495 needSep = false; 11496 pw.println(" mStartedUsers:"); 11497 for (int i=0; i<mStartedUsers.size(); i++) { 11498 UserStartedState uss = mStartedUsers.valueAt(i); 11499 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11500 pw.print(": "); uss.dump("", pw); 11501 } 11502 pw.print(" mStartedUserArray: ["); 11503 for (int i=0; i<mStartedUserArray.length; i++) { 11504 if (i > 0) pw.print(", "); 11505 pw.print(mStartedUserArray[i]); 11506 } 11507 pw.println("]"); 11508 pw.print(" mUserLru: ["); 11509 for (int i=0; i<mUserLru.size(); i++) { 11510 if (i > 0) pw.print(", "); 11511 pw.print(mUserLru.get(i)); 11512 } 11513 pw.println("]"); 11514 if (dumpAll) { 11515 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11516 } 11517 } 11518 if (mHomeProcess != null && (dumpPackage == null 11519 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11520 if (needSep) { 11521 pw.println(); 11522 needSep = false; 11523 } 11524 pw.println(" mHomeProcess: " + mHomeProcess); 11525 } 11526 if (mPreviousProcess != null && (dumpPackage == null 11527 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11528 if (needSep) { 11529 pw.println(); 11530 needSep = false; 11531 } 11532 pw.println(" mPreviousProcess: " + mPreviousProcess); 11533 } 11534 if (dumpAll) { 11535 StringBuilder sb = new StringBuilder(128); 11536 sb.append(" mPreviousProcessVisibleTime: "); 11537 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11538 pw.println(sb); 11539 } 11540 if (mHeavyWeightProcess != null && (dumpPackage == null 11541 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11542 if (needSep) { 11543 pw.println(); 11544 needSep = false; 11545 } 11546 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11547 } 11548 if (dumpPackage == null) { 11549 pw.println(" mConfiguration: " + mConfiguration); 11550 } 11551 if (dumpAll) { 11552 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11553 if (mCompatModePackages.getPackages().size() > 0) { 11554 boolean printed = false; 11555 for (Map.Entry<String, Integer> entry 11556 : mCompatModePackages.getPackages().entrySet()) { 11557 String pkg = entry.getKey(); 11558 int mode = entry.getValue(); 11559 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11560 continue; 11561 } 11562 if (!printed) { 11563 pw.println(" mScreenCompatPackages:"); 11564 printed = true; 11565 } 11566 pw.print(" "); pw.print(pkg); pw.print(": "); 11567 pw.print(mode); pw.println(); 11568 } 11569 } 11570 } 11571 if (dumpPackage == null) { 11572 if (mSleeping || mWentToSleep || mLockScreenShown) { 11573 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11574 + " mLockScreenShown " + mLockScreenShown); 11575 } 11576 if (mShuttingDown || mRunningVoice) { 11577 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11578 } 11579 } 11580 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11581 || mOrigWaitForDebugger) { 11582 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11583 || dumpPackage.equals(mOrigDebugApp)) { 11584 if (needSep) { 11585 pw.println(); 11586 needSep = false; 11587 } 11588 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11589 + " mDebugTransient=" + mDebugTransient 11590 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11591 } 11592 } 11593 if (mOpenGlTraceApp != null) { 11594 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11595 if (needSep) { 11596 pw.println(); 11597 needSep = false; 11598 } 11599 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11600 } 11601 } 11602 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11603 || mProfileFd != null) { 11604 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11605 if (needSep) { 11606 pw.println(); 11607 needSep = false; 11608 } 11609 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11610 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11611 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11612 + mAutoStopProfiler); 11613 } 11614 } 11615 if (dumpPackage == null) { 11616 if (mAlwaysFinishActivities || mController != null) { 11617 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11618 + " mController=" + mController); 11619 } 11620 if (dumpAll) { 11621 pw.println(" Total persistent processes: " + numPers); 11622 pw.println(" mProcessesReady=" + mProcessesReady 11623 + " mSystemReady=" + mSystemReady); 11624 pw.println(" mBooting=" + mBooting 11625 + " mBooted=" + mBooted 11626 + " mFactoryTest=" + mFactoryTest); 11627 pw.print(" mLastPowerCheckRealtime="); 11628 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11629 pw.println(""); 11630 pw.print(" mLastPowerCheckUptime="); 11631 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11632 pw.println(""); 11633 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11634 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11635 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11636 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11637 + " (" + mLruProcesses.size() + " total)" 11638 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11639 + " mNumServiceProcs=" + mNumServiceProcs 11640 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11641 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11642 + " mLastMemoryLevel" + mLastMemoryLevel 11643 + " mLastNumProcesses" + mLastNumProcesses); 11644 long now = SystemClock.uptimeMillis(); 11645 pw.print(" mLastIdleTime="); 11646 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11647 pw.print(" mLowRamSinceLastIdle="); 11648 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11649 pw.println(); 11650 } 11651 } 11652 11653 if (!printedAnything) { 11654 pw.println(" (nothing)"); 11655 } 11656 } 11657 11658 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11659 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11660 if (mProcessesToGc.size() > 0) { 11661 boolean printed = false; 11662 long now = SystemClock.uptimeMillis(); 11663 for (int i=0; i<mProcessesToGc.size(); i++) { 11664 ProcessRecord proc = mProcessesToGc.get(i); 11665 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11666 continue; 11667 } 11668 if (!printed) { 11669 if (needSep) pw.println(); 11670 needSep = true; 11671 pw.println(" Processes that are waiting to GC:"); 11672 printed = true; 11673 } 11674 pw.print(" Process "); pw.println(proc); 11675 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11676 pw.print(", last gced="); 11677 pw.print(now-proc.lastRequestedGc); 11678 pw.print(" ms ago, last lowMem="); 11679 pw.print(now-proc.lastLowMemory); 11680 pw.println(" ms ago"); 11681 11682 } 11683 } 11684 return needSep; 11685 } 11686 11687 void printOomLevel(PrintWriter pw, String name, int adj) { 11688 pw.print(" "); 11689 if (adj >= 0) { 11690 pw.print(' '); 11691 if (adj < 10) pw.print(' '); 11692 } else { 11693 if (adj > -10) pw.print(' '); 11694 } 11695 pw.print(adj); 11696 pw.print(": "); 11697 pw.print(name); 11698 pw.print(" ("); 11699 pw.print(mProcessList.getMemLevel(adj)/1024); 11700 pw.println(" kB)"); 11701 } 11702 11703 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11704 int opti, boolean dumpAll) { 11705 boolean needSep = false; 11706 11707 if (mLruProcesses.size() > 0) { 11708 if (needSep) pw.println(); 11709 needSep = true; 11710 pw.println(" OOM levels:"); 11711 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11712 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11713 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11714 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11715 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11716 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11717 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11718 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11719 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11720 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11721 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11722 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11723 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11724 11725 if (needSep) pw.println(); 11726 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11727 pw.print(" total, non-act at "); 11728 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11729 pw.print(", non-svc at "); 11730 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11731 pw.println("):"); 11732 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11733 needSep = true; 11734 } 11735 11736 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11737 11738 pw.println(); 11739 pw.println(" mHomeProcess: " + mHomeProcess); 11740 pw.println(" mPreviousProcess: " + mPreviousProcess); 11741 if (mHeavyWeightProcess != null) { 11742 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11743 } 11744 11745 return true; 11746 } 11747 11748 /** 11749 * There are three ways to call this: 11750 * - no provider specified: dump all the providers 11751 * - a flattened component name that matched an existing provider was specified as the 11752 * first arg: dump that one provider 11753 * - the first arg isn't the flattened component name of an existing provider: 11754 * dump all providers whose component contains the first arg as a substring 11755 */ 11756 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11757 int opti, boolean dumpAll) { 11758 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11759 } 11760 11761 static class ItemMatcher { 11762 ArrayList<ComponentName> components; 11763 ArrayList<String> strings; 11764 ArrayList<Integer> objects; 11765 boolean all; 11766 11767 ItemMatcher() { 11768 all = true; 11769 } 11770 11771 void build(String name) { 11772 ComponentName componentName = ComponentName.unflattenFromString(name); 11773 if (componentName != null) { 11774 if (components == null) { 11775 components = new ArrayList<ComponentName>(); 11776 } 11777 components.add(componentName); 11778 all = false; 11779 } else { 11780 int objectId = 0; 11781 // Not a '/' separated full component name; maybe an object ID? 11782 try { 11783 objectId = Integer.parseInt(name, 16); 11784 if (objects == null) { 11785 objects = new ArrayList<Integer>(); 11786 } 11787 objects.add(objectId); 11788 all = false; 11789 } catch (RuntimeException e) { 11790 // Not an integer; just do string match. 11791 if (strings == null) { 11792 strings = new ArrayList<String>(); 11793 } 11794 strings.add(name); 11795 all = false; 11796 } 11797 } 11798 } 11799 11800 int build(String[] args, int opti) { 11801 for (; opti<args.length; opti++) { 11802 String name = args[opti]; 11803 if ("--".equals(name)) { 11804 return opti+1; 11805 } 11806 build(name); 11807 } 11808 return opti; 11809 } 11810 11811 boolean match(Object object, ComponentName comp) { 11812 if (all) { 11813 return true; 11814 } 11815 if (components != null) { 11816 for (int i=0; i<components.size(); i++) { 11817 if (components.get(i).equals(comp)) { 11818 return true; 11819 } 11820 } 11821 } 11822 if (objects != null) { 11823 for (int i=0; i<objects.size(); i++) { 11824 if (System.identityHashCode(object) == objects.get(i)) { 11825 return true; 11826 } 11827 } 11828 } 11829 if (strings != null) { 11830 String flat = comp.flattenToString(); 11831 for (int i=0; i<strings.size(); i++) { 11832 if (flat.contains(strings.get(i))) { 11833 return true; 11834 } 11835 } 11836 } 11837 return false; 11838 } 11839 } 11840 11841 /** 11842 * There are three things that cmd can be: 11843 * - a flattened component name that matches an existing activity 11844 * - the cmd arg isn't the flattened component name of an existing activity: 11845 * dump all activity whose component contains the cmd as a substring 11846 * - A hex number of the ActivityRecord object instance. 11847 */ 11848 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11849 int opti, boolean dumpAll) { 11850 ArrayList<ActivityRecord> activities; 11851 11852 synchronized (this) { 11853 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11854 } 11855 11856 if (activities.size() <= 0) { 11857 return false; 11858 } 11859 11860 String[] newArgs = new String[args.length - opti]; 11861 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11862 11863 TaskRecord lastTask = null; 11864 boolean needSep = false; 11865 for (int i=activities.size()-1; i>=0; i--) { 11866 ActivityRecord r = activities.get(i); 11867 if (needSep) { 11868 pw.println(); 11869 } 11870 needSep = true; 11871 synchronized (this) { 11872 if (lastTask != r.task) { 11873 lastTask = r.task; 11874 pw.print("TASK "); pw.print(lastTask.affinity); 11875 pw.print(" id="); pw.println(lastTask.taskId); 11876 if (dumpAll) { 11877 lastTask.dump(pw, " "); 11878 } 11879 } 11880 } 11881 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11882 } 11883 return true; 11884 } 11885 11886 /** 11887 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11888 * there is a thread associated with the activity. 11889 */ 11890 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11891 final ActivityRecord r, String[] args, boolean dumpAll) { 11892 String innerPrefix = prefix + " "; 11893 synchronized (this) { 11894 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11895 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11896 pw.print(" pid="); 11897 if (r.app != null) pw.println(r.app.pid); 11898 else pw.println("(not running)"); 11899 if (dumpAll) { 11900 r.dump(pw, innerPrefix); 11901 } 11902 } 11903 if (r.app != null && r.app.thread != null) { 11904 // flush anything that is already in the PrintWriter since the thread is going 11905 // to write to the file descriptor directly 11906 pw.flush(); 11907 try { 11908 TransferPipe tp = new TransferPipe(); 11909 try { 11910 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11911 r.appToken, innerPrefix, args); 11912 tp.go(fd); 11913 } finally { 11914 tp.kill(); 11915 } 11916 } catch (IOException e) { 11917 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11918 } catch (RemoteException e) { 11919 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11920 } 11921 } 11922 } 11923 11924 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11925 int opti, boolean dumpAll, String dumpPackage) { 11926 boolean needSep = false; 11927 boolean onlyHistory = false; 11928 boolean printedAnything = false; 11929 11930 if ("history".equals(dumpPackage)) { 11931 if (opti < args.length && "-s".equals(args[opti])) { 11932 dumpAll = false; 11933 } 11934 onlyHistory = true; 11935 dumpPackage = null; 11936 } 11937 11938 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11939 if (!onlyHistory && dumpAll) { 11940 if (mRegisteredReceivers.size() > 0) { 11941 boolean printed = false; 11942 Iterator it = mRegisteredReceivers.values().iterator(); 11943 while (it.hasNext()) { 11944 ReceiverList r = (ReceiverList)it.next(); 11945 if (dumpPackage != null && (r.app == null || 11946 !dumpPackage.equals(r.app.info.packageName))) { 11947 continue; 11948 } 11949 if (!printed) { 11950 pw.println(" Registered Receivers:"); 11951 needSep = true; 11952 printed = true; 11953 printedAnything = true; 11954 } 11955 pw.print(" * "); pw.println(r); 11956 r.dump(pw, " "); 11957 } 11958 } 11959 11960 if (mReceiverResolver.dump(pw, needSep ? 11961 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11962 " ", dumpPackage, false)) { 11963 needSep = true; 11964 printedAnything = true; 11965 } 11966 } 11967 11968 for (BroadcastQueue q : mBroadcastQueues) { 11969 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11970 printedAnything |= needSep; 11971 } 11972 11973 needSep = true; 11974 11975 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11976 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11977 if (needSep) { 11978 pw.println(); 11979 } 11980 needSep = true; 11981 printedAnything = true; 11982 pw.print(" Sticky broadcasts for user "); 11983 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11984 StringBuilder sb = new StringBuilder(128); 11985 for (Map.Entry<String, ArrayList<Intent>> ent 11986 : mStickyBroadcasts.valueAt(user).entrySet()) { 11987 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11988 if (dumpAll) { 11989 pw.println(":"); 11990 ArrayList<Intent> intents = ent.getValue(); 11991 final int N = intents.size(); 11992 for (int i=0; i<N; i++) { 11993 sb.setLength(0); 11994 sb.append(" Intent: "); 11995 intents.get(i).toShortString(sb, false, true, false, false); 11996 pw.println(sb.toString()); 11997 Bundle bundle = intents.get(i).getExtras(); 11998 if (bundle != null) { 11999 pw.print(" "); 12000 pw.println(bundle.toString()); 12001 } 12002 } 12003 } else { 12004 pw.println(""); 12005 } 12006 } 12007 } 12008 } 12009 12010 if (!onlyHistory && dumpAll) { 12011 pw.println(); 12012 for (BroadcastQueue queue : mBroadcastQueues) { 12013 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12014 + queue.mBroadcastsScheduled); 12015 } 12016 pw.println(" mHandler:"); 12017 mHandler.dump(new PrintWriterPrinter(pw), " "); 12018 needSep = true; 12019 printedAnything = true; 12020 } 12021 12022 if (!printedAnything) { 12023 pw.println(" (nothing)"); 12024 } 12025 } 12026 12027 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12028 int opti, boolean dumpAll, String dumpPackage) { 12029 boolean needSep; 12030 boolean printedAnything = false; 12031 12032 ItemMatcher matcher = new ItemMatcher(); 12033 matcher.build(args, opti); 12034 12035 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12036 12037 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12038 printedAnything |= needSep; 12039 12040 if (mLaunchingProviders.size() > 0) { 12041 boolean printed = false; 12042 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12043 ContentProviderRecord r = mLaunchingProviders.get(i); 12044 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12045 continue; 12046 } 12047 if (!printed) { 12048 if (needSep) pw.println(); 12049 needSep = true; 12050 pw.println(" Launching content providers:"); 12051 printed = true; 12052 printedAnything = true; 12053 } 12054 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12055 pw.println(r); 12056 } 12057 } 12058 12059 if (mGrantedUriPermissions.size() > 0) { 12060 boolean printed = false; 12061 int dumpUid = -2; 12062 if (dumpPackage != null) { 12063 try { 12064 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12065 } catch (NameNotFoundException e) { 12066 dumpUid = -1; 12067 } 12068 } 12069 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12070 int uid = mGrantedUriPermissions.keyAt(i); 12071 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12072 continue; 12073 } 12074 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12075 if (!printed) { 12076 if (needSep) pw.println(); 12077 needSep = true; 12078 pw.println(" Granted Uri Permissions:"); 12079 printed = true; 12080 printedAnything = true; 12081 } 12082 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12083 for (UriPermission perm : perms.values()) { 12084 pw.print(" "); pw.println(perm); 12085 if (dumpAll) { 12086 perm.dump(pw, " "); 12087 } 12088 } 12089 } 12090 } 12091 12092 if (!printedAnything) { 12093 pw.println(" (nothing)"); 12094 } 12095 } 12096 12097 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12098 int opti, boolean dumpAll, String dumpPackage) { 12099 boolean printed = false; 12100 12101 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12102 12103 if (mIntentSenderRecords.size() > 0) { 12104 Iterator<WeakReference<PendingIntentRecord>> it 12105 = mIntentSenderRecords.values().iterator(); 12106 while (it.hasNext()) { 12107 WeakReference<PendingIntentRecord> ref = it.next(); 12108 PendingIntentRecord rec = ref != null ? ref.get(): null; 12109 if (dumpPackage != null && (rec == null 12110 || !dumpPackage.equals(rec.key.packageName))) { 12111 continue; 12112 } 12113 printed = true; 12114 if (rec != null) { 12115 pw.print(" * "); pw.println(rec); 12116 if (dumpAll) { 12117 rec.dump(pw, " "); 12118 } 12119 } else { 12120 pw.print(" * "); pw.println(ref); 12121 } 12122 } 12123 } 12124 12125 if (!printed) { 12126 pw.println(" (nothing)"); 12127 } 12128 } 12129 12130 private static final int dumpProcessList(PrintWriter pw, 12131 ActivityManagerService service, List list, 12132 String prefix, String normalLabel, String persistentLabel, 12133 String dumpPackage) { 12134 int numPers = 0; 12135 final int N = list.size()-1; 12136 for (int i=N; i>=0; i--) { 12137 ProcessRecord r = (ProcessRecord)list.get(i); 12138 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12139 continue; 12140 } 12141 pw.println(String.format("%s%s #%2d: %s", 12142 prefix, (r.persistent ? persistentLabel : normalLabel), 12143 i, r.toString())); 12144 if (r.persistent) { 12145 numPers++; 12146 } 12147 } 12148 return numPers; 12149 } 12150 12151 private static final boolean dumpProcessOomList(PrintWriter pw, 12152 ActivityManagerService service, List<ProcessRecord> origList, 12153 String prefix, String normalLabel, String persistentLabel, 12154 boolean inclDetails, String dumpPackage) { 12155 12156 ArrayList<Pair<ProcessRecord, Integer>> list 12157 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12158 for (int i=0; i<origList.size(); i++) { 12159 ProcessRecord r = origList.get(i); 12160 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12161 continue; 12162 } 12163 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12164 } 12165 12166 if (list.size() <= 0) { 12167 return false; 12168 } 12169 12170 Comparator<Pair<ProcessRecord, Integer>> comparator 12171 = new Comparator<Pair<ProcessRecord, Integer>>() { 12172 @Override 12173 public int compare(Pair<ProcessRecord, Integer> object1, 12174 Pair<ProcessRecord, Integer> object2) { 12175 if (object1.first.setAdj != object2.first.setAdj) { 12176 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12177 } 12178 if (object1.second.intValue() != object2.second.intValue()) { 12179 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12180 } 12181 return 0; 12182 } 12183 }; 12184 12185 Collections.sort(list, comparator); 12186 12187 final long curRealtime = SystemClock.elapsedRealtime(); 12188 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12189 final long curUptime = SystemClock.uptimeMillis(); 12190 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12191 12192 for (int i=list.size()-1; i>=0; i--) { 12193 ProcessRecord r = list.get(i).first; 12194 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12195 char schedGroup; 12196 switch (r.setSchedGroup) { 12197 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12198 schedGroup = 'B'; 12199 break; 12200 case Process.THREAD_GROUP_DEFAULT: 12201 schedGroup = 'F'; 12202 break; 12203 default: 12204 schedGroup = '?'; 12205 break; 12206 } 12207 char foreground; 12208 if (r.foregroundActivities) { 12209 foreground = 'A'; 12210 } else if (r.foregroundServices) { 12211 foreground = 'S'; 12212 } else { 12213 foreground = ' '; 12214 } 12215 String procState = ProcessList.makeProcStateString(r.curProcState); 12216 pw.print(prefix); 12217 pw.print(r.persistent ? persistentLabel : normalLabel); 12218 pw.print(" #"); 12219 int num = (origList.size()-1)-list.get(i).second; 12220 if (num < 10) pw.print(' '); 12221 pw.print(num); 12222 pw.print(": "); 12223 pw.print(oomAdj); 12224 pw.print(' '); 12225 pw.print(schedGroup); 12226 pw.print('/'); 12227 pw.print(foreground); 12228 pw.print('/'); 12229 pw.print(procState); 12230 pw.print(" trm:"); 12231 if (r.trimMemoryLevel < 10) pw.print(' '); 12232 pw.print(r.trimMemoryLevel); 12233 pw.print(' '); 12234 pw.print(r.toShortString()); 12235 pw.print(" ("); 12236 pw.print(r.adjType); 12237 pw.println(')'); 12238 if (r.adjSource != null || r.adjTarget != null) { 12239 pw.print(prefix); 12240 pw.print(" "); 12241 if (r.adjTarget instanceof ComponentName) { 12242 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12243 } else if (r.adjTarget != null) { 12244 pw.print(r.adjTarget.toString()); 12245 } else { 12246 pw.print("{null}"); 12247 } 12248 pw.print("<="); 12249 if (r.adjSource instanceof ProcessRecord) { 12250 pw.print("Proc{"); 12251 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12252 pw.println("}"); 12253 } else if (r.adjSource != null) { 12254 pw.println(r.adjSource.toString()); 12255 } else { 12256 pw.println("{null}"); 12257 } 12258 } 12259 if (inclDetails) { 12260 pw.print(prefix); 12261 pw.print(" "); 12262 pw.print("oom: max="); pw.print(r.maxAdj); 12263 pw.print(" curRaw="); pw.print(r.curRawAdj); 12264 pw.print(" setRaw="); pw.print(r.setRawAdj); 12265 pw.print(" cur="); pw.print(r.curAdj); 12266 pw.print(" set="); pw.println(r.setAdj); 12267 pw.print(prefix); 12268 pw.print(" "); 12269 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12270 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12271 pw.print(" lastPss="); pw.print(r.lastPss); 12272 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12273 pw.print(prefix); 12274 pw.print(" "); 12275 pw.print("keeping="); pw.print(r.keeping); 12276 pw.print(" cached="); pw.print(r.cached); 12277 pw.print(" empty="); pw.print(r.empty); 12278 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12279 12280 if (!r.keeping) { 12281 if (r.lastWakeTime != 0) { 12282 long wtime; 12283 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12284 synchronized (stats) { 12285 wtime = stats.getProcessWakeTime(r.info.uid, 12286 r.pid, curRealtime); 12287 } 12288 long timeUsed = wtime - r.lastWakeTime; 12289 pw.print(prefix); 12290 pw.print(" "); 12291 pw.print("keep awake over "); 12292 TimeUtils.formatDuration(realtimeSince, pw); 12293 pw.print(" used "); 12294 TimeUtils.formatDuration(timeUsed, pw); 12295 pw.print(" ("); 12296 pw.print((timeUsed*100)/realtimeSince); 12297 pw.println("%)"); 12298 } 12299 if (r.lastCpuTime != 0) { 12300 long timeUsed = r.curCpuTime - r.lastCpuTime; 12301 pw.print(prefix); 12302 pw.print(" "); 12303 pw.print("run cpu over "); 12304 TimeUtils.formatDuration(uptimeSince, pw); 12305 pw.print(" used "); 12306 TimeUtils.formatDuration(timeUsed, pw); 12307 pw.print(" ("); 12308 pw.print((timeUsed*100)/uptimeSince); 12309 pw.println("%)"); 12310 } 12311 } 12312 } 12313 } 12314 return true; 12315 } 12316 12317 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12318 ArrayList<ProcessRecord> procs; 12319 synchronized (this) { 12320 if (args != null && args.length > start 12321 && args[start].charAt(0) != '-') { 12322 procs = new ArrayList<ProcessRecord>(); 12323 int pid = -1; 12324 try { 12325 pid = Integer.parseInt(args[start]); 12326 } catch (NumberFormatException e) { 12327 } 12328 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12329 ProcessRecord proc = mLruProcesses.get(i); 12330 if (proc.pid == pid) { 12331 procs.add(proc); 12332 } else if (proc.processName.equals(args[start])) { 12333 procs.add(proc); 12334 } 12335 } 12336 if (procs.size() <= 0) { 12337 return null; 12338 } 12339 } else { 12340 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12341 } 12342 } 12343 return procs; 12344 } 12345 12346 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12347 PrintWriter pw, String[] args) { 12348 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12349 if (procs == null) { 12350 pw.println("No process found for: " + args[0]); 12351 return; 12352 } 12353 12354 long uptime = SystemClock.uptimeMillis(); 12355 long realtime = SystemClock.elapsedRealtime(); 12356 pw.println("Applications Graphics Acceleration Info:"); 12357 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12358 12359 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12360 ProcessRecord r = procs.get(i); 12361 if (r.thread != null) { 12362 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12363 pw.flush(); 12364 try { 12365 TransferPipe tp = new TransferPipe(); 12366 try { 12367 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12368 tp.go(fd); 12369 } finally { 12370 tp.kill(); 12371 } 12372 } catch (IOException e) { 12373 pw.println("Failure while dumping the app: " + r); 12374 pw.flush(); 12375 } catch (RemoteException e) { 12376 pw.println("Got a RemoteException while dumping the app " + r); 12377 pw.flush(); 12378 } 12379 } 12380 } 12381 } 12382 12383 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12384 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12385 if (procs == null) { 12386 pw.println("No process found for: " + args[0]); 12387 return; 12388 } 12389 12390 pw.println("Applications Database Info:"); 12391 12392 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12393 ProcessRecord r = procs.get(i); 12394 if (r.thread != null) { 12395 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12396 pw.flush(); 12397 try { 12398 TransferPipe tp = new TransferPipe(); 12399 try { 12400 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12401 tp.go(fd); 12402 } finally { 12403 tp.kill(); 12404 } 12405 } catch (IOException e) { 12406 pw.println("Failure while dumping the app: " + r); 12407 pw.flush(); 12408 } catch (RemoteException e) { 12409 pw.println("Got a RemoteException while dumping the app " + r); 12410 pw.flush(); 12411 } 12412 } 12413 } 12414 } 12415 12416 final static class MemItem { 12417 final boolean isProc; 12418 final String label; 12419 final String shortLabel; 12420 final long pss; 12421 final int id; 12422 final boolean hasActivities; 12423 ArrayList<MemItem> subitems; 12424 12425 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12426 boolean _hasActivities) { 12427 isProc = true; 12428 label = _label; 12429 shortLabel = _shortLabel; 12430 pss = _pss; 12431 id = _id; 12432 hasActivities = _hasActivities; 12433 } 12434 12435 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12436 isProc = false; 12437 label = _label; 12438 shortLabel = _shortLabel; 12439 pss = _pss; 12440 id = _id; 12441 hasActivities = false; 12442 } 12443 } 12444 12445 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12446 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12447 if (sort && !isCompact) { 12448 Collections.sort(items, new Comparator<MemItem>() { 12449 @Override 12450 public int compare(MemItem lhs, MemItem rhs) { 12451 if (lhs.pss < rhs.pss) { 12452 return 1; 12453 } else if (lhs.pss > rhs.pss) { 12454 return -1; 12455 } 12456 return 0; 12457 } 12458 }); 12459 } 12460 12461 for (int i=0; i<items.size(); i++) { 12462 MemItem mi = items.get(i); 12463 if (!isCompact) { 12464 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12465 } else if (mi.isProc) { 12466 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12467 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12468 pw.println(mi.hasActivities ? ",a" : ",e"); 12469 } else { 12470 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12471 pw.println(mi.pss); 12472 } 12473 if (mi.subitems != null) { 12474 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12475 true, isCompact); 12476 } 12477 } 12478 } 12479 12480 // These are in KB. 12481 static final long[] DUMP_MEM_BUCKETS = new long[] { 12482 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12483 120*1024, 160*1024, 200*1024, 12484 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12485 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12486 }; 12487 12488 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12489 boolean stackLike) { 12490 int start = label.lastIndexOf('.'); 12491 if (start >= 0) start++; 12492 else start = 0; 12493 int end = label.length(); 12494 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12495 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12496 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12497 out.append(bucket); 12498 out.append(stackLike ? "MB." : "MB "); 12499 out.append(label, start, end); 12500 return; 12501 } 12502 } 12503 out.append(memKB/1024); 12504 out.append(stackLike ? "MB." : "MB "); 12505 out.append(label, start, end); 12506 } 12507 12508 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12509 ProcessList.NATIVE_ADJ, 12510 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12511 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12512 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12513 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12514 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12515 }; 12516 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12517 "Native", 12518 "System", "Persistent", "Foreground", 12519 "Visible", "Perceptible", 12520 "Heavy Weight", "Backup", 12521 "A Services", "Home", 12522 "Previous", "B Services", "Cached" 12523 }; 12524 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12525 "native", 12526 "sys", "pers", "fore", 12527 "vis", "percept", 12528 "heavy", "backup", 12529 "servicea", "home", 12530 "prev", "serviceb", "cached" 12531 }; 12532 12533 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12534 long realtime, boolean isCheckinRequest, boolean isCompact) { 12535 if (isCheckinRequest || isCompact) { 12536 // short checkin version 12537 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12538 } else { 12539 pw.println("Applications Memory Usage (kB):"); 12540 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12541 } 12542 } 12543 12544 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12545 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12546 boolean dumpDetails = false; 12547 boolean dumpFullDetails = false; 12548 boolean dumpDalvik = false; 12549 boolean oomOnly = false; 12550 boolean isCompact = false; 12551 boolean localOnly = false; 12552 12553 int opti = 0; 12554 while (opti < args.length) { 12555 String opt = args[opti]; 12556 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12557 break; 12558 } 12559 opti++; 12560 if ("-a".equals(opt)) { 12561 dumpDetails = true; 12562 dumpFullDetails = true; 12563 dumpDalvik = true; 12564 } else if ("-d".equals(opt)) { 12565 dumpDalvik = true; 12566 } else if ("-c".equals(opt)) { 12567 isCompact = true; 12568 } else if ("--oom".equals(opt)) { 12569 oomOnly = true; 12570 } else if ("--local".equals(opt)) { 12571 localOnly = true; 12572 } else if ("-h".equals(opt)) { 12573 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12574 pw.println(" -a: include all available information for each process."); 12575 pw.println(" -d: include dalvik details when dumping process details."); 12576 pw.println(" -c: dump in a compact machine-parseable representation."); 12577 pw.println(" --oom: only show processes organized by oom adj."); 12578 pw.println(" --local: only collect details locally, don't call process."); 12579 pw.println("If [process] is specified it can be the name or "); 12580 pw.println("pid of a specific process to dump."); 12581 return; 12582 } else { 12583 pw.println("Unknown argument: " + opt + "; use -h for help"); 12584 } 12585 } 12586 12587 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12588 long uptime = SystemClock.uptimeMillis(); 12589 long realtime = SystemClock.elapsedRealtime(); 12590 final long[] tmpLong = new long[1]; 12591 12592 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12593 if (procs == null) { 12594 // No Java processes. Maybe they want to print a native process. 12595 if (args != null && args.length > opti 12596 && args[opti].charAt(0) != '-') { 12597 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12598 = new ArrayList<ProcessCpuTracker.Stats>(); 12599 updateCpuStatsNow(); 12600 int findPid = -1; 12601 try { 12602 findPid = Integer.parseInt(args[opti]); 12603 } catch (NumberFormatException e) { 12604 } 12605 synchronized (mProcessCpuThread) { 12606 final int N = mProcessCpuTracker.countStats(); 12607 for (int i=0; i<N; i++) { 12608 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12609 if (st.pid == findPid || (st.baseName != null 12610 && st.baseName.equals(args[opti]))) { 12611 nativeProcs.add(st); 12612 } 12613 } 12614 } 12615 if (nativeProcs.size() > 0) { 12616 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12617 isCompact); 12618 Debug.MemoryInfo mi = null; 12619 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12620 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12621 final int pid = r.pid; 12622 if (!isCheckinRequest && dumpDetails) { 12623 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12624 } 12625 if (mi == null) { 12626 mi = new Debug.MemoryInfo(); 12627 } 12628 if (dumpDetails || (!brief && !oomOnly)) { 12629 Debug.getMemoryInfo(pid, mi); 12630 } else { 12631 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12632 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12633 } 12634 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12635 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12636 if (isCheckinRequest) { 12637 pw.println(); 12638 } 12639 } 12640 return; 12641 } 12642 } 12643 pw.println("No process found for: " + args[opti]); 12644 return; 12645 } 12646 12647 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12648 dumpDetails = true; 12649 } 12650 12651 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12652 12653 String[] innerArgs = new String[args.length-opti]; 12654 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12655 12656 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12657 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12658 long nativePss=0, dalvikPss=0, otherPss=0; 12659 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12660 12661 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12662 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12663 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12664 12665 long totalPss = 0; 12666 long cachedPss = 0; 12667 12668 Debug.MemoryInfo mi = null; 12669 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12670 final ProcessRecord r = procs.get(i); 12671 final IApplicationThread thread; 12672 final int pid; 12673 final int oomAdj; 12674 final boolean hasActivities; 12675 synchronized (this) { 12676 thread = r.thread; 12677 pid = r.pid; 12678 oomAdj = r.getSetAdjWithServices(); 12679 hasActivities = r.activities.size() > 0; 12680 } 12681 if (thread != null) { 12682 if (!isCheckinRequest && dumpDetails) { 12683 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12684 } 12685 if (mi == null) { 12686 mi = new Debug.MemoryInfo(); 12687 } 12688 if (dumpDetails || (!brief && !oomOnly)) { 12689 Debug.getMemoryInfo(pid, mi); 12690 } else { 12691 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12692 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12693 } 12694 if (dumpDetails) { 12695 if (localOnly) { 12696 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12697 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12698 if (isCheckinRequest) { 12699 pw.println(); 12700 } 12701 } else { 12702 try { 12703 pw.flush(); 12704 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12705 dumpDalvik, innerArgs); 12706 } catch (RemoteException e) { 12707 if (!isCheckinRequest) { 12708 pw.println("Got RemoteException!"); 12709 pw.flush(); 12710 } 12711 } 12712 } 12713 } 12714 12715 final long myTotalPss = mi.getTotalPss(); 12716 final long myTotalUss = mi.getTotalUss(); 12717 12718 synchronized (this) { 12719 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12720 // Record this for posterity if the process has been stable. 12721 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12722 } 12723 } 12724 12725 if (!isCheckinRequest && mi != null) { 12726 totalPss += myTotalPss; 12727 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12728 (hasActivities ? " / activities)" : ")"), 12729 r.processName, myTotalPss, pid, hasActivities); 12730 procMems.add(pssItem); 12731 procMemsMap.put(pid, pssItem); 12732 12733 nativePss += mi.nativePss; 12734 dalvikPss += mi.dalvikPss; 12735 otherPss += mi.otherPss; 12736 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12737 long mem = mi.getOtherPss(j); 12738 miscPss[j] += mem; 12739 otherPss -= mem; 12740 } 12741 12742 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12743 cachedPss += myTotalPss; 12744 } 12745 12746 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12747 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12748 || oomIndex == (oomPss.length-1)) { 12749 oomPss[oomIndex] += myTotalPss; 12750 if (oomProcs[oomIndex] == null) { 12751 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12752 } 12753 oomProcs[oomIndex].add(pssItem); 12754 break; 12755 } 12756 } 12757 } 12758 } 12759 } 12760 12761 long nativeProcTotalPss = 0; 12762 12763 if (!isCheckinRequest && procs.size() > 1) { 12764 // If we are showing aggregations, also look for native processes to 12765 // include so that our aggregations are more accurate. 12766 updateCpuStatsNow(); 12767 synchronized (mProcessCpuThread) { 12768 final int N = mProcessCpuTracker.countStats(); 12769 for (int i=0; i<N; i++) { 12770 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12771 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12772 if (mi == null) { 12773 mi = new Debug.MemoryInfo(); 12774 } 12775 if (!brief && !oomOnly) { 12776 Debug.getMemoryInfo(st.pid, mi); 12777 } else { 12778 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12779 mi.nativePrivateDirty = (int)tmpLong[0]; 12780 } 12781 12782 final long myTotalPss = mi.getTotalPss(); 12783 totalPss += myTotalPss; 12784 nativeProcTotalPss += myTotalPss; 12785 12786 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12787 st.name, myTotalPss, st.pid, false); 12788 procMems.add(pssItem); 12789 12790 nativePss += mi.nativePss; 12791 dalvikPss += mi.dalvikPss; 12792 otherPss += mi.otherPss; 12793 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12794 long mem = mi.getOtherPss(j); 12795 miscPss[j] += mem; 12796 otherPss -= mem; 12797 } 12798 oomPss[0] += myTotalPss; 12799 if (oomProcs[0] == null) { 12800 oomProcs[0] = new ArrayList<MemItem>(); 12801 } 12802 oomProcs[0].add(pssItem); 12803 } 12804 } 12805 } 12806 12807 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12808 12809 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12810 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12811 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12812 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12813 String label = Debug.MemoryInfo.getOtherLabel(j); 12814 catMems.add(new MemItem(label, label, miscPss[j], j)); 12815 } 12816 12817 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12818 for (int j=0; j<oomPss.length; j++) { 12819 if (oomPss[j] != 0) { 12820 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12821 : DUMP_MEM_OOM_LABEL[j]; 12822 MemItem item = new MemItem(label, label, oomPss[j], 12823 DUMP_MEM_OOM_ADJ[j]); 12824 item.subitems = oomProcs[j]; 12825 oomMems.add(item); 12826 } 12827 } 12828 12829 if (!brief && !oomOnly && !isCompact) { 12830 pw.println(); 12831 pw.println("Total PSS by process:"); 12832 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12833 pw.println(); 12834 } 12835 if (!isCompact) { 12836 pw.println("Total PSS by OOM adjustment:"); 12837 } 12838 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12839 if (!brief && !oomOnly) { 12840 PrintWriter out = categoryPw != null ? categoryPw : pw; 12841 if (!isCompact) { 12842 out.println(); 12843 out.println("Total PSS by category:"); 12844 } 12845 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12846 } 12847 if (!isCompact) { 12848 pw.println(); 12849 } 12850 MemInfoReader memInfo = new MemInfoReader(); 12851 memInfo.readMemInfo(); 12852 if (nativeProcTotalPss > 0) { 12853 synchronized (this) { 12854 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 12855 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 12856 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 12857 nativeProcTotalPss); 12858 } 12859 } 12860 if (!brief) { 12861 if (!isCompact) { 12862 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12863 pw.print(" kB (status "); 12864 switch (mLastMemoryLevel) { 12865 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12866 pw.println("normal)"); 12867 break; 12868 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12869 pw.println("moderate)"); 12870 break; 12871 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12872 pw.println("low)"); 12873 break; 12874 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12875 pw.println("critical)"); 12876 break; 12877 default: 12878 pw.print(mLastMemoryLevel); 12879 pw.println(")"); 12880 break; 12881 } 12882 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12883 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12884 pw.print(cachedPss); pw.print(" cached pss + "); 12885 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12886 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12887 } else { 12888 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12889 pw.print(cachedPss + memInfo.getCachedSizeKb() 12890 + memInfo.getFreeSizeKb()); pw.print(","); 12891 pw.println(totalPss - cachedPss); 12892 } 12893 } 12894 if (!isCompact) { 12895 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12896 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12897 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12898 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12899 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12900 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12901 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12902 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12903 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12904 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12905 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12906 } 12907 if (!brief) { 12908 if (memInfo.getZramTotalSizeKb() != 0) { 12909 if (!isCompact) { 12910 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12911 pw.print(" kB physical used for "); 12912 pw.print(memInfo.getSwapTotalSizeKb() 12913 - memInfo.getSwapFreeSizeKb()); 12914 pw.print(" kB in swap ("); 12915 pw.print(memInfo.getSwapTotalSizeKb()); 12916 pw.println(" kB total swap)"); 12917 } else { 12918 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12919 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12920 pw.println(memInfo.getSwapFreeSizeKb()); 12921 } 12922 } 12923 final int[] SINGLE_LONG_FORMAT = new int[] { 12924 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12925 }; 12926 long[] longOut = new long[1]; 12927 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12928 SINGLE_LONG_FORMAT, null, longOut, null); 12929 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12930 longOut[0] = 0; 12931 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12932 SINGLE_LONG_FORMAT, null, longOut, null); 12933 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12934 longOut[0] = 0; 12935 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12936 SINGLE_LONG_FORMAT, null, longOut, null); 12937 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12938 longOut[0] = 0; 12939 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12940 SINGLE_LONG_FORMAT, null, longOut, null); 12941 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12942 if (!isCompact) { 12943 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12944 pw.print(" KSM: "); pw.print(sharing); 12945 pw.print(" kB saved from shared "); 12946 pw.print(shared); pw.println(" kB"); 12947 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12948 pw.print(voltile); pw.println(" kB volatile"); 12949 } 12950 pw.print(" Tuning: "); 12951 pw.print(ActivityManager.staticGetMemoryClass()); 12952 pw.print(" (large "); 12953 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12954 pw.print("), oom "); 12955 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12956 pw.print(" kB"); 12957 pw.print(", restore limit "); 12958 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12959 pw.print(" kB"); 12960 if (ActivityManager.isLowRamDeviceStatic()) { 12961 pw.print(" (low-ram)"); 12962 } 12963 if (ActivityManager.isHighEndGfx()) { 12964 pw.print(" (high-end-gfx)"); 12965 } 12966 pw.println(); 12967 } else { 12968 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12969 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12970 pw.println(voltile); 12971 pw.print("tuning,"); 12972 pw.print(ActivityManager.staticGetMemoryClass()); 12973 pw.print(','); 12974 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12975 pw.print(','); 12976 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12977 if (ActivityManager.isLowRamDeviceStatic()) { 12978 pw.print(",low-ram"); 12979 } 12980 if (ActivityManager.isHighEndGfx()) { 12981 pw.print(",high-end-gfx"); 12982 } 12983 pw.println(); 12984 } 12985 } 12986 } 12987 } 12988 12989 /** 12990 * Searches array of arguments for the specified string 12991 * @param args array of argument strings 12992 * @param value value to search for 12993 * @return true if the value is contained in the array 12994 */ 12995 private static boolean scanArgs(String[] args, String value) { 12996 if (args != null) { 12997 for (String arg : args) { 12998 if (value.equals(arg)) { 12999 return true; 13000 } 13001 } 13002 } 13003 return false; 13004 } 13005 13006 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13007 ContentProviderRecord cpr, boolean always) { 13008 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13009 13010 if (!inLaunching || always) { 13011 synchronized (cpr) { 13012 cpr.launchingApp = null; 13013 cpr.notifyAll(); 13014 } 13015 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13016 String names[] = cpr.info.authority.split(";"); 13017 for (int j = 0; j < names.length; j++) { 13018 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13019 } 13020 } 13021 13022 for (int i=0; i<cpr.connections.size(); i++) { 13023 ContentProviderConnection conn = cpr.connections.get(i); 13024 if (conn.waiting) { 13025 // If this connection is waiting for the provider, then we don't 13026 // need to mess with its process unless we are always removing 13027 // or for some reason the provider is not currently launching. 13028 if (inLaunching && !always) { 13029 continue; 13030 } 13031 } 13032 ProcessRecord capp = conn.client; 13033 conn.dead = true; 13034 if (conn.stableCount > 0) { 13035 if (!capp.persistent && capp.thread != null 13036 && capp.pid != 0 13037 && capp.pid != MY_PID) { 13038 killUnneededProcessLocked(capp, "depends on provider " 13039 + cpr.name.flattenToShortString() 13040 + " in dying proc " + (proc != null ? proc.processName : "??")); 13041 } 13042 } else if (capp.thread != null && conn.provider.provider != null) { 13043 try { 13044 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13045 } catch (RemoteException e) { 13046 } 13047 // In the protocol here, we don't expect the client to correctly 13048 // clean up this connection, we'll just remove it. 13049 cpr.connections.remove(i); 13050 conn.client.conProviders.remove(conn); 13051 } 13052 } 13053 13054 if (inLaunching && always) { 13055 mLaunchingProviders.remove(cpr); 13056 } 13057 return inLaunching; 13058 } 13059 13060 /** 13061 * Main code for cleaning up a process when it has gone away. This is 13062 * called both as a result of the process dying, or directly when stopping 13063 * a process when running in single process mode. 13064 */ 13065 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13066 boolean restarting, boolean allowRestart, int index) { 13067 if (index >= 0) { 13068 removeLruProcessLocked(app); 13069 ProcessList.remove(app.pid); 13070 } 13071 13072 mProcessesToGc.remove(app); 13073 mPendingPssProcesses.remove(app); 13074 13075 // Dismiss any open dialogs. 13076 if (app.crashDialog != null && !app.forceCrashReport) { 13077 app.crashDialog.dismiss(); 13078 app.crashDialog = null; 13079 } 13080 if (app.anrDialog != null) { 13081 app.anrDialog.dismiss(); 13082 app.anrDialog = null; 13083 } 13084 if (app.waitDialog != null) { 13085 app.waitDialog.dismiss(); 13086 app.waitDialog = null; 13087 } 13088 13089 app.crashing = false; 13090 app.notResponding = false; 13091 13092 app.resetPackageList(mProcessStats); 13093 app.unlinkDeathRecipient(); 13094 app.makeInactive(mProcessStats); 13095 app.forcingToForeground = null; 13096 updateProcessForegroundLocked(app, false, false); 13097 app.foregroundActivities = false; 13098 app.hasShownUi = false; 13099 app.treatLikeActivity = false; 13100 app.hasAboveClient = false; 13101 app.hasClientActivities = false; 13102 13103 mServices.killServicesLocked(app, allowRestart); 13104 13105 boolean restart = false; 13106 13107 // Remove published content providers. 13108 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13109 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13110 final boolean always = app.bad || !allowRestart; 13111 if (removeDyingProviderLocked(app, cpr, always) || always) { 13112 // We left the provider in the launching list, need to 13113 // restart it. 13114 restart = true; 13115 } 13116 13117 cpr.provider = null; 13118 cpr.proc = null; 13119 } 13120 app.pubProviders.clear(); 13121 13122 // Take care of any launching providers waiting for this process. 13123 if (checkAppInLaunchingProvidersLocked(app, false)) { 13124 restart = true; 13125 } 13126 13127 // Unregister from connected content providers. 13128 if (!app.conProviders.isEmpty()) { 13129 for (int i=0; i<app.conProviders.size(); i++) { 13130 ContentProviderConnection conn = app.conProviders.get(i); 13131 conn.provider.connections.remove(conn); 13132 } 13133 app.conProviders.clear(); 13134 } 13135 13136 // At this point there may be remaining entries in mLaunchingProviders 13137 // where we were the only one waiting, so they are no longer of use. 13138 // Look for these and clean up if found. 13139 // XXX Commented out for now. Trying to figure out a way to reproduce 13140 // the actual situation to identify what is actually going on. 13141 if (false) { 13142 for (int i=0; i<mLaunchingProviders.size(); i++) { 13143 ContentProviderRecord cpr = (ContentProviderRecord) 13144 mLaunchingProviders.get(i); 13145 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13146 synchronized (cpr) { 13147 cpr.launchingApp = null; 13148 cpr.notifyAll(); 13149 } 13150 } 13151 } 13152 } 13153 13154 skipCurrentReceiverLocked(app); 13155 13156 // Unregister any receivers. 13157 for (int i=app.receivers.size()-1; i>=0; i--) { 13158 removeReceiverLocked(app.receivers.valueAt(i)); 13159 } 13160 app.receivers.clear(); 13161 13162 // If the app is undergoing backup, tell the backup manager about it 13163 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13164 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13165 + mBackupTarget.appInfo + " died during backup"); 13166 try { 13167 IBackupManager bm = IBackupManager.Stub.asInterface( 13168 ServiceManager.getService(Context.BACKUP_SERVICE)); 13169 bm.agentDisconnected(app.info.packageName); 13170 } catch (RemoteException e) { 13171 // can't happen; backup manager is local 13172 } 13173 } 13174 13175 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13176 ProcessChangeItem item = mPendingProcessChanges.get(i); 13177 if (item.pid == app.pid) { 13178 mPendingProcessChanges.remove(i); 13179 mAvailProcessChanges.add(item); 13180 } 13181 } 13182 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13183 13184 // If the caller is restarting this app, then leave it in its 13185 // current lists and let the caller take care of it. 13186 if (restarting) { 13187 return; 13188 } 13189 13190 if (!app.persistent || app.isolated) { 13191 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13192 "Removing non-persistent process during cleanup: " + app); 13193 mProcessNames.remove(app.processName, app.uid); 13194 mIsolatedProcesses.remove(app.uid); 13195 if (mHeavyWeightProcess == app) { 13196 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13197 mHeavyWeightProcess.userId, 0)); 13198 mHeavyWeightProcess = null; 13199 } 13200 } else if (!app.removed) { 13201 // This app is persistent, so we need to keep its record around. 13202 // If it is not already on the pending app list, add it there 13203 // and start a new process for it. 13204 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13205 mPersistentStartingProcesses.add(app); 13206 restart = true; 13207 } 13208 } 13209 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13210 "Clean-up removing on hold: " + app); 13211 mProcessesOnHold.remove(app); 13212 13213 if (app == mHomeProcess) { 13214 mHomeProcess = null; 13215 } 13216 if (app == mPreviousProcess) { 13217 mPreviousProcess = null; 13218 } 13219 13220 if (restart && !app.isolated) { 13221 // We have components that still need to be running in the 13222 // process, so re-launch it. 13223 mProcessNames.put(app.processName, app.uid, app); 13224 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13225 } else if (app.pid > 0 && app.pid != MY_PID) { 13226 // Goodbye! 13227 boolean removed; 13228 synchronized (mPidsSelfLocked) { 13229 mPidsSelfLocked.remove(app.pid); 13230 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13231 } 13232 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 13233 app.processName, app.info.uid); 13234 if (app.isolated) { 13235 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13236 } 13237 app.setPid(0); 13238 } 13239 } 13240 13241 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13242 // Look through the content providers we are waiting to have launched, 13243 // and if any run in this process then either schedule a restart of 13244 // the process or kill the client waiting for it if this process has 13245 // gone bad. 13246 int NL = mLaunchingProviders.size(); 13247 boolean restart = false; 13248 for (int i=0; i<NL; i++) { 13249 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13250 if (cpr.launchingApp == app) { 13251 if (!alwaysBad && !app.bad) { 13252 restart = true; 13253 } else { 13254 removeDyingProviderLocked(app, cpr, true); 13255 // cpr should have been removed from mLaunchingProviders 13256 NL = mLaunchingProviders.size(); 13257 i--; 13258 } 13259 } 13260 } 13261 return restart; 13262 } 13263 13264 // ========================================================= 13265 // SERVICES 13266 // ========================================================= 13267 13268 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13269 int flags) { 13270 enforceNotIsolatedCaller("getServices"); 13271 synchronized (this) { 13272 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13273 } 13274 } 13275 13276 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13277 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13278 synchronized (this) { 13279 return mServices.getRunningServiceControlPanelLocked(name); 13280 } 13281 } 13282 13283 public ComponentName startService(IApplicationThread caller, Intent service, 13284 String resolvedType, int userId) { 13285 enforceNotIsolatedCaller("startService"); 13286 // Refuse possible leaked file descriptors 13287 if (service != null && service.hasFileDescriptors() == true) { 13288 throw new IllegalArgumentException("File descriptors passed in Intent"); 13289 } 13290 13291 if (DEBUG_SERVICE) 13292 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13293 synchronized(this) { 13294 final int callingPid = Binder.getCallingPid(); 13295 final int callingUid = Binder.getCallingUid(); 13296 final long origId = Binder.clearCallingIdentity(); 13297 ComponentName res = mServices.startServiceLocked(caller, service, 13298 resolvedType, callingPid, callingUid, userId); 13299 Binder.restoreCallingIdentity(origId); 13300 return res; 13301 } 13302 } 13303 13304 ComponentName startServiceInPackage(int uid, 13305 Intent service, String resolvedType, int userId) { 13306 synchronized(this) { 13307 if (DEBUG_SERVICE) 13308 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13309 final long origId = Binder.clearCallingIdentity(); 13310 ComponentName res = mServices.startServiceLocked(null, service, 13311 resolvedType, -1, uid, userId); 13312 Binder.restoreCallingIdentity(origId); 13313 return res; 13314 } 13315 } 13316 13317 public int stopService(IApplicationThread caller, Intent service, 13318 String resolvedType, int userId) { 13319 enforceNotIsolatedCaller("stopService"); 13320 // Refuse possible leaked file descriptors 13321 if (service != null && service.hasFileDescriptors() == true) { 13322 throw new IllegalArgumentException("File descriptors passed in Intent"); 13323 } 13324 13325 synchronized(this) { 13326 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13327 } 13328 } 13329 13330 public IBinder peekService(Intent service, String resolvedType) { 13331 enforceNotIsolatedCaller("peekService"); 13332 // Refuse possible leaked file descriptors 13333 if (service != null && service.hasFileDescriptors() == true) { 13334 throw new IllegalArgumentException("File descriptors passed in Intent"); 13335 } 13336 synchronized(this) { 13337 return mServices.peekServiceLocked(service, resolvedType); 13338 } 13339 } 13340 13341 public boolean stopServiceToken(ComponentName className, IBinder token, 13342 int startId) { 13343 synchronized(this) { 13344 return mServices.stopServiceTokenLocked(className, token, startId); 13345 } 13346 } 13347 13348 public void setServiceForeground(ComponentName className, IBinder token, 13349 int id, Notification notification, boolean removeNotification) { 13350 synchronized(this) { 13351 mServices.setServiceForegroundLocked(className, token, id, notification, 13352 removeNotification); 13353 } 13354 } 13355 13356 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13357 boolean requireFull, String name, String callerPackage) { 13358 final int callingUserId = UserHandle.getUserId(callingUid); 13359 if (callingUserId != userId) { 13360 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13361 if ((requireFull || checkComponentPermission( 13362 android.Manifest.permission.INTERACT_ACROSS_USERS, 13363 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13364 && checkComponentPermission(INTERACT_ACROSS_USERS_FULL, 13365 callingPid, callingUid, -1, true) 13366 != PackageManager.PERMISSION_GRANTED) { 13367 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13368 // In this case, they would like to just execute as their 13369 // owner user instead of failing. 13370 userId = callingUserId; 13371 } else { 13372 StringBuilder builder = new StringBuilder(128); 13373 builder.append("Permission Denial: "); 13374 builder.append(name); 13375 if (callerPackage != null) { 13376 builder.append(" from "); 13377 builder.append(callerPackage); 13378 } 13379 builder.append(" asks to run as user "); 13380 builder.append(userId); 13381 builder.append(" but is calling from user "); 13382 builder.append(UserHandle.getUserId(callingUid)); 13383 builder.append("; this requires "); 13384 builder.append(INTERACT_ACROSS_USERS_FULL); 13385 if (!requireFull) { 13386 builder.append(" or "); 13387 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13388 } 13389 String msg = builder.toString(); 13390 Slog.w(TAG, msg); 13391 throw new SecurityException(msg); 13392 } 13393 } 13394 } 13395 if (userId == UserHandle.USER_CURRENT 13396 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13397 // Note that we may be accessing this outside of a lock... 13398 // shouldn't be a big deal, if this is being called outside 13399 // of a locked context there is intrinsically a race with 13400 // the value the caller will receive and someone else changing it. 13401 userId = mCurrentUserId; 13402 } 13403 if (!allowAll && userId < 0) { 13404 throw new IllegalArgumentException( 13405 "Call does not support special user #" + userId); 13406 } 13407 } 13408 return userId; 13409 } 13410 13411 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13412 String className, int flags) { 13413 boolean result = false; 13414 // For apps that don't have pre-defined UIDs, check for permission 13415 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13416 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13417 if (ActivityManager.checkUidPermission( 13418 android.Manifest.permission.INTERACT_ACROSS_USERS, 13419 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13420 ComponentName comp = new ComponentName(aInfo.packageName, className); 13421 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13422 + " requests FLAG_SINGLE_USER, but app does not hold " 13423 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13424 Slog.w(TAG, msg); 13425 throw new SecurityException(msg); 13426 } 13427 // Permission passed 13428 result = true; 13429 } 13430 } else if ("system".equals(componentProcessName)) { 13431 result = true; 13432 } else { 13433 // App with pre-defined UID, check if it's a persistent app 13434 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13435 } 13436 if (DEBUG_MU) { 13437 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13438 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13439 } 13440 return result; 13441 } 13442 13443 /** 13444 * Checks to see if the caller is in the same app as the singleton 13445 * component, or the component is in a special app. It allows special apps 13446 * to export singleton components but prevents exporting singleton 13447 * components for regular apps. 13448 */ 13449 boolean isValidSingletonCall(int callingUid, int componentUid) { 13450 int componentAppId = UserHandle.getAppId(componentUid); 13451 return UserHandle.isSameApp(callingUid, componentUid) 13452 || componentAppId == Process.SYSTEM_UID 13453 || componentAppId == Process.PHONE_UID 13454 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13455 == PackageManager.PERMISSION_GRANTED; 13456 } 13457 13458 public int bindService(IApplicationThread caller, IBinder token, 13459 Intent service, String resolvedType, 13460 IServiceConnection connection, int flags, int userId) { 13461 enforceNotIsolatedCaller("bindService"); 13462 // Refuse possible leaked file descriptors 13463 if (service != null && service.hasFileDescriptors() == true) { 13464 throw new IllegalArgumentException("File descriptors passed in Intent"); 13465 } 13466 13467 synchronized(this) { 13468 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13469 connection, flags, userId); 13470 } 13471 } 13472 13473 public boolean unbindService(IServiceConnection connection) { 13474 synchronized (this) { 13475 return mServices.unbindServiceLocked(connection); 13476 } 13477 } 13478 13479 public void publishService(IBinder token, Intent intent, IBinder service) { 13480 // Refuse possible leaked file descriptors 13481 if (intent != null && intent.hasFileDescriptors() == true) { 13482 throw new IllegalArgumentException("File descriptors passed in Intent"); 13483 } 13484 13485 synchronized(this) { 13486 if (!(token instanceof ServiceRecord)) { 13487 throw new IllegalArgumentException("Invalid service token"); 13488 } 13489 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13490 } 13491 } 13492 13493 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13494 // Refuse possible leaked file descriptors 13495 if (intent != null && intent.hasFileDescriptors() == true) { 13496 throw new IllegalArgumentException("File descriptors passed in Intent"); 13497 } 13498 13499 synchronized(this) { 13500 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13501 } 13502 } 13503 13504 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13505 synchronized(this) { 13506 if (!(token instanceof ServiceRecord)) { 13507 throw new IllegalArgumentException("Invalid service token"); 13508 } 13509 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13510 } 13511 } 13512 13513 // ========================================================= 13514 // BACKUP AND RESTORE 13515 // ========================================================= 13516 13517 // Cause the target app to be launched if necessary and its backup agent 13518 // instantiated. The backup agent will invoke backupAgentCreated() on the 13519 // activity manager to announce its creation. 13520 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13521 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13522 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13523 13524 synchronized(this) { 13525 // !!! TODO: currently no check here that we're already bound 13526 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13527 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13528 synchronized (stats) { 13529 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13530 } 13531 13532 // Backup agent is now in use, its package can't be stopped. 13533 try { 13534 AppGlobals.getPackageManager().setPackageStoppedState( 13535 app.packageName, false, UserHandle.getUserId(app.uid)); 13536 } catch (RemoteException e) { 13537 } catch (IllegalArgumentException e) { 13538 Slog.w(TAG, "Failed trying to unstop package " 13539 + app.packageName + ": " + e); 13540 } 13541 13542 BackupRecord r = new BackupRecord(ss, app, backupMode); 13543 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13544 ? new ComponentName(app.packageName, app.backupAgentName) 13545 : new ComponentName("android", "FullBackupAgent"); 13546 // startProcessLocked() returns existing proc's record if it's already running 13547 ProcessRecord proc = startProcessLocked(app.processName, app, 13548 false, 0, "backup", hostingName, false, false, false); 13549 if (proc == null) { 13550 Slog.e(TAG, "Unable to start backup agent process " + r); 13551 return false; 13552 } 13553 13554 r.app = proc; 13555 mBackupTarget = r; 13556 mBackupAppName = app.packageName; 13557 13558 // Try not to kill the process during backup 13559 updateOomAdjLocked(proc); 13560 13561 // If the process is already attached, schedule the creation of the backup agent now. 13562 // If it is not yet live, this will be done when it attaches to the framework. 13563 if (proc.thread != null) { 13564 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13565 try { 13566 proc.thread.scheduleCreateBackupAgent(app, 13567 compatibilityInfoForPackageLocked(app), backupMode); 13568 } catch (RemoteException e) { 13569 // Will time out on the backup manager side 13570 } 13571 } else { 13572 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13573 } 13574 // Invariants: at this point, the target app process exists and the application 13575 // is either already running or in the process of coming up. mBackupTarget and 13576 // mBackupAppName describe the app, so that when it binds back to the AM we 13577 // know that it's scheduled for a backup-agent operation. 13578 } 13579 13580 return true; 13581 } 13582 13583 @Override 13584 public void clearPendingBackup() { 13585 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13586 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13587 13588 synchronized (this) { 13589 mBackupTarget = null; 13590 mBackupAppName = null; 13591 } 13592 } 13593 13594 // A backup agent has just come up 13595 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13596 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13597 + " = " + agent); 13598 13599 synchronized(this) { 13600 if (!agentPackageName.equals(mBackupAppName)) { 13601 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13602 return; 13603 } 13604 } 13605 13606 long oldIdent = Binder.clearCallingIdentity(); 13607 try { 13608 IBackupManager bm = IBackupManager.Stub.asInterface( 13609 ServiceManager.getService(Context.BACKUP_SERVICE)); 13610 bm.agentConnected(agentPackageName, agent); 13611 } catch (RemoteException e) { 13612 // can't happen; the backup manager service is local 13613 } catch (Exception e) { 13614 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13615 e.printStackTrace(); 13616 } finally { 13617 Binder.restoreCallingIdentity(oldIdent); 13618 } 13619 } 13620 13621 // done with this agent 13622 public void unbindBackupAgent(ApplicationInfo appInfo) { 13623 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13624 if (appInfo == null) { 13625 Slog.w(TAG, "unbind backup agent for null app"); 13626 return; 13627 } 13628 13629 synchronized(this) { 13630 try { 13631 if (mBackupAppName == null) { 13632 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13633 return; 13634 } 13635 13636 if (!mBackupAppName.equals(appInfo.packageName)) { 13637 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13638 return; 13639 } 13640 13641 // Not backing this app up any more; reset its OOM adjustment 13642 final ProcessRecord proc = mBackupTarget.app; 13643 updateOomAdjLocked(proc); 13644 13645 // If the app crashed during backup, 'thread' will be null here 13646 if (proc.thread != null) { 13647 try { 13648 proc.thread.scheduleDestroyBackupAgent(appInfo, 13649 compatibilityInfoForPackageLocked(appInfo)); 13650 } catch (Exception e) { 13651 Slog.e(TAG, "Exception when unbinding backup agent:"); 13652 e.printStackTrace(); 13653 } 13654 } 13655 } finally { 13656 mBackupTarget = null; 13657 mBackupAppName = null; 13658 } 13659 } 13660 } 13661 // ========================================================= 13662 // BROADCASTS 13663 // ========================================================= 13664 13665 private final List getStickiesLocked(String action, IntentFilter filter, 13666 List cur, int userId) { 13667 final ContentResolver resolver = mContext.getContentResolver(); 13668 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13669 if (stickies == null) { 13670 return cur; 13671 } 13672 final ArrayList<Intent> list = stickies.get(action); 13673 if (list == null) { 13674 return cur; 13675 } 13676 int N = list.size(); 13677 for (int i=0; i<N; i++) { 13678 Intent intent = list.get(i); 13679 if (filter.match(resolver, intent, true, TAG) >= 0) { 13680 if (cur == null) { 13681 cur = new ArrayList<Intent>(); 13682 } 13683 cur.add(intent); 13684 } 13685 } 13686 return cur; 13687 } 13688 13689 boolean isPendingBroadcastProcessLocked(int pid) { 13690 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13691 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13692 } 13693 13694 void skipPendingBroadcastLocked(int pid) { 13695 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13696 for (BroadcastQueue queue : mBroadcastQueues) { 13697 queue.skipPendingBroadcastLocked(pid); 13698 } 13699 } 13700 13701 // The app just attached; send any pending broadcasts that it should receive 13702 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13703 boolean didSomething = false; 13704 for (BroadcastQueue queue : mBroadcastQueues) { 13705 didSomething |= queue.sendPendingBroadcastsLocked(app); 13706 } 13707 return didSomething; 13708 } 13709 13710 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13711 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13712 enforceNotIsolatedCaller("registerReceiver"); 13713 int callingUid; 13714 int callingPid; 13715 synchronized(this) { 13716 ProcessRecord callerApp = null; 13717 if (caller != null) { 13718 callerApp = getRecordForAppLocked(caller); 13719 if (callerApp == null) { 13720 throw new SecurityException( 13721 "Unable to find app for caller " + caller 13722 + " (pid=" + Binder.getCallingPid() 13723 + ") when registering receiver " + receiver); 13724 } 13725 if (callerApp.info.uid != Process.SYSTEM_UID && 13726 !callerApp.pkgList.containsKey(callerPackage) && 13727 !"android".equals(callerPackage)) { 13728 throw new SecurityException("Given caller package " + callerPackage 13729 + " is not running in process " + callerApp); 13730 } 13731 callingUid = callerApp.info.uid; 13732 callingPid = callerApp.pid; 13733 } else { 13734 callerPackage = null; 13735 callingUid = Binder.getCallingUid(); 13736 callingPid = Binder.getCallingPid(); 13737 } 13738 13739 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13740 true, true, "registerReceiver", callerPackage); 13741 13742 List allSticky = null; 13743 13744 // Look for any matching sticky broadcasts... 13745 Iterator actions = filter.actionsIterator(); 13746 if (actions != null) { 13747 while (actions.hasNext()) { 13748 String action = (String)actions.next(); 13749 allSticky = getStickiesLocked(action, filter, allSticky, 13750 UserHandle.USER_ALL); 13751 allSticky = getStickiesLocked(action, filter, allSticky, 13752 UserHandle.getUserId(callingUid)); 13753 } 13754 } else { 13755 allSticky = getStickiesLocked(null, filter, allSticky, 13756 UserHandle.USER_ALL); 13757 allSticky = getStickiesLocked(null, filter, allSticky, 13758 UserHandle.getUserId(callingUid)); 13759 } 13760 13761 // The first sticky in the list is returned directly back to 13762 // the client. 13763 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13764 13765 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13766 + ": " + sticky); 13767 13768 if (receiver == null) { 13769 return sticky; 13770 } 13771 13772 ReceiverList rl 13773 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13774 if (rl == null) { 13775 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13776 userId, receiver); 13777 if (rl.app != null) { 13778 rl.app.receivers.add(rl); 13779 } else { 13780 try { 13781 receiver.asBinder().linkToDeath(rl, 0); 13782 } catch (RemoteException e) { 13783 return sticky; 13784 } 13785 rl.linkedToDeath = true; 13786 } 13787 mRegisteredReceivers.put(receiver.asBinder(), rl); 13788 } else if (rl.uid != callingUid) { 13789 throw new IllegalArgumentException( 13790 "Receiver requested to register for uid " + callingUid 13791 + " was previously registered for uid " + rl.uid); 13792 } else if (rl.pid != callingPid) { 13793 throw new IllegalArgumentException( 13794 "Receiver requested to register for pid " + callingPid 13795 + " was previously registered for pid " + rl.pid); 13796 } else if (rl.userId != userId) { 13797 throw new IllegalArgumentException( 13798 "Receiver requested to register for user " + userId 13799 + " was previously registered for user " + rl.userId); 13800 } 13801 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13802 permission, callingUid, userId); 13803 rl.add(bf); 13804 if (!bf.debugCheck()) { 13805 Slog.w(TAG, "==> For Dynamic broadast"); 13806 } 13807 mReceiverResolver.addFilter(bf); 13808 13809 // Enqueue broadcasts for all existing stickies that match 13810 // this filter. 13811 if (allSticky != null) { 13812 ArrayList receivers = new ArrayList(); 13813 receivers.add(bf); 13814 13815 int N = allSticky.size(); 13816 for (int i=0; i<N; i++) { 13817 Intent intent = (Intent)allSticky.get(i); 13818 BroadcastQueue queue = broadcastQueueForIntent(intent); 13819 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13820 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13821 null, null, false, true, true, -1); 13822 queue.enqueueParallelBroadcastLocked(r); 13823 queue.scheduleBroadcastsLocked(); 13824 } 13825 } 13826 13827 return sticky; 13828 } 13829 } 13830 13831 public void unregisterReceiver(IIntentReceiver receiver) { 13832 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13833 13834 final long origId = Binder.clearCallingIdentity(); 13835 try { 13836 boolean doTrim = false; 13837 13838 synchronized(this) { 13839 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13840 if (rl != null) { 13841 if (rl.curBroadcast != null) { 13842 BroadcastRecord r = rl.curBroadcast; 13843 final boolean doNext = finishReceiverLocked( 13844 receiver.asBinder(), r.resultCode, r.resultData, 13845 r.resultExtras, r.resultAbort); 13846 if (doNext) { 13847 doTrim = true; 13848 r.queue.processNextBroadcast(false); 13849 } 13850 } 13851 13852 if (rl.app != null) { 13853 rl.app.receivers.remove(rl); 13854 } 13855 removeReceiverLocked(rl); 13856 if (rl.linkedToDeath) { 13857 rl.linkedToDeath = false; 13858 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13859 } 13860 } 13861 } 13862 13863 // If we actually concluded any broadcasts, we might now be able 13864 // to trim the recipients' apps from our working set 13865 if (doTrim) { 13866 trimApplications(); 13867 return; 13868 } 13869 13870 } finally { 13871 Binder.restoreCallingIdentity(origId); 13872 } 13873 } 13874 13875 void removeReceiverLocked(ReceiverList rl) { 13876 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13877 int N = rl.size(); 13878 for (int i=0; i<N; i++) { 13879 mReceiverResolver.removeFilter(rl.get(i)); 13880 } 13881 } 13882 13883 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13884 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13885 ProcessRecord r = mLruProcesses.get(i); 13886 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13887 try { 13888 r.thread.dispatchPackageBroadcast(cmd, packages); 13889 } catch (RemoteException ex) { 13890 } 13891 } 13892 } 13893 } 13894 13895 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13896 int[] users) { 13897 List<ResolveInfo> receivers = null; 13898 try { 13899 HashSet<ComponentName> singleUserReceivers = null; 13900 boolean scannedFirstReceivers = false; 13901 for (int user : users) { 13902 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13903 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13904 if (user != 0 && newReceivers != null) { 13905 // If this is not the primary user, we need to check for 13906 // any receivers that should be filtered out. 13907 for (int i=0; i<newReceivers.size(); i++) { 13908 ResolveInfo ri = newReceivers.get(i); 13909 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13910 newReceivers.remove(i); 13911 i--; 13912 } 13913 } 13914 } 13915 if (newReceivers != null && newReceivers.size() == 0) { 13916 newReceivers = null; 13917 } 13918 if (receivers == null) { 13919 receivers = newReceivers; 13920 } else if (newReceivers != null) { 13921 // We need to concatenate the additional receivers 13922 // found with what we have do far. This would be easy, 13923 // but we also need to de-dup any receivers that are 13924 // singleUser. 13925 if (!scannedFirstReceivers) { 13926 // Collect any single user receivers we had already retrieved. 13927 scannedFirstReceivers = true; 13928 for (int i=0; i<receivers.size(); i++) { 13929 ResolveInfo ri = receivers.get(i); 13930 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13931 ComponentName cn = new ComponentName( 13932 ri.activityInfo.packageName, ri.activityInfo.name); 13933 if (singleUserReceivers == null) { 13934 singleUserReceivers = new HashSet<ComponentName>(); 13935 } 13936 singleUserReceivers.add(cn); 13937 } 13938 } 13939 } 13940 // Add the new results to the existing results, tracking 13941 // and de-dupping single user receivers. 13942 for (int i=0; i<newReceivers.size(); i++) { 13943 ResolveInfo ri = newReceivers.get(i); 13944 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13945 ComponentName cn = new ComponentName( 13946 ri.activityInfo.packageName, ri.activityInfo.name); 13947 if (singleUserReceivers == null) { 13948 singleUserReceivers = new HashSet<ComponentName>(); 13949 } 13950 if (!singleUserReceivers.contains(cn)) { 13951 singleUserReceivers.add(cn); 13952 receivers.add(ri); 13953 } 13954 } else { 13955 receivers.add(ri); 13956 } 13957 } 13958 } 13959 } 13960 } catch (RemoteException ex) { 13961 // pm is in same process, this will never happen. 13962 } 13963 return receivers; 13964 } 13965 13966 private final int broadcastIntentLocked(ProcessRecord callerApp, 13967 String callerPackage, Intent intent, String resolvedType, 13968 IIntentReceiver resultTo, int resultCode, String resultData, 13969 Bundle map, String requiredPermission, int appOp, 13970 boolean ordered, boolean sticky, int callingPid, int callingUid, 13971 int userId) { 13972 intent = new Intent(intent); 13973 13974 // By default broadcasts do not go to stopped apps. 13975 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13976 13977 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13978 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13979 + " ordered=" + ordered + " userid=" + userId); 13980 if ((resultTo != null) && !ordered) { 13981 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13982 } 13983 13984 userId = handleIncomingUser(callingPid, callingUid, userId, 13985 true, false, "broadcast", callerPackage); 13986 13987 // Make sure that the user who is receiving this broadcast is started. 13988 // If not, we will just skip it. 13989 13990 13991 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13992 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13993 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13994 Slog.w(TAG, "Skipping broadcast of " + intent 13995 + ": user " + userId + " is stopped"); 13996 return ActivityManager.BROADCAST_SUCCESS; 13997 } 13998 } 13999 14000 /* 14001 * Prevent non-system code (defined here to be non-persistent 14002 * processes) from sending protected broadcasts. 14003 */ 14004 int callingAppId = UserHandle.getAppId(callingUid); 14005 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14006 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14007 || callingAppId == Process.NFC_UID || callingUid == 0) { 14008 // Always okay. 14009 } else if (callerApp == null || !callerApp.persistent) { 14010 try { 14011 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14012 intent.getAction())) { 14013 String msg = "Permission Denial: not allowed to send broadcast " 14014 + intent.getAction() + " from pid=" 14015 + callingPid + ", uid=" + callingUid; 14016 Slog.w(TAG, msg); 14017 throw new SecurityException(msg); 14018 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14019 // Special case for compatibility: we don't want apps to send this, 14020 // but historically it has not been protected and apps may be using it 14021 // to poke their own app widget. So, instead of making it protected, 14022 // just limit it to the caller. 14023 if (callerApp == null) { 14024 String msg = "Permission Denial: not allowed to send broadcast " 14025 + intent.getAction() + " from unknown caller."; 14026 Slog.w(TAG, msg); 14027 throw new SecurityException(msg); 14028 } else if (intent.getComponent() != null) { 14029 // They are good enough to send to an explicit component... verify 14030 // it is being sent to the calling app. 14031 if (!intent.getComponent().getPackageName().equals( 14032 callerApp.info.packageName)) { 14033 String msg = "Permission Denial: not allowed to send broadcast " 14034 + intent.getAction() + " to " 14035 + intent.getComponent().getPackageName() + " from " 14036 + callerApp.info.packageName; 14037 Slog.w(TAG, msg); 14038 throw new SecurityException(msg); 14039 } 14040 } else { 14041 // Limit broadcast to their own package. 14042 intent.setPackage(callerApp.info.packageName); 14043 } 14044 } 14045 } catch (RemoteException e) { 14046 Slog.w(TAG, "Remote exception", e); 14047 return ActivityManager.BROADCAST_SUCCESS; 14048 } 14049 } 14050 14051 // Handle special intents: if this broadcast is from the package 14052 // manager about a package being removed, we need to remove all of 14053 // its activities from the history stack. 14054 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14055 intent.getAction()); 14056 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14057 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14058 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14059 || uidRemoved) { 14060 if (checkComponentPermission( 14061 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14062 callingPid, callingUid, -1, true) 14063 == PackageManager.PERMISSION_GRANTED) { 14064 if (uidRemoved) { 14065 final Bundle intentExtras = intent.getExtras(); 14066 final int uid = intentExtras != null 14067 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14068 if (uid >= 0) { 14069 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14070 synchronized (bs) { 14071 bs.removeUidStatsLocked(uid); 14072 } 14073 mAppOpsService.uidRemoved(uid); 14074 } 14075 } else { 14076 // If resources are unavailable just force stop all 14077 // those packages and flush the attribute cache as well. 14078 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14079 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14080 if (list != null && (list.length > 0)) { 14081 for (String pkg : list) { 14082 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14083 "storage unmount"); 14084 } 14085 sendPackageBroadcastLocked( 14086 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14087 } 14088 } else { 14089 Uri data = intent.getData(); 14090 String ssp; 14091 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14092 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14093 intent.getAction()); 14094 boolean fullUninstall = removed && 14095 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14096 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14097 forceStopPackageLocked(ssp, UserHandle.getAppId( 14098 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14099 false, fullUninstall, userId, 14100 removed ? "pkg removed" : "pkg changed"); 14101 } 14102 if (removed) { 14103 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14104 new String[] {ssp}, userId); 14105 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14106 mAppOpsService.packageRemoved( 14107 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14108 14109 // Remove all permissions granted from/to this package 14110 removeUriPermissionsForPackageLocked(ssp, userId, true); 14111 } 14112 } 14113 } 14114 } 14115 } 14116 } else { 14117 String msg = "Permission Denial: " + intent.getAction() 14118 + " broadcast from " + callerPackage + " (pid=" + callingPid 14119 + ", uid=" + callingUid + ")" 14120 + " requires " 14121 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14122 Slog.w(TAG, msg); 14123 throw new SecurityException(msg); 14124 } 14125 14126 // Special case for adding a package: by default turn on compatibility 14127 // mode. 14128 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14129 Uri data = intent.getData(); 14130 String ssp; 14131 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14132 mCompatModePackages.handlePackageAddedLocked(ssp, 14133 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14134 } 14135 } 14136 14137 /* 14138 * If this is the time zone changed action, queue up a message that will reset the timezone 14139 * of all currently running processes. This message will get queued up before the broadcast 14140 * happens. 14141 */ 14142 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14143 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14144 } 14145 14146 /* 14147 * If the user set the time, let all running processes know. 14148 */ 14149 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14150 final int is24Hour = intent.getBooleanExtra( 14151 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14152 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14153 } 14154 14155 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14156 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14157 } 14158 14159 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14160 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14161 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14162 } 14163 14164 // Add to the sticky list if requested. 14165 if (sticky) { 14166 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14167 callingPid, callingUid) 14168 != PackageManager.PERMISSION_GRANTED) { 14169 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14170 + callingPid + ", uid=" + callingUid 14171 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14172 Slog.w(TAG, msg); 14173 throw new SecurityException(msg); 14174 } 14175 if (requiredPermission != null) { 14176 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14177 + " and enforce permission " + requiredPermission); 14178 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14179 } 14180 if (intent.getComponent() != null) { 14181 throw new SecurityException( 14182 "Sticky broadcasts can't target a specific component"); 14183 } 14184 // We use userId directly here, since the "all" target is maintained 14185 // as a separate set of sticky broadcasts. 14186 if (userId != UserHandle.USER_ALL) { 14187 // But first, if this is not a broadcast to all users, then 14188 // make sure it doesn't conflict with an existing broadcast to 14189 // all users. 14190 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14191 UserHandle.USER_ALL); 14192 if (stickies != null) { 14193 ArrayList<Intent> list = stickies.get(intent.getAction()); 14194 if (list != null) { 14195 int N = list.size(); 14196 int i; 14197 for (i=0; i<N; i++) { 14198 if (intent.filterEquals(list.get(i))) { 14199 throw new IllegalArgumentException( 14200 "Sticky broadcast " + intent + " for user " 14201 + userId + " conflicts with existing global broadcast"); 14202 } 14203 } 14204 } 14205 } 14206 } 14207 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14208 if (stickies == null) { 14209 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14210 mStickyBroadcasts.put(userId, stickies); 14211 } 14212 ArrayList<Intent> list = stickies.get(intent.getAction()); 14213 if (list == null) { 14214 list = new ArrayList<Intent>(); 14215 stickies.put(intent.getAction(), list); 14216 } 14217 int N = list.size(); 14218 int i; 14219 for (i=0; i<N; i++) { 14220 if (intent.filterEquals(list.get(i))) { 14221 // This sticky already exists, replace it. 14222 list.set(i, new Intent(intent)); 14223 break; 14224 } 14225 } 14226 if (i >= N) { 14227 list.add(new Intent(intent)); 14228 } 14229 } 14230 14231 int[] users; 14232 if (userId == UserHandle.USER_ALL) { 14233 // Caller wants broadcast to go to all started users. 14234 users = mStartedUserArray; 14235 } else { 14236 // Caller wants broadcast to go to one specific user. 14237 users = new int[] {userId}; 14238 } 14239 14240 // Figure out who all will receive this broadcast. 14241 List receivers = null; 14242 List<BroadcastFilter> registeredReceivers = null; 14243 // Need to resolve the intent to interested receivers... 14244 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14245 == 0) { 14246 receivers = collectReceiverComponents(intent, resolvedType, users); 14247 } 14248 if (intent.getComponent() == null) { 14249 registeredReceivers = mReceiverResolver.queryIntent(intent, 14250 resolvedType, false, userId); 14251 } 14252 14253 final boolean replacePending = 14254 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14255 14256 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14257 + " replacePending=" + replacePending); 14258 14259 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14260 if (!ordered && NR > 0) { 14261 // If we are not serializing this broadcast, then send the 14262 // registered receivers separately so they don't wait for the 14263 // components to be launched. 14264 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14265 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14266 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14267 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14268 ordered, sticky, false, userId); 14269 if (DEBUG_BROADCAST) Slog.v( 14270 TAG, "Enqueueing parallel broadcast " + r); 14271 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14272 if (!replaced) { 14273 queue.enqueueParallelBroadcastLocked(r); 14274 queue.scheduleBroadcastsLocked(); 14275 } 14276 registeredReceivers = null; 14277 NR = 0; 14278 } 14279 14280 // Merge into one list. 14281 int ir = 0; 14282 if (receivers != null) { 14283 // A special case for PACKAGE_ADDED: do not allow the package 14284 // being added to see this broadcast. This prevents them from 14285 // using this as a back door to get run as soon as they are 14286 // installed. Maybe in the future we want to have a special install 14287 // broadcast or such for apps, but we'd like to deliberately make 14288 // this decision. 14289 String skipPackages[] = null; 14290 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14291 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14292 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14293 Uri data = intent.getData(); 14294 if (data != null) { 14295 String pkgName = data.getSchemeSpecificPart(); 14296 if (pkgName != null) { 14297 skipPackages = new String[] { pkgName }; 14298 } 14299 } 14300 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14301 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14302 } 14303 if (skipPackages != null && (skipPackages.length > 0)) { 14304 for (String skipPackage : skipPackages) { 14305 if (skipPackage != null) { 14306 int NT = receivers.size(); 14307 for (int it=0; it<NT; it++) { 14308 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14309 if (curt.activityInfo.packageName.equals(skipPackage)) { 14310 receivers.remove(it); 14311 it--; 14312 NT--; 14313 } 14314 } 14315 } 14316 } 14317 } 14318 14319 int NT = receivers != null ? receivers.size() : 0; 14320 int it = 0; 14321 ResolveInfo curt = null; 14322 BroadcastFilter curr = null; 14323 while (it < NT && ir < NR) { 14324 if (curt == null) { 14325 curt = (ResolveInfo)receivers.get(it); 14326 } 14327 if (curr == null) { 14328 curr = registeredReceivers.get(ir); 14329 } 14330 if (curr.getPriority() >= curt.priority) { 14331 // Insert this broadcast record into the final list. 14332 receivers.add(it, curr); 14333 ir++; 14334 curr = null; 14335 it++; 14336 NT++; 14337 } else { 14338 // Skip to the next ResolveInfo in the final list. 14339 it++; 14340 curt = null; 14341 } 14342 } 14343 } 14344 while (ir < NR) { 14345 if (receivers == null) { 14346 receivers = new ArrayList(); 14347 } 14348 receivers.add(registeredReceivers.get(ir)); 14349 ir++; 14350 } 14351 14352 if ((receivers != null && receivers.size() > 0) 14353 || resultTo != null) { 14354 BroadcastQueue queue = broadcastQueueForIntent(intent); 14355 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14356 callerPackage, callingPid, callingUid, resolvedType, 14357 requiredPermission, appOp, receivers, resultTo, resultCode, 14358 resultData, map, ordered, sticky, false, userId); 14359 if (DEBUG_BROADCAST) Slog.v( 14360 TAG, "Enqueueing ordered broadcast " + r 14361 + ": prev had " + queue.mOrderedBroadcasts.size()); 14362 if (DEBUG_BROADCAST) { 14363 int seq = r.intent.getIntExtra("seq", -1); 14364 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14365 } 14366 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14367 if (!replaced) { 14368 queue.enqueueOrderedBroadcastLocked(r); 14369 queue.scheduleBroadcastsLocked(); 14370 } 14371 } 14372 14373 return ActivityManager.BROADCAST_SUCCESS; 14374 } 14375 14376 final Intent verifyBroadcastLocked(Intent intent) { 14377 // Refuse possible leaked file descriptors 14378 if (intent != null && intent.hasFileDescriptors() == true) { 14379 throw new IllegalArgumentException("File descriptors passed in Intent"); 14380 } 14381 14382 int flags = intent.getFlags(); 14383 14384 if (!mProcessesReady) { 14385 // if the caller really truly claims to know what they're doing, go 14386 // ahead and allow the broadcast without launching any receivers 14387 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14388 intent = new Intent(intent); 14389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14390 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14391 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14392 + " before boot completion"); 14393 throw new IllegalStateException("Cannot broadcast before boot completed"); 14394 } 14395 } 14396 14397 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14398 throw new IllegalArgumentException( 14399 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14400 } 14401 14402 return intent; 14403 } 14404 14405 public final int broadcastIntent(IApplicationThread caller, 14406 Intent intent, String resolvedType, IIntentReceiver resultTo, 14407 int resultCode, String resultData, Bundle map, 14408 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14409 enforceNotIsolatedCaller("broadcastIntent"); 14410 synchronized(this) { 14411 intent = verifyBroadcastLocked(intent); 14412 14413 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14414 final int callingPid = Binder.getCallingPid(); 14415 final int callingUid = Binder.getCallingUid(); 14416 final long origId = Binder.clearCallingIdentity(); 14417 int res = broadcastIntentLocked(callerApp, 14418 callerApp != null ? callerApp.info.packageName : null, 14419 intent, resolvedType, resultTo, 14420 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14421 callingPid, callingUid, userId); 14422 Binder.restoreCallingIdentity(origId); 14423 return res; 14424 } 14425 } 14426 14427 int broadcastIntentInPackage(String packageName, int uid, 14428 Intent intent, String resolvedType, IIntentReceiver resultTo, 14429 int resultCode, String resultData, Bundle map, 14430 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14431 synchronized(this) { 14432 intent = verifyBroadcastLocked(intent); 14433 14434 final long origId = Binder.clearCallingIdentity(); 14435 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14436 resultTo, resultCode, resultData, map, requiredPermission, 14437 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14438 Binder.restoreCallingIdentity(origId); 14439 return res; 14440 } 14441 } 14442 14443 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14444 // Refuse possible leaked file descriptors 14445 if (intent != null && intent.hasFileDescriptors() == true) { 14446 throw new IllegalArgumentException("File descriptors passed in Intent"); 14447 } 14448 14449 userId = handleIncomingUser(Binder.getCallingPid(), 14450 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14451 14452 synchronized(this) { 14453 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14454 != PackageManager.PERMISSION_GRANTED) { 14455 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14456 + Binder.getCallingPid() 14457 + ", uid=" + Binder.getCallingUid() 14458 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14459 Slog.w(TAG, msg); 14460 throw new SecurityException(msg); 14461 } 14462 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14463 if (stickies != null) { 14464 ArrayList<Intent> list = stickies.get(intent.getAction()); 14465 if (list != null) { 14466 int N = list.size(); 14467 int i; 14468 for (i=0; i<N; i++) { 14469 if (intent.filterEquals(list.get(i))) { 14470 list.remove(i); 14471 break; 14472 } 14473 } 14474 if (list.size() <= 0) { 14475 stickies.remove(intent.getAction()); 14476 } 14477 } 14478 if (stickies.size() <= 0) { 14479 mStickyBroadcasts.remove(userId); 14480 } 14481 } 14482 } 14483 } 14484 14485 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14486 String resultData, Bundle resultExtras, boolean resultAbort) { 14487 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14488 if (r == null) { 14489 Slog.w(TAG, "finishReceiver called but not found on queue"); 14490 return false; 14491 } 14492 14493 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14494 } 14495 14496 void backgroundServicesFinishedLocked(int userId) { 14497 for (BroadcastQueue queue : mBroadcastQueues) { 14498 queue.backgroundServicesFinishedLocked(userId); 14499 } 14500 } 14501 14502 public void finishReceiver(IBinder who, int resultCode, String resultData, 14503 Bundle resultExtras, boolean resultAbort) { 14504 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14505 14506 // Refuse possible leaked file descriptors 14507 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14508 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14509 } 14510 14511 final long origId = Binder.clearCallingIdentity(); 14512 try { 14513 boolean doNext = false; 14514 BroadcastRecord r; 14515 14516 synchronized(this) { 14517 r = broadcastRecordForReceiverLocked(who); 14518 if (r != null) { 14519 doNext = r.queue.finishReceiverLocked(r, resultCode, 14520 resultData, resultExtras, resultAbort, true); 14521 } 14522 } 14523 14524 if (doNext) { 14525 r.queue.processNextBroadcast(false); 14526 } 14527 trimApplications(); 14528 } finally { 14529 Binder.restoreCallingIdentity(origId); 14530 } 14531 } 14532 14533 // ========================================================= 14534 // INSTRUMENTATION 14535 // ========================================================= 14536 14537 public boolean startInstrumentation(ComponentName className, 14538 String profileFile, int flags, Bundle arguments, 14539 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14540 int userId, String abiOverride) { 14541 enforceNotIsolatedCaller("startInstrumentation"); 14542 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14543 userId, false, true, "startInstrumentation", null); 14544 // Refuse possible leaked file descriptors 14545 if (arguments != null && arguments.hasFileDescriptors()) { 14546 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14547 } 14548 14549 synchronized(this) { 14550 InstrumentationInfo ii = null; 14551 ApplicationInfo ai = null; 14552 try { 14553 ii = mContext.getPackageManager().getInstrumentationInfo( 14554 className, STOCK_PM_FLAGS); 14555 ai = AppGlobals.getPackageManager().getApplicationInfo( 14556 ii.targetPackage, STOCK_PM_FLAGS, userId); 14557 } catch (PackageManager.NameNotFoundException e) { 14558 } catch (RemoteException e) { 14559 } 14560 if (ii == null) { 14561 reportStartInstrumentationFailure(watcher, className, 14562 "Unable to find instrumentation info for: " + className); 14563 return false; 14564 } 14565 if (ai == null) { 14566 reportStartInstrumentationFailure(watcher, className, 14567 "Unable to find instrumentation target package: " + ii.targetPackage); 14568 return false; 14569 } 14570 14571 int match = mContext.getPackageManager().checkSignatures( 14572 ii.targetPackage, ii.packageName); 14573 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14574 String msg = "Permission Denial: starting instrumentation " 14575 + className + " from pid=" 14576 + Binder.getCallingPid() 14577 + ", uid=" + Binder.getCallingPid() 14578 + " not allowed because package " + ii.packageName 14579 + " does not have a signature matching the target " 14580 + ii.targetPackage; 14581 reportStartInstrumentationFailure(watcher, className, msg); 14582 throw new SecurityException(msg); 14583 } 14584 14585 final long origId = Binder.clearCallingIdentity(); 14586 // Instrumentation can kill and relaunch even persistent processes 14587 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14588 "start instr"); 14589 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14590 app.instrumentationClass = className; 14591 app.instrumentationInfo = ai; 14592 app.instrumentationProfileFile = profileFile; 14593 app.instrumentationArguments = arguments; 14594 app.instrumentationWatcher = watcher; 14595 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14596 app.instrumentationResultClass = className; 14597 Binder.restoreCallingIdentity(origId); 14598 } 14599 14600 return true; 14601 } 14602 14603 /** 14604 * Report errors that occur while attempting to start Instrumentation. Always writes the 14605 * error to the logs, but if somebody is watching, send the report there too. This enables 14606 * the "am" command to report errors with more information. 14607 * 14608 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14609 * @param cn The component name of the instrumentation. 14610 * @param report The error report. 14611 */ 14612 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14613 ComponentName cn, String report) { 14614 Slog.w(TAG, report); 14615 try { 14616 if (watcher != null) { 14617 Bundle results = new Bundle(); 14618 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14619 results.putString("Error", report); 14620 watcher.instrumentationStatus(cn, -1, results); 14621 } 14622 } catch (RemoteException e) { 14623 Slog.w(TAG, e); 14624 } 14625 } 14626 14627 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14628 if (app.instrumentationWatcher != null) { 14629 try { 14630 // NOTE: IInstrumentationWatcher *must* be oneway here 14631 app.instrumentationWatcher.instrumentationFinished( 14632 app.instrumentationClass, 14633 resultCode, 14634 results); 14635 } catch (RemoteException e) { 14636 } 14637 } 14638 if (app.instrumentationUiAutomationConnection != null) { 14639 try { 14640 app.instrumentationUiAutomationConnection.shutdown(); 14641 } catch (RemoteException re) { 14642 /* ignore */ 14643 } 14644 // Only a UiAutomation can set this flag and now that 14645 // it is finished we make sure it is reset to its default. 14646 mUserIsMonkey = false; 14647 } 14648 app.instrumentationWatcher = null; 14649 app.instrumentationUiAutomationConnection = null; 14650 app.instrumentationClass = null; 14651 app.instrumentationInfo = null; 14652 app.instrumentationProfileFile = null; 14653 app.instrumentationArguments = null; 14654 14655 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14656 "finished inst"); 14657 } 14658 14659 public void finishInstrumentation(IApplicationThread target, 14660 int resultCode, Bundle results) { 14661 int userId = UserHandle.getCallingUserId(); 14662 // Refuse possible leaked file descriptors 14663 if (results != null && results.hasFileDescriptors()) { 14664 throw new IllegalArgumentException("File descriptors passed in Intent"); 14665 } 14666 14667 synchronized(this) { 14668 ProcessRecord app = getRecordForAppLocked(target); 14669 if (app == null) { 14670 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14671 return; 14672 } 14673 final long origId = Binder.clearCallingIdentity(); 14674 finishInstrumentationLocked(app, resultCode, results); 14675 Binder.restoreCallingIdentity(origId); 14676 } 14677 } 14678 14679 // ========================================================= 14680 // CONFIGURATION 14681 // ========================================================= 14682 14683 public ConfigurationInfo getDeviceConfigurationInfo() { 14684 ConfigurationInfo config = new ConfigurationInfo(); 14685 synchronized (this) { 14686 config.reqTouchScreen = mConfiguration.touchscreen; 14687 config.reqKeyboardType = mConfiguration.keyboard; 14688 config.reqNavigation = mConfiguration.navigation; 14689 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14690 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14691 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14692 } 14693 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14694 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14695 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14696 } 14697 config.reqGlEsVersion = GL_ES_VERSION; 14698 } 14699 return config; 14700 } 14701 14702 ActivityStack getFocusedStack() { 14703 return mStackSupervisor.getFocusedStack(); 14704 } 14705 14706 public Configuration getConfiguration() { 14707 Configuration ci; 14708 synchronized(this) { 14709 ci = new Configuration(mConfiguration); 14710 } 14711 return ci; 14712 } 14713 14714 public void updatePersistentConfiguration(Configuration values) { 14715 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14716 "updateConfiguration()"); 14717 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14718 "updateConfiguration()"); 14719 if (values == null) { 14720 throw new NullPointerException("Configuration must not be null"); 14721 } 14722 14723 synchronized(this) { 14724 final long origId = Binder.clearCallingIdentity(); 14725 updateConfigurationLocked(values, null, true, false); 14726 Binder.restoreCallingIdentity(origId); 14727 } 14728 } 14729 14730 public void updateConfiguration(Configuration values) { 14731 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14732 "updateConfiguration()"); 14733 14734 synchronized(this) { 14735 if (values == null && mWindowManager != null) { 14736 // sentinel: fetch the current configuration from the window manager 14737 values = mWindowManager.computeNewConfiguration(); 14738 } 14739 14740 if (mWindowManager != null) { 14741 mProcessList.applyDisplaySize(mWindowManager); 14742 } 14743 14744 final long origId = Binder.clearCallingIdentity(); 14745 if (values != null) { 14746 Settings.System.clearConfiguration(values); 14747 } 14748 updateConfigurationLocked(values, null, false, false); 14749 Binder.restoreCallingIdentity(origId); 14750 } 14751 } 14752 14753 /** 14754 * Do either or both things: (1) change the current configuration, and (2) 14755 * make sure the given activity is running with the (now) current 14756 * configuration. Returns true if the activity has been left running, or 14757 * false if <var>starting</var> is being destroyed to match the new 14758 * configuration. 14759 * @param persistent TODO 14760 */ 14761 boolean updateConfigurationLocked(Configuration values, 14762 ActivityRecord starting, boolean persistent, boolean initLocale) { 14763 int changes = 0; 14764 14765 if (values != null) { 14766 Configuration newConfig = new Configuration(mConfiguration); 14767 changes = newConfig.updateFrom(values); 14768 if (changes != 0) { 14769 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14770 Slog.i(TAG, "Updating configuration to: " + values); 14771 } 14772 14773 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14774 14775 if (values.locale != null && !initLocale) { 14776 saveLocaleLocked(values.locale, 14777 !values.locale.equals(mConfiguration.locale), 14778 values.userSetLocale); 14779 } 14780 14781 mConfigurationSeq++; 14782 if (mConfigurationSeq <= 0) { 14783 mConfigurationSeq = 1; 14784 } 14785 newConfig.seq = mConfigurationSeq; 14786 mConfiguration = newConfig; 14787 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14788 mUsageStatsService.noteStartConfig(newConfig); 14789 14790 final Configuration configCopy = new Configuration(mConfiguration); 14791 14792 // TODO: If our config changes, should we auto dismiss any currently 14793 // showing dialogs? 14794 mShowDialogs = shouldShowDialogs(newConfig); 14795 14796 AttributeCache ac = AttributeCache.instance(); 14797 if (ac != null) { 14798 ac.updateConfiguration(configCopy); 14799 } 14800 14801 // Make sure all resources in our process are updated 14802 // right now, so that anyone who is going to retrieve 14803 // resource values after we return will be sure to get 14804 // the new ones. This is especially important during 14805 // boot, where the first config change needs to guarantee 14806 // all resources have that config before following boot 14807 // code is executed. 14808 mSystemThread.applyConfigurationToResources(configCopy); 14809 14810 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14811 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14812 msg.obj = new Configuration(configCopy); 14813 mHandler.sendMessage(msg); 14814 } 14815 14816 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14817 ProcessRecord app = mLruProcesses.get(i); 14818 try { 14819 if (app.thread != null) { 14820 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14821 + app.processName + " new config " + mConfiguration); 14822 app.thread.scheduleConfigurationChanged(configCopy); 14823 } 14824 } catch (Exception e) { 14825 } 14826 } 14827 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14828 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14829 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14830 | Intent.FLAG_RECEIVER_FOREGROUND); 14831 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14832 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14833 Process.SYSTEM_UID, UserHandle.USER_ALL); 14834 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14835 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14836 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14837 broadcastIntentLocked(null, null, intent, 14838 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14839 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14840 } 14841 } 14842 } 14843 14844 boolean kept = true; 14845 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14846 // mainStack is null during startup. 14847 if (mainStack != null) { 14848 if (changes != 0 && starting == null) { 14849 // If the configuration changed, and the caller is not already 14850 // in the process of starting an activity, then find the top 14851 // activity to check if its configuration needs to change. 14852 starting = mainStack.topRunningActivityLocked(null); 14853 } 14854 14855 if (starting != null) { 14856 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14857 // And we need to make sure at this point that all other activities 14858 // are made visible with the correct configuration. 14859 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14860 } 14861 } 14862 14863 if (values != null && mWindowManager != null) { 14864 mWindowManager.setNewConfiguration(mConfiguration); 14865 } 14866 14867 return kept; 14868 } 14869 14870 /** 14871 * Decide based on the configuration whether we should shouw the ANR, 14872 * crash, etc dialogs. The idea is that if there is no affordnace to 14873 * press the on-screen buttons, we shouldn't show the dialog. 14874 * 14875 * A thought: SystemUI might also want to get told about this, the Power 14876 * dialog / global actions also might want different behaviors. 14877 */ 14878 private static final boolean shouldShowDialogs(Configuration config) { 14879 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14880 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14881 } 14882 14883 /** 14884 * Save the locale. You must be inside a synchronized (this) block. 14885 */ 14886 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14887 if(isDiff) { 14888 SystemProperties.set("user.language", l.getLanguage()); 14889 SystemProperties.set("user.region", l.getCountry()); 14890 } 14891 14892 if(isPersist) { 14893 SystemProperties.set("persist.sys.language", l.getLanguage()); 14894 SystemProperties.set("persist.sys.country", l.getCountry()); 14895 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14896 } 14897 } 14898 14899 @Override 14900 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14901 ActivityRecord srec = ActivityRecord.forToken(token); 14902 return srec != null && srec.task.affinity != null && 14903 srec.task.affinity.equals(destAffinity); 14904 } 14905 14906 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14907 Intent resultData) { 14908 14909 synchronized (this) { 14910 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14911 if (stack != null) { 14912 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14913 } 14914 return false; 14915 } 14916 } 14917 14918 public int getLaunchedFromUid(IBinder activityToken) { 14919 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14920 if (srec == null) { 14921 return -1; 14922 } 14923 return srec.launchedFromUid; 14924 } 14925 14926 public String getLaunchedFromPackage(IBinder activityToken) { 14927 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14928 if (srec == null) { 14929 return null; 14930 } 14931 return srec.launchedFromPackage; 14932 } 14933 14934 // ========================================================= 14935 // LIFETIME MANAGEMENT 14936 // ========================================================= 14937 14938 // Returns which broadcast queue the app is the current [or imminent] receiver 14939 // on, or 'null' if the app is not an active broadcast recipient. 14940 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14941 BroadcastRecord r = app.curReceiver; 14942 if (r != null) { 14943 return r.queue; 14944 } 14945 14946 // It's not the current receiver, but it might be starting up to become one 14947 synchronized (this) { 14948 for (BroadcastQueue queue : mBroadcastQueues) { 14949 r = queue.mPendingBroadcast; 14950 if (r != null && r.curApp == app) { 14951 // found it; report which queue it's in 14952 return queue; 14953 } 14954 } 14955 } 14956 14957 return null; 14958 } 14959 14960 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14961 boolean doingAll, long now) { 14962 if (mAdjSeq == app.adjSeq) { 14963 // This adjustment has already been computed. 14964 return app.curRawAdj; 14965 } 14966 14967 if (app.thread == null) { 14968 app.adjSeq = mAdjSeq; 14969 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14970 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14971 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14972 } 14973 14974 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14975 app.adjSource = null; 14976 app.adjTarget = null; 14977 app.empty = false; 14978 app.cached = false; 14979 14980 final int activitiesSize = app.activities.size(); 14981 14982 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14983 // The max adjustment doesn't allow this app to be anything 14984 // below foreground, so it is not worth doing work for it. 14985 app.adjType = "fixed"; 14986 app.adjSeq = mAdjSeq; 14987 app.curRawAdj = app.maxAdj; 14988 app.foregroundActivities = false; 14989 app.keeping = true; 14990 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14991 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14992 // System processes can do UI, and when they do we want to have 14993 // them trim their memory after the user leaves the UI. To 14994 // facilitate this, here we need to determine whether or not it 14995 // is currently showing UI. 14996 app.systemNoUi = true; 14997 if (app == TOP_APP) { 14998 app.systemNoUi = false; 14999 } else if (activitiesSize > 0) { 15000 for (int j = 0; j < activitiesSize; j++) { 15001 final ActivityRecord r = app.activities.get(j); 15002 if (r.visible) { 15003 app.systemNoUi = false; 15004 } 15005 } 15006 } 15007 if (!app.systemNoUi) { 15008 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15009 } 15010 return (app.curAdj=app.maxAdj); 15011 } 15012 15013 app.keeping = false; 15014 app.systemNoUi = false; 15015 15016 // Determine the importance of the process, starting with most 15017 // important to least, and assign an appropriate OOM adjustment. 15018 int adj; 15019 int schedGroup; 15020 int procState; 15021 boolean foregroundActivities = false; 15022 boolean interesting = false; 15023 BroadcastQueue queue; 15024 if (app == TOP_APP) { 15025 // The last app on the list is the foreground app. 15026 adj = ProcessList.FOREGROUND_APP_ADJ; 15027 schedGroup = Process.THREAD_GROUP_DEFAULT; 15028 app.adjType = "top-activity"; 15029 foregroundActivities = true; 15030 interesting = true; 15031 procState = ActivityManager.PROCESS_STATE_TOP; 15032 } else if (app.instrumentationClass != null) { 15033 // Don't want to kill running instrumentation. 15034 adj = ProcessList.FOREGROUND_APP_ADJ; 15035 schedGroup = Process.THREAD_GROUP_DEFAULT; 15036 app.adjType = "instrumentation"; 15037 interesting = true; 15038 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15039 } else if ((queue = isReceivingBroadcast(app)) != null) { 15040 // An app that is currently receiving a broadcast also 15041 // counts as being in the foreground for OOM killer purposes. 15042 // It's placed in a sched group based on the nature of the 15043 // broadcast as reflected by which queue it's active in. 15044 adj = ProcessList.FOREGROUND_APP_ADJ; 15045 schedGroup = (queue == mFgBroadcastQueue) 15046 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15047 app.adjType = "broadcast"; 15048 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15049 } else if (app.executingServices.size() > 0) { 15050 // An app that is currently executing a service callback also 15051 // counts as being in the foreground. 15052 adj = ProcessList.FOREGROUND_APP_ADJ; 15053 schedGroup = app.execServicesFg ? 15054 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15055 app.adjType = "exec-service"; 15056 procState = ActivityManager.PROCESS_STATE_SERVICE; 15057 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15058 } else { 15059 // As far as we know the process is empty. We may change our mind later. 15060 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15061 // At this point we don't actually know the adjustment. Use the cached adj 15062 // value that the caller wants us to. 15063 adj = cachedAdj; 15064 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15065 app.cached = true; 15066 app.empty = true; 15067 app.adjType = "cch-empty"; 15068 } 15069 15070 // Examine all activities if not already foreground. 15071 if (!foregroundActivities && activitiesSize > 0) { 15072 for (int j = 0; j < activitiesSize; j++) { 15073 final ActivityRecord r = app.activities.get(j); 15074 if (r.app != app) { 15075 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15076 + app + "?!?"); 15077 continue; 15078 } 15079 if (r.visible) { 15080 // App has a visible activity; only upgrade adjustment. 15081 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15082 adj = ProcessList.VISIBLE_APP_ADJ; 15083 app.adjType = "visible"; 15084 } 15085 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15086 procState = ActivityManager.PROCESS_STATE_TOP; 15087 } 15088 schedGroup = Process.THREAD_GROUP_DEFAULT; 15089 app.cached = false; 15090 app.empty = false; 15091 foregroundActivities = true; 15092 break; 15093 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15094 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15095 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15096 app.adjType = "pausing"; 15097 } 15098 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15099 procState = ActivityManager.PROCESS_STATE_TOP; 15100 } 15101 schedGroup = Process.THREAD_GROUP_DEFAULT; 15102 app.cached = false; 15103 app.empty = false; 15104 foregroundActivities = true; 15105 } else if (r.state == ActivityState.STOPPING) { 15106 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15107 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15108 app.adjType = "stopping"; 15109 } 15110 // For the process state, we will at this point consider the 15111 // process to be cached. It will be cached either as an activity 15112 // or empty depending on whether the activity is finishing. We do 15113 // this so that we can treat the process as cached for purposes of 15114 // memory trimming (determing current memory level, trim command to 15115 // send to process) since there can be an arbitrary number of stopping 15116 // processes and they should soon all go into the cached state. 15117 if (!r.finishing) { 15118 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15119 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15120 } 15121 } 15122 app.cached = false; 15123 app.empty = false; 15124 foregroundActivities = true; 15125 } else { 15126 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15127 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15128 app.adjType = "cch-act"; 15129 } 15130 } 15131 } 15132 } 15133 15134 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15135 if (app.foregroundServices) { 15136 // The user is aware of this app, so make it visible. 15137 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15138 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15139 app.cached = false; 15140 app.adjType = "fg-service"; 15141 schedGroup = Process.THREAD_GROUP_DEFAULT; 15142 } else if (app.forcingToForeground != null) { 15143 // The user is aware of this app, so make it visible. 15144 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15145 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15146 app.cached = false; 15147 app.adjType = "force-fg"; 15148 app.adjSource = app.forcingToForeground; 15149 schedGroup = Process.THREAD_GROUP_DEFAULT; 15150 } 15151 } 15152 15153 if (app.foregroundServices) { 15154 interesting = true; 15155 } 15156 15157 if (app == mHeavyWeightProcess) { 15158 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15159 // We don't want to kill the current heavy-weight process. 15160 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15161 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15162 app.cached = false; 15163 app.adjType = "heavy"; 15164 } 15165 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15166 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15167 } 15168 } 15169 15170 if (app == mHomeProcess) { 15171 if (adj > ProcessList.HOME_APP_ADJ) { 15172 // This process is hosting what we currently consider to be the 15173 // home app, so we don't want to let it go into the background. 15174 adj = ProcessList.HOME_APP_ADJ; 15175 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15176 app.cached = false; 15177 app.adjType = "home"; 15178 } 15179 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15180 procState = ActivityManager.PROCESS_STATE_HOME; 15181 } 15182 } 15183 15184 if (app == mPreviousProcess && app.activities.size() > 0) { 15185 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15186 // This was the previous process that showed UI to the user. 15187 // We want to try to keep it around more aggressively, to give 15188 // a good experience around switching between two apps. 15189 adj = ProcessList.PREVIOUS_APP_ADJ; 15190 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15191 app.cached = false; 15192 app.adjType = "previous"; 15193 } 15194 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15195 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15196 } 15197 } 15198 15199 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15200 + " reason=" + app.adjType); 15201 15202 // By default, we use the computed adjustment. It may be changed if 15203 // there are applications dependent on our services or providers, but 15204 // this gives us a baseline and makes sure we don't get into an 15205 // infinite recursion. 15206 app.adjSeq = mAdjSeq; 15207 app.curRawAdj = adj; 15208 app.hasStartedServices = false; 15209 15210 if (mBackupTarget != null && app == mBackupTarget.app) { 15211 // If possible we want to avoid killing apps while they're being backed up 15212 if (adj > ProcessList.BACKUP_APP_ADJ) { 15213 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15214 adj = ProcessList.BACKUP_APP_ADJ; 15215 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15216 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15217 } 15218 app.adjType = "backup"; 15219 app.cached = false; 15220 } 15221 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15222 procState = ActivityManager.PROCESS_STATE_BACKUP; 15223 } 15224 } 15225 15226 boolean mayBeTop = false; 15227 15228 for (int is = app.services.size()-1; 15229 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15230 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15231 || procState > ActivityManager.PROCESS_STATE_TOP); 15232 is--) { 15233 ServiceRecord s = app.services.valueAt(is); 15234 if (s.startRequested) { 15235 app.hasStartedServices = true; 15236 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15237 procState = ActivityManager.PROCESS_STATE_SERVICE; 15238 } 15239 if (app.hasShownUi && app != mHomeProcess) { 15240 // If this process has shown some UI, let it immediately 15241 // go to the LRU list because it may be pretty heavy with 15242 // UI stuff. We'll tag it with a label just to help 15243 // debug and understand what is going on. 15244 if (adj > ProcessList.SERVICE_ADJ) { 15245 app.adjType = "cch-started-ui-services"; 15246 } 15247 } else { 15248 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15249 // This service has seen some activity within 15250 // recent memory, so we will keep its process ahead 15251 // of the background processes. 15252 if (adj > ProcessList.SERVICE_ADJ) { 15253 adj = ProcessList.SERVICE_ADJ; 15254 app.adjType = "started-services"; 15255 app.cached = false; 15256 } 15257 } 15258 // If we have let the service slide into the background 15259 // state, still have some text describing what it is doing 15260 // even though the service no longer has an impact. 15261 if (adj > ProcessList.SERVICE_ADJ) { 15262 app.adjType = "cch-started-services"; 15263 } 15264 } 15265 // Don't kill this process because it is doing work; it 15266 // has said it is doing work. 15267 app.keeping = true; 15268 } 15269 for (int conni = s.connections.size()-1; 15270 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15271 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15272 || procState > ActivityManager.PROCESS_STATE_TOP); 15273 conni--) { 15274 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15275 for (int i = 0; 15276 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15277 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15278 || procState > ActivityManager.PROCESS_STATE_TOP); 15279 i++) { 15280 // XXX should compute this based on the max of 15281 // all connected clients. 15282 ConnectionRecord cr = clist.get(i); 15283 if (cr.binding.client == app) { 15284 // Binding to ourself is not interesting. 15285 continue; 15286 } 15287 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15288 ProcessRecord client = cr.binding.client; 15289 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15290 TOP_APP, doingAll, now); 15291 int clientProcState = client.curProcState; 15292 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15293 // If the other app is cached for any reason, for purposes here 15294 // we are going to consider it empty. The specific cached state 15295 // doesn't propagate except under certain conditions. 15296 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15297 } 15298 String adjType = null; 15299 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15300 // Not doing bind OOM management, so treat 15301 // this guy more like a started service. 15302 if (app.hasShownUi && app != mHomeProcess) { 15303 // If this process has shown some UI, let it immediately 15304 // go to the LRU list because it may be pretty heavy with 15305 // UI stuff. We'll tag it with a label just to help 15306 // debug and understand what is going on. 15307 if (adj > clientAdj) { 15308 adjType = "cch-bound-ui-services"; 15309 } 15310 app.cached = false; 15311 clientAdj = adj; 15312 clientProcState = procState; 15313 } else { 15314 if (now >= (s.lastActivity 15315 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15316 // This service has not seen activity within 15317 // recent memory, so allow it to drop to the 15318 // LRU list if there is no other reason to keep 15319 // it around. We'll also tag it with a label just 15320 // to help debug and undertand what is going on. 15321 if (adj > clientAdj) { 15322 adjType = "cch-bound-services"; 15323 } 15324 clientAdj = adj; 15325 } 15326 } 15327 } 15328 if (adj > clientAdj) { 15329 // If this process has recently shown UI, and 15330 // the process that is binding to it is less 15331 // important than being visible, then we don't 15332 // care about the binding as much as we care 15333 // about letting this process get into the LRU 15334 // list to be killed and restarted if needed for 15335 // memory. 15336 if (app.hasShownUi && app != mHomeProcess 15337 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15338 adjType = "cch-bound-ui-services"; 15339 } else { 15340 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15341 |Context.BIND_IMPORTANT)) != 0) { 15342 adj = clientAdj; 15343 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15344 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15345 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15346 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15347 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15348 adj = clientAdj; 15349 } else { 15350 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15351 adj = ProcessList.VISIBLE_APP_ADJ; 15352 } 15353 } 15354 if (!client.cached) { 15355 app.cached = false; 15356 } 15357 if (client.keeping) { 15358 app.keeping = true; 15359 } 15360 adjType = "service"; 15361 } 15362 } 15363 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15364 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15365 schedGroup = Process.THREAD_GROUP_DEFAULT; 15366 } 15367 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15368 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15369 // Special handling of clients who are in the top state. 15370 // We *may* want to consider this process to be in the 15371 // top state as well, but only if there is not another 15372 // reason for it to be running. Being on the top is a 15373 // special state, meaning you are specifically running 15374 // for the current top app. If the process is already 15375 // running in the background for some other reason, it 15376 // is more important to continue considering it to be 15377 // in the background state. 15378 mayBeTop = true; 15379 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15380 } else { 15381 // Special handling for above-top states (persistent 15382 // processes). These should not bring the current process 15383 // into the top state, since they are not on top. Instead 15384 // give them the best state after that. 15385 clientProcState = 15386 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15387 } 15388 } 15389 } else { 15390 if (clientProcState < 15391 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15392 clientProcState = 15393 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15394 } 15395 } 15396 if (procState > clientProcState) { 15397 procState = clientProcState; 15398 } 15399 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15400 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15401 app.pendingUiClean = true; 15402 } 15403 if (adjType != null) { 15404 app.adjType = adjType; 15405 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15406 .REASON_SERVICE_IN_USE; 15407 app.adjSource = cr.binding.client; 15408 app.adjSourceOom = clientAdj; 15409 app.adjTarget = s.name; 15410 } 15411 } 15412 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15413 app.treatLikeActivity = true; 15414 } 15415 final ActivityRecord a = cr.activity; 15416 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15417 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15418 (a.visible || a.state == ActivityState.RESUMED 15419 || a.state == ActivityState.PAUSING)) { 15420 adj = ProcessList.FOREGROUND_APP_ADJ; 15421 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15422 schedGroup = Process.THREAD_GROUP_DEFAULT; 15423 } 15424 app.cached = false; 15425 app.adjType = "service"; 15426 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15427 .REASON_SERVICE_IN_USE; 15428 app.adjSource = a; 15429 app.adjSourceOom = adj; 15430 app.adjTarget = s.name; 15431 } 15432 } 15433 } 15434 } 15435 } 15436 15437 for (int provi = app.pubProviders.size()-1; 15438 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15439 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15440 || procState > ActivityManager.PROCESS_STATE_TOP); 15441 provi--) { 15442 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15443 for (int i = cpr.connections.size()-1; 15444 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15445 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15446 || procState > ActivityManager.PROCESS_STATE_TOP); 15447 i--) { 15448 ContentProviderConnection conn = cpr.connections.get(i); 15449 ProcessRecord client = conn.client; 15450 if (client == app) { 15451 // Being our own client is not interesting. 15452 continue; 15453 } 15454 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15455 int clientProcState = client.curProcState; 15456 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15457 // If the other app is cached for any reason, for purposes here 15458 // we are going to consider it empty. 15459 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15460 } 15461 if (adj > clientAdj) { 15462 if (app.hasShownUi && app != mHomeProcess 15463 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15464 app.adjType = "cch-ui-provider"; 15465 } else { 15466 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15467 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15468 app.adjType = "provider"; 15469 } 15470 app.cached &= client.cached; 15471 app.keeping |= client.keeping; 15472 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15473 .REASON_PROVIDER_IN_USE; 15474 app.adjSource = client; 15475 app.adjSourceOom = clientAdj; 15476 app.adjTarget = cpr.name; 15477 } 15478 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15479 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15480 // Special handling of clients who are in the top state. 15481 // We *may* want to consider this process to be in the 15482 // top state as well, but only if there is not another 15483 // reason for it to be running. Being on the top is a 15484 // special state, meaning you are specifically running 15485 // for the current top app. If the process is already 15486 // running in the background for some other reason, it 15487 // is more important to continue considering it to be 15488 // in the background state. 15489 mayBeTop = true; 15490 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15491 } else { 15492 // Special handling for above-top states (persistent 15493 // processes). These should not bring the current process 15494 // into the top state, since they are not on top. Instead 15495 // give them the best state after that. 15496 clientProcState = 15497 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15498 } 15499 } 15500 if (procState > clientProcState) { 15501 procState = clientProcState; 15502 } 15503 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15504 schedGroup = Process.THREAD_GROUP_DEFAULT; 15505 } 15506 } 15507 // If the provider has external (non-framework) process 15508 // dependencies, ensure that its adjustment is at least 15509 // FOREGROUND_APP_ADJ. 15510 if (cpr.hasExternalProcessHandles()) { 15511 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15512 adj = ProcessList.FOREGROUND_APP_ADJ; 15513 schedGroup = Process.THREAD_GROUP_DEFAULT; 15514 app.cached = false; 15515 app.keeping = true; 15516 app.adjType = "provider"; 15517 app.adjTarget = cpr.name; 15518 } 15519 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15520 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15521 } 15522 } 15523 } 15524 15525 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15526 // A client of one of our services or providers is in the top state. We 15527 // *may* want to be in the top state, but not if we are already running in 15528 // the background for some other reason. For the decision here, we are going 15529 // to pick out a few specific states that we want to remain in when a client 15530 // is top (states that tend to be longer-term) and otherwise allow it to go 15531 // to the top state. 15532 switch (procState) { 15533 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15534 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15535 case ActivityManager.PROCESS_STATE_SERVICE: 15536 // These all are longer-term states, so pull them up to the top 15537 // of the background states, but not all the way to the top state. 15538 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15539 break; 15540 default: 15541 // Otherwise, top is a better choice, so take it. 15542 procState = ActivityManager.PROCESS_STATE_TOP; 15543 break; 15544 } 15545 } 15546 15547 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15548 if (app.hasClientActivities) { 15549 // This is a cached process, but with client activities. Mark it so. 15550 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15551 app.adjType = "cch-client-act"; 15552 } else if (app.treatLikeActivity) { 15553 // This is a cached process, but somebody wants us to treat it like it has 15554 // an activity, okay! 15555 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15556 app.adjType = "cch-as-act"; 15557 } 15558 } 15559 15560 if (adj == ProcessList.SERVICE_ADJ) { 15561 if (doingAll) { 15562 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15563 mNewNumServiceProcs++; 15564 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15565 if (!app.serviceb) { 15566 // This service isn't far enough down on the LRU list to 15567 // normally be a B service, but if we are low on RAM and it 15568 // is large we want to force it down since we would prefer to 15569 // keep launcher over it. 15570 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15571 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15572 app.serviceHighRam = true; 15573 app.serviceb = true; 15574 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15575 } else { 15576 mNewNumAServiceProcs++; 15577 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15578 } 15579 } else { 15580 app.serviceHighRam = false; 15581 } 15582 } 15583 if (app.serviceb) { 15584 adj = ProcessList.SERVICE_B_ADJ; 15585 } 15586 } 15587 15588 app.curRawAdj = adj; 15589 15590 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15591 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15592 if (adj > app.maxAdj) { 15593 adj = app.maxAdj; 15594 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15595 schedGroup = Process.THREAD_GROUP_DEFAULT; 15596 } 15597 } 15598 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15599 app.keeping = true; 15600 } 15601 15602 // Do final modification to adj. Everything we do between here and applying 15603 // the final setAdj must be done in this function, because we will also use 15604 // it when computing the final cached adj later. Note that we don't need to 15605 // worry about this for max adj above, since max adj will always be used to 15606 // keep it out of the cached vaues. 15607 app.curAdj = app.modifyRawOomAdj(adj); 15608 app.curSchedGroup = schedGroup; 15609 app.curProcState = procState; 15610 app.foregroundActivities = foregroundActivities; 15611 15612 return app.curRawAdj; 15613 } 15614 15615 /** 15616 * Schedule PSS collection of a process. 15617 */ 15618 void requestPssLocked(ProcessRecord proc, int procState) { 15619 if (mPendingPssProcesses.contains(proc)) { 15620 return; 15621 } 15622 if (mPendingPssProcesses.size() == 0) { 15623 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15624 } 15625 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15626 proc.pssProcState = procState; 15627 mPendingPssProcesses.add(proc); 15628 } 15629 15630 /** 15631 * Schedule PSS collection of all processes. 15632 */ 15633 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15634 if (!always) { 15635 if (now < (mLastFullPssTime + 15636 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15637 return; 15638 } 15639 } 15640 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15641 mLastFullPssTime = now; 15642 mFullPssPending = true; 15643 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15644 mPendingPssProcesses.clear(); 15645 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15646 ProcessRecord app = mLruProcesses.get(i); 15647 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15648 app.pssProcState = app.setProcState; 15649 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15650 isSleeping(), now); 15651 mPendingPssProcesses.add(app); 15652 } 15653 } 15654 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15655 } 15656 15657 /** 15658 * Ask a given process to GC right now. 15659 */ 15660 final void performAppGcLocked(ProcessRecord app) { 15661 try { 15662 app.lastRequestedGc = SystemClock.uptimeMillis(); 15663 if (app.thread != null) { 15664 if (app.reportLowMemory) { 15665 app.reportLowMemory = false; 15666 app.thread.scheduleLowMemory(); 15667 } else { 15668 app.thread.processInBackground(); 15669 } 15670 } 15671 } catch (Exception e) { 15672 // whatever. 15673 } 15674 } 15675 15676 /** 15677 * Returns true if things are idle enough to perform GCs. 15678 */ 15679 private final boolean canGcNowLocked() { 15680 boolean processingBroadcasts = false; 15681 for (BroadcastQueue q : mBroadcastQueues) { 15682 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15683 processingBroadcasts = true; 15684 } 15685 } 15686 return !processingBroadcasts 15687 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15688 } 15689 15690 /** 15691 * Perform GCs on all processes that are waiting for it, but only 15692 * if things are idle. 15693 */ 15694 final void performAppGcsLocked() { 15695 final int N = mProcessesToGc.size(); 15696 if (N <= 0) { 15697 return; 15698 } 15699 if (canGcNowLocked()) { 15700 while (mProcessesToGc.size() > 0) { 15701 ProcessRecord proc = mProcessesToGc.remove(0); 15702 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15703 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15704 <= SystemClock.uptimeMillis()) { 15705 // To avoid spamming the system, we will GC processes one 15706 // at a time, waiting a few seconds between each. 15707 performAppGcLocked(proc); 15708 scheduleAppGcsLocked(); 15709 return; 15710 } else { 15711 // It hasn't been long enough since we last GCed this 15712 // process... put it in the list to wait for its time. 15713 addProcessToGcListLocked(proc); 15714 break; 15715 } 15716 } 15717 } 15718 15719 scheduleAppGcsLocked(); 15720 } 15721 } 15722 15723 /** 15724 * If all looks good, perform GCs on all processes waiting for them. 15725 */ 15726 final void performAppGcsIfAppropriateLocked() { 15727 if (canGcNowLocked()) { 15728 performAppGcsLocked(); 15729 return; 15730 } 15731 // Still not idle, wait some more. 15732 scheduleAppGcsLocked(); 15733 } 15734 15735 /** 15736 * Schedule the execution of all pending app GCs. 15737 */ 15738 final void scheduleAppGcsLocked() { 15739 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15740 15741 if (mProcessesToGc.size() > 0) { 15742 // Schedule a GC for the time to the next process. 15743 ProcessRecord proc = mProcessesToGc.get(0); 15744 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15745 15746 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15747 long now = SystemClock.uptimeMillis(); 15748 if (when < (now+GC_TIMEOUT)) { 15749 when = now + GC_TIMEOUT; 15750 } 15751 mHandler.sendMessageAtTime(msg, when); 15752 } 15753 } 15754 15755 /** 15756 * Add a process to the array of processes waiting to be GCed. Keeps the 15757 * list in sorted order by the last GC time. The process can't already be 15758 * on the list. 15759 */ 15760 final void addProcessToGcListLocked(ProcessRecord proc) { 15761 boolean added = false; 15762 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15763 if (mProcessesToGc.get(i).lastRequestedGc < 15764 proc.lastRequestedGc) { 15765 added = true; 15766 mProcessesToGc.add(i+1, proc); 15767 break; 15768 } 15769 } 15770 if (!added) { 15771 mProcessesToGc.add(0, proc); 15772 } 15773 } 15774 15775 /** 15776 * Set up to ask a process to GC itself. This will either do it 15777 * immediately, or put it on the list of processes to gc the next 15778 * time things are idle. 15779 */ 15780 final void scheduleAppGcLocked(ProcessRecord app) { 15781 long now = SystemClock.uptimeMillis(); 15782 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15783 return; 15784 } 15785 if (!mProcessesToGc.contains(app)) { 15786 addProcessToGcListLocked(app); 15787 scheduleAppGcsLocked(); 15788 } 15789 } 15790 15791 final void checkExcessivePowerUsageLocked(boolean doKills) { 15792 updateCpuStatsNow(); 15793 15794 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15795 boolean doWakeKills = doKills; 15796 boolean doCpuKills = doKills; 15797 if (mLastPowerCheckRealtime == 0) { 15798 doWakeKills = false; 15799 } 15800 if (mLastPowerCheckUptime == 0) { 15801 doCpuKills = false; 15802 } 15803 if (stats.isScreenOn()) { 15804 doWakeKills = false; 15805 } 15806 final long curRealtime = SystemClock.elapsedRealtime(); 15807 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15808 final long curUptime = SystemClock.uptimeMillis(); 15809 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15810 mLastPowerCheckRealtime = curRealtime; 15811 mLastPowerCheckUptime = curUptime; 15812 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15813 doWakeKills = false; 15814 } 15815 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15816 doCpuKills = false; 15817 } 15818 int i = mLruProcesses.size(); 15819 while (i > 0) { 15820 i--; 15821 ProcessRecord app = mLruProcesses.get(i); 15822 if (!app.keeping) { 15823 long wtime; 15824 synchronized (stats) { 15825 wtime = stats.getProcessWakeTime(app.info.uid, 15826 app.pid, curRealtime); 15827 } 15828 long wtimeUsed = wtime - app.lastWakeTime; 15829 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15830 if (DEBUG_POWER) { 15831 StringBuilder sb = new StringBuilder(128); 15832 sb.append("Wake for "); 15833 app.toShortString(sb); 15834 sb.append(": over "); 15835 TimeUtils.formatDuration(realtimeSince, sb); 15836 sb.append(" used "); 15837 TimeUtils.formatDuration(wtimeUsed, sb); 15838 sb.append(" ("); 15839 sb.append((wtimeUsed*100)/realtimeSince); 15840 sb.append("%)"); 15841 Slog.i(TAG, sb.toString()); 15842 sb.setLength(0); 15843 sb.append("CPU for "); 15844 app.toShortString(sb); 15845 sb.append(": over "); 15846 TimeUtils.formatDuration(uptimeSince, sb); 15847 sb.append(" used "); 15848 TimeUtils.formatDuration(cputimeUsed, sb); 15849 sb.append(" ("); 15850 sb.append((cputimeUsed*100)/uptimeSince); 15851 sb.append("%)"); 15852 Slog.i(TAG, sb.toString()); 15853 } 15854 // If a process has held a wake lock for more 15855 // than 50% of the time during this period, 15856 // that sounds bad. Kill! 15857 if (doWakeKills && realtimeSince > 0 15858 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15859 synchronized (stats) { 15860 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15861 realtimeSince, wtimeUsed); 15862 } 15863 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15864 + " during " + realtimeSince); 15865 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15866 } else if (doCpuKills && uptimeSince > 0 15867 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15868 synchronized (stats) { 15869 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15870 uptimeSince, cputimeUsed); 15871 } 15872 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15873 + " during " + uptimeSince); 15874 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15875 } else { 15876 app.lastWakeTime = wtime; 15877 app.lastCpuTime = app.curCpuTime; 15878 } 15879 } 15880 } 15881 } 15882 15883 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15884 ProcessRecord TOP_APP, boolean doingAll, long now) { 15885 boolean success = true; 15886 15887 if (app.curRawAdj != app.setRawAdj) { 15888 if (wasKeeping && !app.keeping) { 15889 // This app is no longer something we want to keep. Note 15890 // its current wake lock time to later know to kill it if 15891 // it is not behaving well. 15892 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15893 synchronized (stats) { 15894 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15895 app.pid, SystemClock.elapsedRealtime()); 15896 } 15897 app.lastCpuTime = app.curCpuTime; 15898 } 15899 15900 app.setRawAdj = app.curRawAdj; 15901 } 15902 15903 int changes = 0; 15904 15905 if (app.curAdj != app.setAdj) { 15906 ProcessList.setOomAdj(app.pid, app.curAdj); 15907 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15908 TAG, "Set " + app.pid + " " + app.processName + 15909 " adj " + app.curAdj + ": " + app.adjType); 15910 app.setAdj = app.curAdj; 15911 } 15912 15913 if (app.setSchedGroup != app.curSchedGroup) { 15914 app.setSchedGroup = app.curSchedGroup; 15915 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15916 "Setting process group of " + app.processName 15917 + " to " + app.curSchedGroup); 15918 if (app.waitingToKill != null && 15919 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15920 killUnneededProcessLocked(app, app.waitingToKill); 15921 success = false; 15922 } else { 15923 if (true) { 15924 long oldId = Binder.clearCallingIdentity(); 15925 try { 15926 Process.setProcessGroup(app.pid, app.curSchedGroup); 15927 } catch (Exception e) { 15928 Slog.w(TAG, "Failed setting process group of " + app.pid 15929 + " to " + app.curSchedGroup); 15930 e.printStackTrace(); 15931 } finally { 15932 Binder.restoreCallingIdentity(oldId); 15933 } 15934 } else { 15935 if (app.thread != null) { 15936 try { 15937 app.thread.setSchedulingGroup(app.curSchedGroup); 15938 } catch (RemoteException e) { 15939 } 15940 } 15941 } 15942 Process.setSwappiness(app.pid, 15943 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15944 } 15945 } 15946 if (app.repForegroundActivities != app.foregroundActivities) { 15947 app.repForegroundActivities = app.foregroundActivities; 15948 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15949 } 15950 if (app.repProcState != app.curProcState) { 15951 app.repProcState = app.curProcState; 15952 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15953 if (app.thread != null) { 15954 try { 15955 if (false) { 15956 //RuntimeException h = new RuntimeException("here"); 15957 Slog.i(TAG, "Sending new process state " + app.repProcState 15958 + " to " + app /*, h*/); 15959 } 15960 app.thread.setProcessState(app.repProcState); 15961 } catch (RemoteException e) { 15962 } 15963 } 15964 } 15965 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15966 app.setProcState)) { 15967 app.lastStateTime = now; 15968 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15969 isSleeping(), now); 15970 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15971 + ProcessList.makeProcStateString(app.setProcState) + " to " 15972 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15973 + (app.nextPssTime-now) + ": " + app); 15974 } else { 15975 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15976 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15977 requestPssLocked(app, app.setProcState); 15978 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15979 isSleeping(), now); 15980 } else if (false && DEBUG_PSS) { 15981 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15982 } 15983 } 15984 if (app.setProcState != app.curProcState) { 15985 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15986 "Proc state change of " + app.processName 15987 + " to " + app.curProcState); 15988 app.setProcState = app.curProcState; 15989 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15990 app.notCachedSinceIdle = false; 15991 } 15992 if (!doingAll) { 15993 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15994 } else { 15995 app.procStateChanged = true; 15996 } 15997 } 15998 15999 if (changes != 0) { 16000 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16001 int i = mPendingProcessChanges.size()-1; 16002 ProcessChangeItem item = null; 16003 while (i >= 0) { 16004 item = mPendingProcessChanges.get(i); 16005 if (item.pid == app.pid) { 16006 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16007 break; 16008 } 16009 i--; 16010 } 16011 if (i < 0) { 16012 // No existing item in pending changes; need a new one. 16013 final int NA = mAvailProcessChanges.size(); 16014 if (NA > 0) { 16015 item = mAvailProcessChanges.remove(NA-1); 16016 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16017 } else { 16018 item = new ProcessChangeItem(); 16019 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16020 } 16021 item.changes = 0; 16022 item.pid = app.pid; 16023 item.uid = app.info.uid; 16024 if (mPendingProcessChanges.size() == 0) { 16025 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16026 "*** Enqueueing dispatch processes changed!"); 16027 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16028 } 16029 mPendingProcessChanges.add(item); 16030 } 16031 item.changes |= changes; 16032 item.processState = app.repProcState; 16033 item.foregroundActivities = app.repForegroundActivities; 16034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16035 + Integer.toHexString(System.identityHashCode(item)) 16036 + " " + app.toShortString() + ": changes=" + item.changes 16037 + " procState=" + item.processState 16038 + " foreground=" + item.foregroundActivities 16039 + " type=" + app.adjType + " source=" + app.adjSource 16040 + " target=" + app.adjTarget); 16041 } 16042 16043 return success; 16044 } 16045 16046 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 16047 if (proc.thread != null && proc.baseProcessTracker != null) { 16048 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16049 } 16050 } 16051 16052 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16053 ProcessRecord TOP_APP, boolean doingAll, long now) { 16054 if (app.thread == null) { 16055 return false; 16056 } 16057 16058 final boolean wasKeeping = app.keeping; 16059 16060 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16061 16062 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 16063 } 16064 16065 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16066 boolean oomAdj) { 16067 if (isForeground != proc.foregroundServices) { 16068 proc.foregroundServices = isForeground; 16069 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16070 proc.info.uid); 16071 if (isForeground) { 16072 if (curProcs == null) { 16073 curProcs = new ArrayList<ProcessRecord>(); 16074 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16075 } 16076 if (!curProcs.contains(proc)) { 16077 curProcs.add(proc); 16078 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16079 proc.info.packageName, proc.info.uid); 16080 } 16081 } else { 16082 if (curProcs != null) { 16083 if (curProcs.remove(proc)) { 16084 mBatteryStatsService.noteEvent( 16085 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16086 proc.info.packageName, proc.info.uid); 16087 if (curProcs.size() <= 0) { 16088 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16089 } 16090 } 16091 } 16092 } 16093 if (oomAdj) { 16094 updateOomAdjLocked(); 16095 } 16096 } 16097 } 16098 16099 private final ActivityRecord resumedAppLocked() { 16100 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16101 String pkg; 16102 int uid; 16103 if (act != null && !act.sleeping) { 16104 pkg = act.packageName; 16105 uid = act.info.applicationInfo.uid; 16106 } else { 16107 pkg = null; 16108 uid = -1; 16109 } 16110 // Has the UID or resumed package name changed? 16111 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16112 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16113 if (mCurResumedPackage != null) { 16114 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16115 mCurResumedPackage, mCurResumedUid); 16116 } 16117 mCurResumedPackage = pkg; 16118 mCurResumedUid = uid; 16119 if (mCurResumedPackage != null) { 16120 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16121 mCurResumedPackage, mCurResumedUid); 16122 } 16123 } 16124 return act; 16125 } 16126 16127 final boolean updateOomAdjLocked(ProcessRecord app) { 16128 final ActivityRecord TOP_ACT = resumedAppLocked(); 16129 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16130 final boolean wasCached = app.cached; 16131 16132 mAdjSeq++; 16133 16134 // This is the desired cached adjusment we want to tell it to use. 16135 // If our app is currently cached, we know it, and that is it. Otherwise, 16136 // we don't know it yet, and it needs to now be cached we will then 16137 // need to do a complete oom adj. 16138 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16139 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16140 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16141 SystemClock.uptimeMillis()); 16142 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16143 // Changed to/from cached state, so apps after it in the LRU 16144 // list may also be changed. 16145 updateOomAdjLocked(); 16146 } 16147 return success; 16148 } 16149 16150 final void updateOomAdjLocked() { 16151 final ActivityRecord TOP_ACT = resumedAppLocked(); 16152 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16153 final long now = SystemClock.uptimeMillis(); 16154 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16155 final int N = mLruProcesses.size(); 16156 16157 if (false) { 16158 RuntimeException e = new RuntimeException(); 16159 e.fillInStackTrace(); 16160 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16161 } 16162 16163 mAdjSeq++; 16164 mNewNumServiceProcs = 0; 16165 mNewNumAServiceProcs = 0; 16166 16167 final int emptyProcessLimit; 16168 final int cachedProcessLimit; 16169 if (mProcessLimit <= 0) { 16170 emptyProcessLimit = cachedProcessLimit = 0; 16171 } else if (mProcessLimit == 1) { 16172 emptyProcessLimit = 1; 16173 cachedProcessLimit = 0; 16174 } else { 16175 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16176 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16177 } 16178 16179 // Let's determine how many processes we have running vs. 16180 // how many slots we have for background processes; we may want 16181 // to put multiple processes in a slot of there are enough of 16182 // them. 16183 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16184 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16185 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16186 if (numEmptyProcs > cachedProcessLimit) { 16187 // If there are more empty processes than our limit on cached 16188 // processes, then use the cached process limit for the factor. 16189 // This ensures that the really old empty processes get pushed 16190 // down to the bottom, so if we are running low on memory we will 16191 // have a better chance at keeping around more cached processes 16192 // instead of a gazillion empty processes. 16193 numEmptyProcs = cachedProcessLimit; 16194 } 16195 int emptyFactor = numEmptyProcs/numSlots; 16196 if (emptyFactor < 1) emptyFactor = 1; 16197 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16198 if (cachedFactor < 1) cachedFactor = 1; 16199 int stepCached = 0; 16200 int stepEmpty = 0; 16201 int numCached = 0; 16202 int numEmpty = 0; 16203 int numTrimming = 0; 16204 16205 mNumNonCachedProcs = 0; 16206 mNumCachedHiddenProcs = 0; 16207 16208 // First update the OOM adjustment for each of the 16209 // application processes based on their current state. 16210 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16211 int nextCachedAdj = curCachedAdj+1; 16212 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16213 int nextEmptyAdj = curEmptyAdj+2; 16214 for (int i=N-1; i>=0; i--) { 16215 ProcessRecord app = mLruProcesses.get(i); 16216 if (!app.killedByAm && app.thread != null) { 16217 app.procStateChanged = false; 16218 final boolean wasKeeping = app.keeping; 16219 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16220 16221 // If we haven't yet assigned the final cached adj 16222 // to the process, do that now. 16223 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16224 switch (app.curProcState) { 16225 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16226 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16227 // This process is a cached process holding activities... 16228 // assign it the next cached value for that type, and then 16229 // step that cached level. 16230 app.curRawAdj = curCachedAdj; 16231 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16232 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16233 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16234 + ")"); 16235 if (curCachedAdj != nextCachedAdj) { 16236 stepCached++; 16237 if (stepCached >= cachedFactor) { 16238 stepCached = 0; 16239 curCachedAdj = nextCachedAdj; 16240 nextCachedAdj += 2; 16241 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16242 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16243 } 16244 } 16245 } 16246 break; 16247 default: 16248 // For everything else, assign next empty cached process 16249 // level and bump that up. Note that this means that 16250 // long-running services that have dropped down to the 16251 // cached level will be treated as empty (since their process 16252 // state is still as a service), which is what we want. 16253 app.curRawAdj = curEmptyAdj; 16254 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16255 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16256 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16257 + ")"); 16258 if (curEmptyAdj != nextEmptyAdj) { 16259 stepEmpty++; 16260 if (stepEmpty >= emptyFactor) { 16261 stepEmpty = 0; 16262 curEmptyAdj = nextEmptyAdj; 16263 nextEmptyAdj += 2; 16264 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16265 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16266 } 16267 } 16268 } 16269 break; 16270 } 16271 } 16272 16273 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 16274 16275 // Count the number of process types. 16276 switch (app.curProcState) { 16277 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16278 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16279 mNumCachedHiddenProcs++; 16280 numCached++; 16281 if (numCached > cachedProcessLimit) { 16282 killUnneededProcessLocked(app, "cached #" + numCached); 16283 } 16284 break; 16285 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16286 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16287 && app.lastActivityTime < oldTime) { 16288 killUnneededProcessLocked(app, "empty for " 16289 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16290 / 1000) + "s"); 16291 } else { 16292 numEmpty++; 16293 if (numEmpty > emptyProcessLimit) { 16294 killUnneededProcessLocked(app, "empty #" + numEmpty); 16295 } 16296 } 16297 break; 16298 default: 16299 mNumNonCachedProcs++; 16300 break; 16301 } 16302 16303 if (app.isolated && app.services.size() <= 0) { 16304 // If this is an isolated process, and there are no 16305 // services running in it, then the process is no longer 16306 // needed. We agressively kill these because we can by 16307 // definition not re-use the same process again, and it is 16308 // good to avoid having whatever code was running in them 16309 // left sitting around after no longer needed. 16310 killUnneededProcessLocked(app, "isolated not needed"); 16311 } 16312 16313 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16314 && !app.killedByAm) { 16315 numTrimming++; 16316 } 16317 } 16318 } 16319 16320 mNumServiceProcs = mNewNumServiceProcs; 16321 16322 // Now determine the memory trimming level of background processes. 16323 // Unfortunately we need to start at the back of the list to do this 16324 // properly. We only do this if the number of background apps we 16325 // are managing to keep around is less than half the maximum we desire; 16326 // if we are keeping a good number around, we'll let them use whatever 16327 // memory they want. 16328 final int numCachedAndEmpty = numCached + numEmpty; 16329 int memFactor; 16330 if (numCached <= ProcessList.TRIM_CACHED_APPS 16331 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16332 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16333 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16334 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16335 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16336 } else { 16337 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16338 } 16339 } else { 16340 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16341 } 16342 // We always allow the memory level to go up (better). We only allow it to go 16343 // down if we are in a state where that is allowed, *and* the total number of processes 16344 // has gone down since last time. 16345 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16346 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16347 + " last=" + mLastNumProcesses); 16348 if (memFactor > mLastMemoryLevel) { 16349 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16350 memFactor = mLastMemoryLevel; 16351 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16352 } 16353 } 16354 mLastMemoryLevel = memFactor; 16355 mLastNumProcesses = mLruProcesses.size(); 16356 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16357 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16358 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16359 if (mLowRamStartTime == 0) { 16360 mLowRamStartTime = now; 16361 } 16362 int step = 0; 16363 int fgTrimLevel; 16364 switch (memFactor) { 16365 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16366 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16367 break; 16368 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16369 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16370 break; 16371 default: 16372 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16373 break; 16374 } 16375 int factor = numTrimming/3; 16376 int minFactor = 2; 16377 if (mHomeProcess != null) minFactor++; 16378 if (mPreviousProcess != null) minFactor++; 16379 if (factor < minFactor) factor = minFactor; 16380 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16381 for (int i=N-1; i>=0; i--) { 16382 ProcessRecord app = mLruProcesses.get(i); 16383 if (allChanged || app.procStateChanged) { 16384 setProcessTrackerState(app, trackerMemFactor, now); 16385 app.procStateChanged = false; 16386 } 16387 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16388 && !app.killedByAm) { 16389 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16390 try { 16391 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16392 "Trimming memory of " + app.processName 16393 + " to " + curLevel); 16394 app.thread.scheduleTrimMemory(curLevel); 16395 } catch (RemoteException e) { 16396 } 16397 if (false) { 16398 // For now we won't do this; our memory trimming seems 16399 // to be good enough at this point that destroying 16400 // activities causes more harm than good. 16401 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16402 && app != mHomeProcess && app != mPreviousProcess) { 16403 // Need to do this on its own message because the stack may not 16404 // be in a consistent state at this point. 16405 // For these apps we will also finish their activities 16406 // to help them free memory. 16407 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16408 } 16409 } 16410 } 16411 app.trimMemoryLevel = curLevel; 16412 step++; 16413 if (step >= factor) { 16414 step = 0; 16415 switch (curLevel) { 16416 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16417 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16418 break; 16419 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16420 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16421 break; 16422 } 16423 } 16424 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16425 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16426 && app.thread != null) { 16427 try { 16428 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16429 "Trimming memory of heavy-weight " + app.processName 16430 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16431 app.thread.scheduleTrimMemory( 16432 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16433 } catch (RemoteException e) { 16434 } 16435 } 16436 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16437 } else { 16438 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16439 || app.systemNoUi) && app.pendingUiClean) { 16440 // If this application is now in the background and it 16441 // had done UI, then give it the special trim level to 16442 // have it free UI resources. 16443 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16444 if (app.trimMemoryLevel < level && app.thread != null) { 16445 try { 16446 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16447 "Trimming memory of bg-ui " + app.processName 16448 + " to " + level); 16449 app.thread.scheduleTrimMemory(level); 16450 } catch (RemoteException e) { 16451 } 16452 } 16453 app.pendingUiClean = false; 16454 } 16455 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16456 try { 16457 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16458 "Trimming memory of fg " + app.processName 16459 + " to " + fgTrimLevel); 16460 app.thread.scheduleTrimMemory(fgTrimLevel); 16461 } catch (RemoteException e) { 16462 } 16463 } 16464 app.trimMemoryLevel = fgTrimLevel; 16465 } 16466 } 16467 } else { 16468 if (mLowRamStartTime != 0) { 16469 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16470 mLowRamStartTime = 0; 16471 } 16472 for (int i=N-1; i>=0; i--) { 16473 ProcessRecord app = mLruProcesses.get(i); 16474 if (allChanged || app.procStateChanged) { 16475 setProcessTrackerState(app, trackerMemFactor, now); 16476 app.procStateChanged = false; 16477 } 16478 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16479 || app.systemNoUi) && app.pendingUiClean) { 16480 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16481 && app.thread != null) { 16482 try { 16483 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16484 "Trimming memory of ui hidden " + app.processName 16485 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16486 app.thread.scheduleTrimMemory( 16487 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16488 } catch (RemoteException e) { 16489 } 16490 } 16491 app.pendingUiClean = false; 16492 } 16493 app.trimMemoryLevel = 0; 16494 } 16495 } 16496 16497 if (mAlwaysFinishActivities) { 16498 // Need to do this on its own message because the stack may not 16499 // be in a consistent state at this point. 16500 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16501 } 16502 16503 if (allChanged) { 16504 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16505 } 16506 16507 if (mProcessStats.shouldWriteNowLocked(now)) { 16508 mHandler.post(new Runnable() { 16509 @Override public void run() { 16510 synchronized (ActivityManagerService.this) { 16511 mProcessStats.writeStateAsyncLocked(); 16512 } 16513 } 16514 }); 16515 } 16516 16517 if (DEBUG_OOM_ADJ) { 16518 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16519 } 16520 } 16521 16522 final void trimApplications() { 16523 synchronized (this) { 16524 int i; 16525 16526 // First remove any unused application processes whose package 16527 // has been removed. 16528 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16529 final ProcessRecord app = mRemovedProcesses.get(i); 16530 if (app.activities.size() == 0 16531 && app.curReceiver == null && app.services.size() == 0) { 16532 Slog.i( 16533 TAG, "Exiting empty application process " 16534 + app.processName + " (" 16535 + (app.thread != null ? app.thread.asBinder() : null) 16536 + ")\n"); 16537 if (app.pid > 0 && app.pid != MY_PID) { 16538 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16539 app.processName, app.setAdj, "empty"); 16540 app.killedByAm = true; 16541 Process.killProcessQuiet(app.pid); 16542 } else { 16543 try { 16544 app.thread.scheduleExit(); 16545 } catch (Exception e) { 16546 // Ignore exceptions. 16547 } 16548 } 16549 cleanUpApplicationRecordLocked(app, false, true, -1); 16550 mRemovedProcesses.remove(i); 16551 16552 if (app.persistent) { 16553 if (app.persistent) { 16554 addAppLocked(app.info, false, null /* ABI override */); 16555 } 16556 } 16557 } 16558 } 16559 16560 // Now update the oom adj for all processes. 16561 updateOomAdjLocked(); 16562 } 16563 } 16564 16565 /** This method sends the specified signal to each of the persistent apps */ 16566 public void signalPersistentProcesses(int sig) throws RemoteException { 16567 if (sig != Process.SIGNAL_USR1) { 16568 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16569 } 16570 16571 synchronized (this) { 16572 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16573 != PackageManager.PERMISSION_GRANTED) { 16574 throw new SecurityException("Requires permission " 16575 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16576 } 16577 16578 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16579 ProcessRecord r = mLruProcesses.get(i); 16580 if (r.thread != null && r.persistent) { 16581 Process.sendSignal(r.pid, sig); 16582 } 16583 } 16584 } 16585 } 16586 16587 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16588 if (proc == null || proc == mProfileProc) { 16589 proc = mProfileProc; 16590 path = mProfileFile; 16591 profileType = mProfileType; 16592 clearProfilerLocked(); 16593 } 16594 if (proc == null) { 16595 return; 16596 } 16597 try { 16598 proc.thread.profilerControl(false, path, null, profileType); 16599 } catch (RemoteException e) { 16600 throw new IllegalStateException("Process disappeared"); 16601 } 16602 } 16603 16604 private void clearProfilerLocked() { 16605 if (mProfileFd != null) { 16606 try { 16607 mProfileFd.close(); 16608 } catch (IOException e) { 16609 } 16610 } 16611 mProfileApp = null; 16612 mProfileProc = null; 16613 mProfileFile = null; 16614 mProfileType = 0; 16615 mAutoStopProfiler = false; 16616 } 16617 16618 public boolean profileControl(String process, int userId, boolean start, 16619 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16620 16621 try { 16622 synchronized (this) { 16623 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16624 // its own permission. 16625 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16626 != PackageManager.PERMISSION_GRANTED) { 16627 throw new SecurityException("Requires permission " 16628 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16629 } 16630 16631 if (start && fd == null) { 16632 throw new IllegalArgumentException("null fd"); 16633 } 16634 16635 ProcessRecord proc = null; 16636 if (process != null) { 16637 proc = findProcessLocked(process, userId, "profileControl"); 16638 } 16639 16640 if (start && (proc == null || proc.thread == null)) { 16641 throw new IllegalArgumentException("Unknown process: " + process); 16642 } 16643 16644 if (start) { 16645 stopProfilerLocked(null, null, 0); 16646 setProfileApp(proc.info, proc.processName, path, fd, false); 16647 mProfileProc = proc; 16648 mProfileType = profileType; 16649 try { 16650 fd = fd.dup(); 16651 } catch (IOException e) { 16652 fd = null; 16653 } 16654 proc.thread.profilerControl(start, path, fd, profileType); 16655 fd = null; 16656 mProfileFd = null; 16657 } else { 16658 stopProfilerLocked(proc, path, profileType); 16659 if (fd != null) { 16660 try { 16661 fd.close(); 16662 } catch (IOException e) { 16663 } 16664 } 16665 } 16666 16667 return true; 16668 } 16669 } catch (RemoteException e) { 16670 throw new IllegalStateException("Process disappeared"); 16671 } finally { 16672 if (fd != null) { 16673 try { 16674 fd.close(); 16675 } catch (IOException e) { 16676 } 16677 } 16678 } 16679 } 16680 16681 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16682 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16683 userId, true, true, callName, null); 16684 ProcessRecord proc = null; 16685 try { 16686 int pid = Integer.parseInt(process); 16687 synchronized (mPidsSelfLocked) { 16688 proc = mPidsSelfLocked.get(pid); 16689 } 16690 } catch (NumberFormatException e) { 16691 } 16692 16693 if (proc == null) { 16694 ArrayMap<String, SparseArray<ProcessRecord>> all 16695 = mProcessNames.getMap(); 16696 SparseArray<ProcessRecord> procs = all.get(process); 16697 if (procs != null && procs.size() > 0) { 16698 proc = procs.valueAt(0); 16699 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16700 for (int i=1; i<procs.size(); i++) { 16701 ProcessRecord thisProc = procs.valueAt(i); 16702 if (thisProc.userId == userId) { 16703 proc = thisProc; 16704 break; 16705 } 16706 } 16707 } 16708 } 16709 } 16710 16711 return proc; 16712 } 16713 16714 public boolean dumpHeap(String process, int userId, boolean managed, 16715 String path, ParcelFileDescriptor fd) throws RemoteException { 16716 16717 try { 16718 synchronized (this) { 16719 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16720 // its own permission (same as profileControl). 16721 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16722 != PackageManager.PERMISSION_GRANTED) { 16723 throw new SecurityException("Requires permission " 16724 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16725 } 16726 16727 if (fd == null) { 16728 throw new IllegalArgumentException("null fd"); 16729 } 16730 16731 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16732 if (proc == null || proc.thread == null) { 16733 throw new IllegalArgumentException("Unknown process: " + process); 16734 } 16735 16736 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16737 if (!isDebuggable) { 16738 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16739 throw new SecurityException("Process not debuggable: " + proc); 16740 } 16741 } 16742 16743 proc.thread.dumpHeap(managed, path, fd); 16744 fd = null; 16745 return true; 16746 } 16747 } catch (RemoteException e) { 16748 throw new IllegalStateException("Process disappeared"); 16749 } finally { 16750 if (fd != null) { 16751 try { 16752 fd.close(); 16753 } catch (IOException e) { 16754 } 16755 } 16756 } 16757 } 16758 16759 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16760 public void monitor() { 16761 synchronized (this) { } 16762 } 16763 16764 void onCoreSettingsChange(Bundle settings) { 16765 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16766 ProcessRecord processRecord = mLruProcesses.get(i); 16767 try { 16768 if (processRecord.thread != null) { 16769 processRecord.thread.setCoreSettings(settings); 16770 } 16771 } catch (RemoteException re) { 16772 /* ignore */ 16773 } 16774 } 16775 } 16776 16777 // Multi-user methods 16778 16779 /** 16780 * Start user, if its not already running, but don't bring it to foreground. 16781 */ 16782 @Override 16783 public boolean startUserInBackground(final int userId) { 16784 return startUser(userId, /* foreground */ false); 16785 } 16786 16787 /** 16788 * Refreshes the list of users related to the current user when either a 16789 * user switch happens or when a new related user is started in the 16790 * background. 16791 */ 16792 private void updateCurrentProfileIdsLocked() { 16793 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16794 mCurrentUserId, false /* enabledOnly */); 16795 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16796 for (int i = 0; i < currentProfileIds.length; i++) { 16797 currentProfileIds[i] = profiles.get(i).id; 16798 } 16799 mCurrentProfileIds = currentProfileIds; 16800 } 16801 16802 private Set getProfileIdsLocked(int userId) { 16803 Set userIds = new HashSet<Integer>(); 16804 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16805 userId, false /* enabledOnly */); 16806 for (UserInfo user : profiles) { 16807 userIds.add(Integer.valueOf(user.id)); 16808 } 16809 return userIds; 16810 } 16811 16812 @Override 16813 public boolean switchUser(final int userId) { 16814 return startUser(userId, /* foregound */ true); 16815 } 16816 16817 private boolean startUser(final int userId, boolean foreground) { 16818 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 16819 != PackageManager.PERMISSION_GRANTED) { 16820 String msg = "Permission Denial: switchUser() from pid=" 16821 + Binder.getCallingPid() 16822 + ", uid=" + Binder.getCallingUid() 16823 + " requires " + INTERACT_ACROSS_USERS_FULL; 16824 Slog.w(TAG, msg); 16825 throw new SecurityException(msg); 16826 } 16827 16828 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16829 16830 final long ident = Binder.clearCallingIdentity(); 16831 try { 16832 synchronized (this) { 16833 final int oldUserId = mCurrentUserId; 16834 if (oldUserId == userId) { 16835 return true; 16836 } 16837 16838 mStackSupervisor.setLockTaskModeLocked(null, false); 16839 16840 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16841 if (userInfo == null) { 16842 Slog.w(TAG, "No user info for user #" + userId); 16843 return false; 16844 } 16845 16846 if (foreground) { 16847 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16848 R.anim.screen_user_enter); 16849 } 16850 16851 boolean needStart = false; 16852 16853 // If the user we are switching to is not currently started, then 16854 // we need to start it now. 16855 if (mStartedUsers.get(userId) == null) { 16856 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16857 updateStartedUserArrayLocked(); 16858 needStart = true; 16859 } 16860 16861 final Integer userIdInt = Integer.valueOf(userId); 16862 mUserLru.remove(userIdInt); 16863 mUserLru.add(userIdInt); 16864 16865 if (foreground) { 16866 mCurrentUserId = userId; 16867 updateCurrentProfileIdsLocked(); 16868 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16869 // Once the internal notion of the active user has switched, we lock the device 16870 // with the option to show the user switcher on the keyguard. 16871 mWindowManager.lockNow(null); 16872 } else { 16873 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16874 updateCurrentProfileIdsLocked(); 16875 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16876 mUserLru.remove(currentUserIdInt); 16877 mUserLru.add(currentUserIdInt); 16878 } 16879 16880 final UserStartedState uss = mStartedUsers.get(userId); 16881 16882 // Make sure user is in the started state. If it is currently 16883 // stopping, we need to knock that off. 16884 if (uss.mState == UserStartedState.STATE_STOPPING) { 16885 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16886 // so we can just fairly silently bring the user back from 16887 // the almost-dead. 16888 uss.mState = UserStartedState.STATE_RUNNING; 16889 updateStartedUserArrayLocked(); 16890 needStart = true; 16891 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16892 // This means ACTION_SHUTDOWN has been sent, so we will 16893 // need to treat this as a new boot of the user. 16894 uss.mState = UserStartedState.STATE_BOOTING; 16895 updateStartedUserArrayLocked(); 16896 needStart = true; 16897 } 16898 16899 if (uss.mState == UserStartedState.STATE_BOOTING) { 16900 // Booting up a new user, need to tell system services about it. 16901 // Note that this is on the same handler as scheduling of broadcasts, 16902 // which is important because it needs to go first. 16903 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16904 } 16905 16906 if (foreground) { 16907 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16908 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16909 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16910 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16911 oldUserId, userId, uss)); 16912 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16913 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16914 } 16915 16916 if (needStart) { 16917 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16918 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16919 | Intent.FLAG_RECEIVER_FOREGROUND); 16920 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16921 broadcastIntentLocked(null, null, intent, 16922 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16923 false, false, MY_PID, Process.SYSTEM_UID, userId); 16924 } 16925 16926 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16927 if (userId != UserHandle.USER_OWNER) { 16928 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16929 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16930 broadcastIntentLocked(null, null, intent, null, 16931 new IIntentReceiver.Stub() { 16932 public void performReceive(Intent intent, int resultCode, 16933 String data, Bundle extras, boolean ordered, 16934 boolean sticky, int sendingUser) { 16935 userInitialized(uss, userId); 16936 } 16937 }, 0, null, null, null, AppOpsManager.OP_NONE, 16938 true, false, MY_PID, Process.SYSTEM_UID, 16939 userId); 16940 uss.initializing = true; 16941 } else { 16942 getUserManagerLocked().makeInitialized(userInfo.id); 16943 } 16944 } 16945 16946 if (foreground) { 16947 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16948 if (homeInFront) { 16949 startHomeActivityLocked(userId); 16950 } else { 16951 mStackSupervisor.resumeTopActivitiesLocked(); 16952 } 16953 EventLogTags.writeAmSwitchUser(userId); 16954 getUserManagerLocked().userForeground(userId); 16955 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16956 } else { 16957 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16958 } 16959 16960 if (needStart) { 16961 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16962 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16963 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16964 broadcastIntentLocked(null, null, intent, 16965 null, new IIntentReceiver.Stub() { 16966 @Override 16967 public void performReceive(Intent intent, int resultCode, String data, 16968 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16969 throws RemoteException { 16970 } 16971 }, 0, null, null, 16972 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16973 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16974 } 16975 } 16976 } finally { 16977 Binder.restoreCallingIdentity(ident); 16978 } 16979 16980 return true; 16981 } 16982 16983 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16984 long ident = Binder.clearCallingIdentity(); 16985 try { 16986 Intent intent; 16987 if (oldUserId >= 0) { 16988 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16989 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16990 | Intent.FLAG_RECEIVER_FOREGROUND); 16991 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16992 broadcastIntentLocked(null, null, intent, 16993 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16994 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16995 } 16996 if (newUserId >= 0) { 16997 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16998 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16999 | Intent.FLAG_RECEIVER_FOREGROUND); 17000 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17001 broadcastIntentLocked(null, null, intent, 17002 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17003 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 17004 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17005 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17006 | Intent.FLAG_RECEIVER_FOREGROUND); 17007 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17008 broadcastIntentLocked(null, null, intent, 17009 null, null, 0, null, null, 17010 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17011 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17012 } 17013 } finally { 17014 Binder.restoreCallingIdentity(ident); 17015 } 17016 } 17017 17018 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17019 final int newUserId) { 17020 final int N = mUserSwitchObservers.beginBroadcast(); 17021 if (N > 0) { 17022 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17023 int mCount = 0; 17024 @Override 17025 public void sendResult(Bundle data) throws RemoteException { 17026 synchronized (ActivityManagerService.this) { 17027 if (mCurUserSwitchCallback == this) { 17028 mCount++; 17029 if (mCount == N) { 17030 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17031 } 17032 } 17033 } 17034 } 17035 }; 17036 synchronized (this) { 17037 uss.switching = true; 17038 mCurUserSwitchCallback = callback; 17039 } 17040 for (int i=0; i<N; i++) { 17041 try { 17042 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17043 newUserId, callback); 17044 } catch (RemoteException e) { 17045 } 17046 } 17047 } else { 17048 synchronized (this) { 17049 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17050 } 17051 } 17052 mUserSwitchObservers.finishBroadcast(); 17053 } 17054 17055 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17056 synchronized (this) { 17057 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17058 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17059 } 17060 } 17061 17062 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17063 mCurUserSwitchCallback = null; 17064 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17065 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17066 oldUserId, newUserId, uss)); 17067 } 17068 17069 void userInitialized(UserStartedState uss, int newUserId) { 17070 completeSwitchAndInitalize(uss, newUserId, true, false); 17071 } 17072 17073 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17074 completeSwitchAndInitalize(uss, newUserId, false, true); 17075 } 17076 17077 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17078 boolean clearInitializing, boolean clearSwitching) { 17079 boolean unfrozen = false; 17080 synchronized (this) { 17081 if (clearInitializing) { 17082 uss.initializing = false; 17083 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17084 } 17085 if (clearSwitching) { 17086 uss.switching = false; 17087 } 17088 if (!uss.switching && !uss.initializing) { 17089 mWindowManager.stopFreezingScreen(); 17090 unfrozen = true; 17091 } 17092 } 17093 if (unfrozen) { 17094 final int N = mUserSwitchObservers.beginBroadcast(); 17095 for (int i=0; i<N; i++) { 17096 try { 17097 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17098 } catch (RemoteException e) { 17099 } 17100 } 17101 mUserSwitchObservers.finishBroadcast(); 17102 } 17103 } 17104 17105 void scheduleStartProfilesLocked() { 17106 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17107 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17108 DateUtils.SECOND_IN_MILLIS); 17109 } 17110 } 17111 17112 void startProfilesLocked() { 17113 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17114 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17115 mCurrentUserId, false /* enabledOnly */); 17116 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17117 for (UserInfo user : profiles) { 17118 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17119 && user.id != mCurrentUserId) { 17120 toStart.add(user); 17121 } 17122 } 17123 final int n = toStart.size(); 17124 int i = 0; 17125 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17126 startUserInBackground(toStart.get(i).id); 17127 } 17128 if (i < n) { 17129 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17130 } 17131 } 17132 17133 void finishUserBoot(UserStartedState uss) { 17134 synchronized (this) { 17135 if (uss.mState == UserStartedState.STATE_BOOTING 17136 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17137 uss.mState = UserStartedState.STATE_RUNNING; 17138 final int userId = uss.mHandle.getIdentifier(); 17139 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17140 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17141 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17142 broadcastIntentLocked(null, null, intent, 17143 null, null, 0, null, null, 17144 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17145 true, false, MY_PID, Process.SYSTEM_UID, userId); 17146 } 17147 } 17148 } 17149 17150 void finishUserSwitch(UserStartedState uss) { 17151 synchronized (this) { 17152 finishUserBoot(uss); 17153 17154 startProfilesLocked(); 17155 17156 int num = mUserLru.size(); 17157 int i = 0; 17158 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17159 Integer oldUserId = mUserLru.get(i); 17160 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17161 if (oldUss == null) { 17162 // Shouldn't happen, but be sane if it does. 17163 mUserLru.remove(i); 17164 num--; 17165 continue; 17166 } 17167 if (oldUss.mState == UserStartedState.STATE_STOPPING 17168 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17169 // This user is already stopping, doesn't count. 17170 num--; 17171 i++; 17172 continue; 17173 } 17174 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17175 // Owner and current can't be stopped, but count as running. 17176 i++; 17177 continue; 17178 } 17179 // This is a user to be stopped. 17180 stopUserLocked(oldUserId, null); 17181 num--; 17182 i++; 17183 } 17184 } 17185 } 17186 17187 @Override 17188 public int stopUser(final int userId, final IStopUserCallback callback) { 17189 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17190 != PackageManager.PERMISSION_GRANTED) { 17191 String msg = "Permission Denial: switchUser() from pid=" 17192 + Binder.getCallingPid() 17193 + ", uid=" + Binder.getCallingUid() 17194 + " requires " + INTERACT_ACROSS_USERS_FULL; 17195 Slog.w(TAG, msg); 17196 throw new SecurityException(msg); 17197 } 17198 if (userId <= 0) { 17199 throw new IllegalArgumentException("Can't stop primary user " + userId); 17200 } 17201 synchronized (this) { 17202 return stopUserLocked(userId, callback); 17203 } 17204 } 17205 17206 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17207 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17208 if (mCurrentUserId == userId) { 17209 return ActivityManager.USER_OP_IS_CURRENT; 17210 } 17211 17212 final UserStartedState uss = mStartedUsers.get(userId); 17213 if (uss == null) { 17214 // User is not started, nothing to do... but we do need to 17215 // callback if requested. 17216 if (callback != null) { 17217 mHandler.post(new Runnable() { 17218 @Override 17219 public void run() { 17220 try { 17221 callback.userStopped(userId); 17222 } catch (RemoteException e) { 17223 } 17224 } 17225 }); 17226 } 17227 return ActivityManager.USER_OP_SUCCESS; 17228 } 17229 17230 if (callback != null) { 17231 uss.mStopCallbacks.add(callback); 17232 } 17233 17234 if (uss.mState != UserStartedState.STATE_STOPPING 17235 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17236 uss.mState = UserStartedState.STATE_STOPPING; 17237 updateStartedUserArrayLocked(); 17238 17239 long ident = Binder.clearCallingIdentity(); 17240 try { 17241 // We are going to broadcast ACTION_USER_STOPPING and then 17242 // once that is done send a final ACTION_SHUTDOWN and then 17243 // stop the user. 17244 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17245 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17246 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17247 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17248 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17249 // This is the result receiver for the final shutdown broadcast. 17250 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17251 @Override 17252 public void performReceive(Intent intent, int resultCode, String data, 17253 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17254 finishUserStop(uss); 17255 } 17256 }; 17257 // This is the result receiver for the initial stopping broadcast. 17258 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17259 @Override 17260 public void performReceive(Intent intent, int resultCode, String data, 17261 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17262 // On to the next. 17263 synchronized (ActivityManagerService.this) { 17264 if (uss.mState != UserStartedState.STATE_STOPPING) { 17265 // Whoops, we are being started back up. Abort, abort! 17266 return; 17267 } 17268 uss.mState = UserStartedState.STATE_SHUTDOWN; 17269 } 17270 mSystemServiceManager.stopUser(userId); 17271 broadcastIntentLocked(null, null, shutdownIntent, 17272 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17273 true, false, MY_PID, Process.SYSTEM_UID, userId); 17274 } 17275 }; 17276 // Kick things off. 17277 broadcastIntentLocked(null, null, stoppingIntent, 17278 null, stoppingReceiver, 0, null, null, 17279 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17280 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17281 } finally { 17282 Binder.restoreCallingIdentity(ident); 17283 } 17284 } 17285 17286 return ActivityManager.USER_OP_SUCCESS; 17287 } 17288 17289 void finishUserStop(UserStartedState uss) { 17290 final int userId = uss.mHandle.getIdentifier(); 17291 boolean stopped; 17292 ArrayList<IStopUserCallback> callbacks; 17293 synchronized (this) { 17294 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17295 if (mStartedUsers.get(userId) != uss) { 17296 stopped = false; 17297 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17298 stopped = false; 17299 } else { 17300 stopped = true; 17301 // User can no longer run. 17302 mStartedUsers.remove(userId); 17303 mUserLru.remove(Integer.valueOf(userId)); 17304 updateStartedUserArrayLocked(); 17305 17306 // Clean up all state and processes associated with the user. 17307 // Kill all the processes for the user. 17308 forceStopUserLocked(userId, "finish user"); 17309 } 17310 } 17311 17312 for (int i=0; i<callbacks.size(); i++) { 17313 try { 17314 if (stopped) callbacks.get(i).userStopped(userId); 17315 else callbacks.get(i).userStopAborted(userId); 17316 } catch (RemoteException e) { 17317 } 17318 } 17319 17320 if (stopped) { 17321 mSystemServiceManager.cleanupUser(userId); 17322 synchronized (this) { 17323 mStackSupervisor.removeUserLocked(userId); 17324 } 17325 } 17326 } 17327 17328 @Override 17329 public UserInfo getCurrentUser() { 17330 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17331 != PackageManager.PERMISSION_GRANTED) && ( 17332 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17333 != PackageManager.PERMISSION_GRANTED)) { 17334 String msg = "Permission Denial: getCurrentUser() from pid=" 17335 + Binder.getCallingPid() 17336 + ", uid=" + Binder.getCallingUid() 17337 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17338 Slog.w(TAG, msg); 17339 throw new SecurityException(msg); 17340 } 17341 synchronized (this) { 17342 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17343 } 17344 } 17345 17346 int getCurrentUserIdLocked() { 17347 return mCurrentUserId; 17348 } 17349 17350 @Override 17351 public boolean isUserRunning(int userId, boolean orStopped) { 17352 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17353 != PackageManager.PERMISSION_GRANTED) { 17354 String msg = "Permission Denial: isUserRunning() from pid=" 17355 + Binder.getCallingPid() 17356 + ", uid=" + Binder.getCallingUid() 17357 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17358 Slog.w(TAG, msg); 17359 throw new SecurityException(msg); 17360 } 17361 synchronized (this) { 17362 return isUserRunningLocked(userId, orStopped); 17363 } 17364 } 17365 17366 boolean isUserRunningLocked(int userId, boolean orStopped) { 17367 UserStartedState state = mStartedUsers.get(userId); 17368 if (state == null) { 17369 return false; 17370 } 17371 if (orStopped) { 17372 return true; 17373 } 17374 return state.mState != UserStartedState.STATE_STOPPING 17375 && state.mState != UserStartedState.STATE_SHUTDOWN; 17376 } 17377 17378 @Override 17379 public int[] getRunningUserIds() { 17380 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17381 != PackageManager.PERMISSION_GRANTED) { 17382 String msg = "Permission Denial: isUserRunning() from pid=" 17383 + Binder.getCallingPid() 17384 + ", uid=" + Binder.getCallingUid() 17385 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17386 Slog.w(TAG, msg); 17387 throw new SecurityException(msg); 17388 } 17389 synchronized (this) { 17390 return mStartedUserArray; 17391 } 17392 } 17393 17394 private void updateStartedUserArrayLocked() { 17395 int num = 0; 17396 for (int i=0; i<mStartedUsers.size(); i++) { 17397 UserStartedState uss = mStartedUsers.valueAt(i); 17398 // This list does not include stopping users. 17399 if (uss.mState != UserStartedState.STATE_STOPPING 17400 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17401 num++; 17402 } 17403 } 17404 mStartedUserArray = new int[num]; 17405 num = 0; 17406 for (int i=0; i<mStartedUsers.size(); i++) { 17407 UserStartedState uss = mStartedUsers.valueAt(i); 17408 if (uss.mState != UserStartedState.STATE_STOPPING 17409 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17410 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17411 num++; 17412 } 17413 } 17414 } 17415 17416 @Override 17417 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17418 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17419 != PackageManager.PERMISSION_GRANTED) { 17420 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17421 + Binder.getCallingPid() 17422 + ", uid=" + Binder.getCallingUid() 17423 + " requires " + INTERACT_ACROSS_USERS_FULL; 17424 Slog.w(TAG, msg); 17425 throw new SecurityException(msg); 17426 } 17427 17428 mUserSwitchObservers.register(observer); 17429 } 17430 17431 @Override 17432 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17433 mUserSwitchObservers.unregister(observer); 17434 } 17435 17436 private boolean userExists(int userId) { 17437 if (userId == 0) { 17438 return true; 17439 } 17440 UserManagerService ums = getUserManagerLocked(); 17441 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17442 } 17443 17444 int[] getUsersLocked() { 17445 UserManagerService ums = getUserManagerLocked(); 17446 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17447 } 17448 17449 UserManagerService getUserManagerLocked() { 17450 if (mUserManager == null) { 17451 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17452 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17453 } 17454 return mUserManager; 17455 } 17456 17457 private int applyUserId(int uid, int userId) { 17458 return UserHandle.getUid(userId, uid); 17459 } 17460 17461 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17462 if (info == null) return null; 17463 ApplicationInfo newInfo = new ApplicationInfo(info); 17464 newInfo.uid = applyUserId(info.uid, userId); 17465 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17466 + info.packageName; 17467 return newInfo; 17468 } 17469 17470 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17471 if (aInfo == null 17472 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17473 return aInfo; 17474 } 17475 17476 ActivityInfo info = new ActivityInfo(aInfo); 17477 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17478 return info; 17479 } 17480 17481 private final class LocalService extends ActivityManagerInternal { 17482 @Override 17483 public void goingToSleep() { 17484 ActivityManagerService.this.goingToSleep(); 17485 } 17486 17487 @Override 17488 public void wakingUp() { 17489 ActivityManagerService.this.wakingUp(); 17490 } 17491 } 17492 17493 /** 17494 * An implementation of IAppTask, that allows an app to manage its own tasks via 17495 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17496 * only the process that calls getAppTasks() can call the AppTask methods. 17497 */ 17498 class AppTaskImpl extends IAppTask.Stub { 17499 private int mTaskId; 17500 private int mCallingUid; 17501 17502 public AppTaskImpl(int taskId, int callingUid) { 17503 mTaskId = taskId; 17504 mCallingUid = callingUid; 17505 } 17506 17507 @Override 17508 public void finishAndRemoveTask() { 17509 // Ensure that we are called from the same process that created this AppTask 17510 if (mCallingUid != Binder.getCallingUid()) { 17511 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17512 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17513 return; 17514 } 17515 17516 synchronized (ActivityManagerService.this) { 17517 long origId = Binder.clearCallingIdentity(); 17518 try { 17519 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17520 if (tr != null) { 17521 // Only kill the process if we are not a new document 17522 int flags = tr.getBaseIntent().getFlags(); 17523 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17524 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17525 removeTaskByIdLocked(mTaskId, 17526 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17527 } 17528 } finally { 17529 Binder.restoreCallingIdentity(origId); 17530 } 17531 } 17532 } 17533 17534 @Override 17535 public ActivityManager.RecentTaskInfo getTaskInfo() { 17536 // Ensure that we are called from the same process that created this AppTask 17537 if (mCallingUid != Binder.getCallingUid()) { 17538 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17539 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17540 return null; 17541 } 17542 17543 synchronized (ActivityManagerService.this) { 17544 long origId = Binder.clearCallingIdentity(); 17545 try { 17546 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17547 if (tr != null) { 17548 return createRecentTaskInfoFromTaskRecord(tr); 17549 } 17550 } finally { 17551 Binder.restoreCallingIdentity(origId); 17552 } 17553 return null; 17554 } 17555 } 17556 } 17557} 17558