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